diff options
632 files changed, 69308 insertions, 3070 deletions
diff --git a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini index 53ae48faf06..813a67f7fcd 100644 --- a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini +++ b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini @@ -92,6 +92,99 @@ [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), {name: Ed25519}, false, [sign, sign\])] expected: FAIL + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign, sign\])] + expected: FAIL + [okp_importKey_Ed25519.https.any.html] [Good parameters: Ed25519 bits (spki, buffer(44), {name: Ed25519}, true, [verify\])] @@ -186,3 +279,96 @@ [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), {name: Ed25519}, false, [sign, sign\])] expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign, sign\])] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini index a648a2c9e95..b1f80afada5 100644 --- a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini +++ b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini @@ -92,6 +92,99 @@ [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), {name: Ed448}, false, [sign, sign\])] expected: FAIL + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign, sign\])] + expected: FAIL + [okp_importKey_Ed448.https.any.html] [Good parameters: Ed448 bits (spki, buffer(69), {name: Ed448}, true, [verify\])] @@ -186,3 +279,96 @@ [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), {name: Ed448}, false, [sign, sign\])] expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign, sign\])] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini index 6bf07f7980f..f35c0980194 100644 --- a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini +++ b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini @@ -80,6 +80,87 @@ [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), {name: X25519}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + [Good parameters: X25519 bits (spki, buffer(44), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (spki, buffer(44), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + [okp_importKey_X25519.https.any.worker.html] [Good parameters: X25519 bits (spki, buffer(44), {name: X25519}, true, [\])] @@ -162,3 +243,84 @@ [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), {name: X25519}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + + [Good parameters: X25519 bits (spki, buffer(44), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (spki, buffer(44), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini index 9120981ca5b..1911cc7fa63 100644 --- a/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini +++ b/tests/wpt/meta-legacy-layout/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini @@ -80,6 +80,87 @@ [Good parameters: X448 bits (jwk, object(crv, d, x, kty), {name: X448}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + [Good parameters: X448 bits (spki, buffer(68), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (spki, buffer(68), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + [okp_importKey_X448.https.any.html] [Good parameters: X448 bits (spki, buffer(68), {name: X448}, true, [\])] @@ -162,3 +243,84 @@ [Good parameters: X448 bits (jwk, object(crv, d, x, kty), {name: X448}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + + [Good parameters: X448 bits (spki, buffer(68), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (spki, buffer(68), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-relative-color.html.ini b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-relative-color.html.ini index d4e0b6dccc5..70aa2015799 100644 --- a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-relative-color.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-relative-color.html.ini @@ -3697,3 +3697,9 @@ [Property background-color value 'hsl(from currentColor calc((h / 360) * 360deg) s l)'] expected: FAIL + + [Property color value 'light-dark(rgb(from rebeccapurple r g b), rgb(from rebeccapurple r g b))'] + expected: FAIL + + [Property color value 'light-dark(color-mix(in srgb, rgb(from rebeccapurple none g b), rebeccapurple), color-mix(in srgb, rgb(from rebeccapurple none g b), rebeccapurple))'] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-relative-color.html.ini b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-relative-color.html.ini index 3d655cd0048..380c9a54f3f 100644 --- a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-relative-color.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-relative-color.html.ini @@ -3724,3 +3724,6 @@ [e.style['color'\] = "color(from color-mix(in xyz-d65, color(xyz-d65 0.7 0.5 0.3), color(xyz-d65 0.7 0.5 0.3)) xyz-d65 x y z / alpha)" should set the property value] expected: FAIL + + [e.style['color'\] = "oklch(from red calc(1 / l) c h)" should set the property value] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-overflowing-parsing.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-overflowing-parsing.html.ini index 72f4601118a..72f4601118a 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-overflowing-parsing.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-overflowing-parsing.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-overflowing-serialization.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-overflowing-serialization.html.ini index 18c1abafcc7..18c1abafcc7 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-overflowing-serialization.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-overflowing-serialization.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-snapped-parsing.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-snapped-parsing.html.ini index 6ad6378fe26..6ad6378fe26 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-snapped-parsing.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-snapped-parsing.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-snapped-serialization.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-snapped-serialization.html.ini index 35c90640507..35c90640507 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-snapped-serialization.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-snapped-serialization.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-stuck-parsing.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-stuck-parsing.html.ini index 849d4af452a..849d4af452a 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-stuck-parsing.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-stuck-parsing.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-stuck-serialization.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-stuck-serialization.html.ini index 95ca2e600cb..95ca2e600cb 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/at-container-stuck-serialization.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/at-container-stuck-serialization.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/container-type-scroll-state-computed.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-computed.html.ini index bf71bdf192b..bf71bdf192b 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/container-type-scroll-state-computed.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-computed.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/container-type-scroll-state-containment.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-containment.html.ini index 6816d82fe23..6816d82fe23 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/container-type-scroll-state-containment.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-containment.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/container-type-scroll-state-parsing.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-parsing.html.ini index 77be49bdc31..77be49bdc31 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/container-type-scroll-state-parsing.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-parsing.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-initially-snapped.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-initially-snapped.html.ini index 0b354083d7a..0b354083d7a 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-initially-snapped.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-initially-snapped.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-initially-stuck.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-initially-stuck.html.ini index 7260020fd97..7260020fd97 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-initially-stuck.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-initially-stuck.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-change.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-change.html.ini index 346d353eab5..346d353eab5 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-change.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-change.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-container-type-change.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-container-type-change.html.ini index a1cd47a47cc..a1cd47a47cc 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-container-type-change.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-container-type-change.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-none.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-none.html.ini index e5d314021fb..e5d314021fb 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-none.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-none.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-wm.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-wm.html.ini index a91d853ebd3..a91d853ebd3 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-snapped-wm.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-wm.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html.ini new file mode 100644 index 00000000000..f0b3a1e7a8a --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html.ini @@ -0,0 +1,2 @@ +[scroll-state-stuck-container-type-change.html] + expected: ERROR diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html.ini new file mode 100644 index 00000000000..3caa58f120b --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html.ini @@ -0,0 +1,2 @@ +[scroll-state-stuck-writing-direction.html] + expected: ERROR diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-target-query-change.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-target-query-change.html.ini index 8125d4e9608..8125d4e9608 100644 --- a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state-target-query-change.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/scroll-state/scroll-state-target-query-change.html.ini diff --git a/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/size-container-writing-mode-change.html.ini b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/size-container-writing-mode-change.html.ini new file mode 100644 index 00000000000..7e0cf86879c --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-conditional/container-queries/size-container-writing-mode-change.html.ini @@ -0,0 +1,2 @@ +[size-container-writing-mode-change.html] + expected: ERROR diff --git a/tests/wpt/meta-legacy-layout/css/css-fonts/generic-family-keywords-001.html.ini b/tests/wpt/meta-legacy-layout/css/css-fonts/generic-family-keywords-001.html.ini index 8cfa1c28944..e7b1cf288a0 100644 --- a/tests/wpt/meta-legacy-layout/css/css-fonts/generic-family-keywords-001.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-fonts/generic-family-keywords-001.html.ini @@ -8,17 +8,14 @@ [@font-face matching for quoted and unquoted serif] expected: FAIL - [@font-face matching for quoted and unquoted cursive] - expected: FAIL - [@font-face matching for quoted and unquoted fantasy] expected: FAIL [@font-face matching for quoted and unquoted monospace] expected: FAIL - [@font-face matching for quoted and unquoted system-ui] + [@font-face matching for quoted and unquoted ui-monospace] expected: FAIL - [@font-face matching for quoted and unquoted ui-monospace] + [@font-face matching for quoted and unquoted emoji] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-overflow/line-clamp/webkit-line-clamp-050.html.ini b/tests/wpt/meta-legacy-layout/css/css-overflow/line-clamp/webkit-line-clamp-050.html.ini new file mode 100644 index 00000000000..9a1676cf418 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-overflow/line-clamp/webkit-line-clamp-050.html.ini @@ -0,0 +1,2 @@ +[webkit-line-clamp-050.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-pseudo/first-line-below-float.html.ini b/tests/wpt/meta-legacy-layout/css/css-pseudo/first-line-below-float.html.ini new file mode 100644 index 00000000000..077242949df --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-pseudo/first-line-below-float.html.ini @@ -0,0 +1,2 @@ +[first-line-below-float.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html.ini b/tests/wpt/meta-legacy-layout/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html.ini new file mode 100644 index 00000000000..e06425a5209 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html.ini @@ -0,0 +1,18 @@ +[the-check-pseudo-element.tentative.html] + ["::check" should be a valid selector] + expected: FAIL + + ["*::check" should be a valid selector] + expected: FAIL + + ["foo.bar[baz\]::check" should be a valid selector] + expected: FAIL + + ["::check::marker" should be a valid selector] + expected: FAIL + + ["::slotted(*)::check" should be a valid selector] + expected: FAIL + + ["::part(foo)::check" should be a valid selector] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/animation/height-interpolation.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/animation/height-interpolation.html.ini index 4e9354a0d3b..4ef5c8b240d 100644 --- a/tests/wpt/meta-legacy-layout/css/css-sizing/animation/height-interpolation.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/animation/height-interpolation.html.ini @@ -478,3 +478,27 @@ [Web Animations: property <height> from neutral to [fit-content\] at (1.5) should be [fit-content\]] expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (0.5) should be [100px\]] + expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (0.6) should be [100px\]] + expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (1) should be [100px\]] + expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (1.5) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (0.5) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (0.6) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (1) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (1.5) should be [100px\]] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/abspos-1.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/abspos-1.html.ini new file mode 100644 index 00000000000..c57e026f684 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/abspos-1.html.ini @@ -0,0 +1,2 @@ +[abspos-1.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/abspos-2.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/abspos-2.html.ini new file mode 100644 index 00000000000..c5dc50ec598 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/abspos-2.html.ini @@ -0,0 +1,2 @@ +[abspos-2.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/bfc-next-to-float-1.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/bfc-next-to-float-1.html.ini new file mode 100644 index 00000000000..e9afa40967e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/bfc-next-to-float-1.html.ini @@ -0,0 +1,2 @@ +[bfc-next-to-float-1.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/block-height-1.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/block-height-1.html.ini new file mode 100644 index 00000000000..51f953f5c6a --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/block-height-1.html.ini @@ -0,0 +1,27 @@ +[block-height-1.html] + [[data-expected-height\] 1] + expected: FAIL + + [[data-expected-height\] 2] + expected: FAIL + + [[data-expected-height\] 3] + expected: FAIL + + [[data-expected-height\] 7] + expected: FAIL + + [[data-expected-height\] 8] + expected: FAIL + + [[data-expected-height\] 9] + expected: FAIL + + [[data-expected-height\] 13] + expected: FAIL + + [[data-expected-height\] 14] + expected: FAIL + + [[data-expected-height\] 15] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/block-height-2.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/block-height-2.html.ini new file mode 100644 index 00000000000..9b6449c79e3 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/block-height-2.html.ini @@ -0,0 +1,6 @@ +[block-height-2.html] + [[data-expected-height\] 1] + expected: FAIL + + [[data-expected-height\] 2] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/min-width-1.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/min-width-1.html.ini new file mode 100644 index 00000000000..e3446c9bc89 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/min-width-1.html.ini @@ -0,0 +1,2 @@ +[min-width-1.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/positioned-non-replaced-1.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/positioned-non-replaced-1.html.ini new file mode 100644 index 00000000000..025f23f9b67 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/positioned-non-replaced-1.html.ini @@ -0,0 +1,2 @@ +[positioned-non-replaced-1.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/positioned-replaced-1.html.ini b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/positioned-replaced-1.html.ini new file mode 100644 index 00000000000..062731ceee4 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-sizing/stretch/positioned-replaced-1.html.ini @@ -0,0 +1,2 @@ +[positioned-replaced-1.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-text/white-space/white-space-intrinsic-size-021.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/white-space/white-space-intrinsic-size-021.html.ini index a1b8879de43..cf5d3972ffe 100644 --- a/tests/wpt/meta-legacy-layout/css/css-text/white-space/white-space-intrinsic-size-021.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-text/white-space/white-space-intrinsic-size-021.html.ini @@ -65,18 +65,6 @@ [.container > div 77] expected: FAIL - [.container > div 103] - expected: FAIL - - [.container > div 104] - expected: FAIL - - [.container > div 127] - expected: FAIL - - [.container > div 128] - expected: FAIL - [.container > div 135] expected: FAIL @@ -110,14 +98,35 @@ [.container > div 152] expected: FAIL - [.container > div 169] + [.container > div 89] + expected: FAIL + + [.container > div 91] + expected: FAIL + + [.container > div 93] + expected: FAIL + + [.container > div 119] + expected: FAIL + + [.container > div 120] + expected: FAIL + + [.container > div 159] + expected: FAIL + + [.container > div 160] + expected: FAIL + + [.container > div 177] expected: FAIL - [.container > div 170] + [.container > div 178] expected: FAIL - [.container > div 173] + [.container > div 181] expected: FAIL - [.container > div 174] + [.container > div 182] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-ui/text-overflow-ellipsis-multiline-001.html.ini b/tests/wpt/meta-legacy-layout/css/css-ui/text-overflow-ellipsis-multiline-001.html.ini new file mode 100644 index 00000000000..6f62710f6d1 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-ui/text-overflow-ellipsis-multiline-001.html.ini @@ -0,0 +1,2 @@ +[text-overflow-ellipsis-multiline-001.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/calc-serialization-002.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/calc-serialization-002.html.ini new file mode 100644 index 00000000000..e933384770c --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-values/calc-serialization-002.html.ini @@ -0,0 +1,3 @@ +[calc-serialization-002.html] + [testing calc((min(10px, 20%) + max(1rem, 2%)) * 2)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini index 1ff5d2a7b72..a0f3ecf08a5 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini @@ -3796,3 +3796,123 @@ [Web Animations: property <height> from [calc-size(50px, size)\] to [calc-size(min-content, size)\] at (1) should be [100px\]] expected: FAIL + + [CSS Transitions: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [CSS Animations: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [Web Animations: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini index c480e928296..7b0fbe413b9 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini @@ -28,3 +28,33 @@ [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1.5) should be [calc-size(min-content, 300px + size * -0.5)\]] expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (-0.3) should be [calc-size(fit-content, (100px + size) * 1.3 + (200px + size) * -0.3)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0) should be [calc-size(fit-content, (100px + size) * 1 + (200px + size) * 0)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0.5) should be [calc-size(fit-content, (100px + size) * 0.5 + (200px + size) * 0.5)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1) should be [calc-size(fit-content, (100px + size) * 0 + (200px + size) * 1)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1.5) should be [calc-size(fit-content, (100px + size) * -0.5 + (200px + size) * 1.5)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (-0.3) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (0) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (0.5) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1.5) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini index 3a8389477a1..c8802fc001d 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini @@ -43,3 +43,33 @@ [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [calc-size(min-content, -50px + size * 1.5)\]] expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (-0.3) should be [calc-size(fit-content, 260px + (100px + size) * -0.3)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (0) should be [calc-size(fit-content, 200px + (100px + size) * 0)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (0.5) should be [calc-size(fit-content, 100px + (100px + size) * 0.5)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (1) should be [calc-size(fit-content, 0px + (100px + size) * 1)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (1.5) should be [calc-size(fit-content, -100px + (100px + size) * 1.5)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (-0.3) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0.5) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [min-content\]] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini index 67c9993b16a..f973fc571e9 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini @@ -28,3 +28,33 @@ [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (1.5) should be [calc-size(min-content, -100px + size * 1.5)\]] expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (-0.3) should be [calc-size(fit-content, (100px + size) * 1.3 + (200px + size) * -0.3)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0) should be [calc-size(fit-content, (100px + size) * 1 + (200px + size) * 0)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0.5) should be [calc-size(fit-content, (100px + size) * 0.5 + (200px + size) * 0.5)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1) should be [calc-size(fit-content, (100px + size) * 0 + (200px + size) * 1)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1.5) should be [calc-size(fit-content, (100px + size) * -0.5 + (200px + size) * 1.5)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (-0.3) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (0) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (0.5) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (1) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (1.5) should be [min-content\]] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini index ab115e64efe..e3ee8af41b7 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini @@ -43,3 +43,33 @@ [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [calc-size(min-content, -50px + size * 1.5)\]] expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (-0.3) should be [calc-size(max-content, (100px + size) * 1.3 + -60px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (0) should be [calc-size(max-content, (100px + size) * 1 + 0px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (0.5) should be [calc-size(max-content, (100px + size) * 0.5 + 100px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (1) should be [calc-size(max-content, (100px + size) * 0 + 200px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (1.5) should be [calc-size(max-content, (100px + size) * -0.5 + 300px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (-0.3) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0.5) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [min-content\]] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/minmax-length-percent-serialize.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/minmax-length-percent-serialize.html.ini index 3a95b5bb439..401b2b107b3 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/minmax-length-percent-serialize.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/minmax-length-percent-serialize.html.ini @@ -214,3 +214,9 @@ ['max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)' as a computed value should serialize as 'max(10px + (10px + min(10%, 30px)) * 2, 5% + 80px)'.] expected: FAIL + + ['max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)' as a specified value should serialize as 'max(10px + (2 * (10px + min(10%, 30px))), 5% + 5em)'.] + expected: FAIL + + ['max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)' as a computed value should serialize as 'max(10px + (2 * (10px + min(10%, 30px))), 5% + 80px)'.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/round-function.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/round-function.html.ini new file mode 100644 index 00000000000..819fbf742db --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-values/round-function.html.ini @@ -0,0 +1,3 @@ +[round-function.html] + [round(down, (7 - 1) / 3, 1) should be used-value-equivalent to 2] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-values/vh_not_refreshing_on_chrome.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/vh_not_refreshing_on_chrome.html.ini index 599b3e07f8d..9bafc27593e 100644 --- a/tests/wpt/meta-legacy-layout/css/css-values/vh_not_refreshing_on_chrome.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-values/vh_not_refreshing_on_chrome.html.ini @@ -1,2 +1,3 @@ [vh_not_refreshing_on_chrome.html] bug: https://github.com/servo/servo/issues/8984 + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/custom-elements/CustomElementRegistry.html.ini b/tests/wpt/meta-legacy-layout/custom-elements/CustomElementRegistry.html.ini index deab4a1159a..df317e32f5c 100644 --- a/tests/wpt/meta-legacy-layout/custom-elements/CustomElementRegistry.html.ini +++ b/tests/wpt/meta-legacy-layout/custom-elements/CustomElementRegistry.html.ini @@ -2,3 +2,6 @@ type: testharness [customElements.define must upgrade elements in the shadow-including tree order] expected: FAIL + + [customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html.ini b/tests/wpt/meta-legacy-layout/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html.ini new file mode 100644 index 00000000000..d8b66a385b9 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html.ini @@ -0,0 +1,12 @@ +[custom-element-move-reactions.html] + [the disconnected/connected callbacks should be called when no other callback is defined] + expected: FAIL + + [the element should stay connected during the callbacks] + expected: FAIL + + [When connectedMoveCallback is defined, it is called instead of disconnectedCallback/connectedCallback] + expected: FAIL + + [Reactions to atomic move are called in order of element, not in order of operation] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/fetch-preflight.https.sub.any.js.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/fetch-preflight.https.sub.any.js.ini index f290329dfbe..0147b1bc84c 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/fetch-preflight.https.sub.any.js.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/fetch-preflight.https.sub.any.js.ini @@ -1,16 +1,10 @@ [fetch-preflight.https.sub.any.html] - [Same-site fetch with preflight] - expected: FAIL - - [Cross-site fetch with preflight] + [Cross-site fetch with preflight: sec-fetch-site] expected: FAIL [fetch-preflight.https.sub.any.worker.html] - [Same-site fetch with preflight] - expected: FAIL - - [Cross-site fetch with preflight] + [Cross-site fetch with preflight: sec-fetch-site] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/fetch.https.sub.any.js.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/fetch.https.sub.any.js.ini index 3d653a386bc..31cda1be01e 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/fetch.https.sub.any.js.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/fetch.https.sub.any.js.ini @@ -1,114 +1,12 @@ [fetch.https.sub.any.html] - [CORS mode: sec-fetch-site] - expected: FAIL - - [Same-origin mode: sec-fetch-dest] - expected: FAIL - - [Cross-site fetch: sec-fetch-dest] - expected: FAIL - [Cross-site fetch: sec-fetch-site] expected: FAIL - [Same-origin fetch: sec-fetch-mode] - expected: FAIL - - [CORS mode: sec-fetch-mode] - expected: FAIL - - [Same-origin mode: sec-fetch-mode] - expected: FAIL - - [Same-origin mode: sec-fetch-site] - expected: FAIL - - [Same-origin fetch: sec-fetch-site] - expected: FAIL - - [Cross-site fetch: sec-fetch-mode] - expected: FAIL - - [CORS mode: sec-fetch-dest] - expected: FAIL - - [Same-origin fetch: sec-fetch-dest] - expected: FAIL - - [no-CORS mode: sec-fetch-dest] - expected: FAIL - - [Same-site fetch: sec-fetch-dest] - expected: FAIL - - [no-CORS mode: sec-fetch-site] - expected: FAIL - - [Same-site fetch: sec-fetch-site] - expected: FAIL - - [no-CORS mode: sec-fetch-mode] - expected: FAIL - - [Same-site fetch: sec-fetch-mode] - expected: FAIL - [fetch.https.sub.any.worker.html] - [CORS mode: sec-fetch-site] - expected: FAIL - - [Same-origin mode: sec-fetch-dest] - expected: FAIL - - [Cross-site fetch: sec-fetch-dest] - expected: FAIL - [Cross-site fetch: sec-fetch-site] expected: FAIL - [Same-origin fetch: sec-fetch-mode] - expected: FAIL - - [CORS mode: sec-fetch-mode] - expected: FAIL - - [Same-origin mode: sec-fetch-mode] - expected: FAIL - - [Same-origin mode: sec-fetch-site] - expected: FAIL - - [Same-origin fetch: sec-fetch-site] - expected: FAIL - - [Cross-site fetch: sec-fetch-mode] - expected: FAIL - - [CORS mode: sec-fetch-dest] - expected: FAIL - - [Same-origin fetch: sec-fetch-dest] - expected: FAIL - - [no-CORS mode: sec-fetch-dest] - expected: FAIL - - [Same-site fetch: sec-fetch-dest] - expected: FAIL - - [no-CORS mode: sec-fetch-site] - expected: FAIL - - [Same-site fetch: sec-fetch-site] - expected: FAIL - - [no-CORS mode: sec-fetch-mode] - expected: FAIL - - [Same-site fetch: sec-fetch-mode] - expected: FAIL - [fetch.https.sub.any.sharedworker.html] expected: ERROR diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-font-face.sub.tentative.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-font-face.sub.tentative.html.ini index f5e8ecddd7f..eaa11f4cf28 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-font-face.sub.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-font-face.sub.tentative.html.ini @@ -23,8 +23,8 @@ [sec-fetch-mode - Not sent to non-trustworthy cross-site destination] expected: FAIL - [sec-fetch-mode - Not sent to non-trustworthy same-site destination] + [sec-fetch-user - Not sent to non-trustworthy cross-site destination] expected: FAIL - [sec-fetch-user - Not sent to non-trustworthy cross-site destination] + [sec-fetch-dest - Not sent to non-trustworthy cross-site destination] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.https.sub.tentative.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.https.sub.tentative.html.ini index ec48f2ec823..4ec27c8b8aa 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.https.sub.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.https.sub.tentative.html.ini @@ -3,9 +3,6 @@ [background-image sec-fetch-site - Same origin] expected: TIMEOUT - [border-image sec-fetch-site - Same origin] - expected: FAIL - [content sec-fetch-site - Same origin] expected: FAIL @@ -33,9 +30,6 @@ [background-image sec-fetch-site - Same site] expected: TIMEOUT - [border-image sec-fetch-site - Same site] - expected: FAIL - [content sec-fetch-site - Same site] expected: FAIL @@ -138,9 +132,6 @@ [background-image sec-fetch-site - Same-Origin -> Same-Site] expected: TIMEOUT - [border-image sec-fetch-site - Same-Origin -> Same-Site] - expected: FAIL - [content sec-fetch-site - Same-Origin -> Same-Site] expected: FAIL @@ -183,9 +174,6 @@ [background-image sec-fetch-site - Same-Site -> Same-Site] expected: TIMEOUT - [border-image sec-fetch-site - Same-Site -> Same-Site] - expected: FAIL - [content sec-fetch-site - Same-Site -> Same-Site] expected: FAIL @@ -228,9 +216,6 @@ [background-image sec-fetch-mode] expected: TIMEOUT - [border-image sec-fetch-mode] - expected: FAIL - [content sec-fetch-mode] expected: FAIL @@ -243,9 +228,6 @@ [background-image sec-fetch-dest] expected: TIMEOUT - [border-image sec-fetch-dest] - expected: FAIL - [content sec-fetch-dest] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini index f9de5391ad6..741af78eff8 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini @@ -146,3 +146,9 @@ [list-style-image sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL + + [background-image sec-fetch-site - HTTPS downgrade (header not sent)] + expected: TIMEOUT + + [border-image sec-fetch-site - HTTPS downgrade (header not sent)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-a.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-a.sub.html.ini index 6f19fd27de4..dd0b375d338 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-a.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-a.sub.html.ini @@ -4,3 +4,6 @@ [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-legacy-layout/fetch/metadata/generated/element-audio.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.https.sub.html.ini index 4a4d16a5676..03e98a8db48 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.https.sub.html.ini @@ -1,19 +1,10 @@ [element-audio.https.sub.html] - [sec-fetch-site - Same origin, no attributes] - expected: FAIL - [sec-fetch-site - Cross-site, no attributes] expected: FAIL - [sec-fetch-site - Same site, no attributes] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin, no attributes] expected: FAIL @@ -23,38 +14,11 @@ [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 -> Same-Site, no attributes] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site, no attributes] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-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-mode - no attributes] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin=anonymous] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-dest - no attributes] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.sub.html.ini index 3b31ea96366..7cc93481772 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-audio.sub.html.ini @@ -4,3 +4,6 @@ [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-legacy-layout/fetch/metadata/generated/element-iframe.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-iframe.sub.html.ini index 6d496e923ca..b154a96d9de 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-iframe.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-iframe.sub.html.ini @@ -4,3 +4,6 @@ [sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.https.sub.html.ini index 13f6a1ecd91..a42697b3dc8 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.https.sub.html.ini @@ -1,34 +1,16 @@ [element-img.https.sub.html] - [sec-fetch-site - src - Same origin, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same origin, no attributes] - expected: FAIL - [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 site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same 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 - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - [sec-fetch-site - src - Cross-Site -> Same Origin, no attributes] expected: FAIL @@ -47,36 +29,12 @@ [sec-fetch-site - srcset - Cross-Site -> Cross-Site, no attributes] expected: FAIL - [sec-fetch-site - src - Same-Origin -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Origin -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - src - Same-Origin -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Origin -> Same-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 -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - src - Same-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Site -> Same-Site, no attributes] - expected: FAIL - [sec-fetch-site - src - Same-Site -> Cross-Site, no attributes] expected: FAIL @@ -85,33 +43,3 @@ [sec-fetch-site - src - HTTPS downgrade-upgrade, no attributes] expected: FAIL - - [sec-fetch-mode - src - no attributes] - expected: FAIL - - [sec-fetch-mode - src - attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode - src - attributes: crossorigin=anonymous] - expected: FAIL - - [sec-fetch-mode - src - attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-mode - srcset - no attributes] - expected: FAIL - - [sec-fetch-mode - srcset - attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode - srcset - attributes: crossorigin=anonymous] - expected: FAIL - - [sec-fetch-mode - srcset - attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-dest - src - no attributes] - expected: FAIL - - [sec-fetch-dest - srcset - no attributes] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.sub.html.ini index 2d53a409cf2..cd58db1fdd2 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-img.sub.html.ini @@ -10,3 +10,9 @@ [sec-fetch-site - srcset - HTTPS downgrade-upgrade, no attributes] expected: FAIL + + [sec-fetch-site - src - HTTPS downgrade (header not sent), no attributes] + expected: FAIL + + [sec-fetch-site - srcset - HTTPS downgrade (header not sent), no attributes] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini index f083672c134..a1d357e629e 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini @@ -5,15 +5,9 @@ [sec-fetch-site - Cross-site no attributes] expected: FAIL - [sec-fetch-site - Same site no attributes] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect no attributes] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect no attributes] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin no attributes] expected: FAIL @@ -26,36 +20,12 @@ [sec-fetch-site - Same-Origin -> Same Origin no attributes] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site no attributes] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site no attributes] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site no attributes] - expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site no attributes] expected: FAIL - [sec-fetch-mode no attributes] - expected: FAIL - - [sec-fetch-mode attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode attributes: crossorigin=anonymous] - expected: FAIL - - [sec-fetch-mode attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-dest no attributes] - expected: FAIL - [sec-fetch-dest attributes: as=audio] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini index c91344a198e..b75a39a81a0 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini @@ -4,3 +4,6 @@ [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-legacy-layout/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini index 1b884336d31..5bc9bb2c8cf 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini @@ -1,7 +1,4 @@ [element-meta-refresh.https.optional.sub.html] - [sec-fetch-site - Same origin] - expected: FAIL - [sec-fetch-site - Cross-site] expected: FAIL @@ -11,9 +8,6 @@ [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin] expected: FAIL @@ -23,18 +17,9 @@ [sec-fetch-site - Cross-Site -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Origin -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin] - expected: FAIL - [sec-fetch-site - Same-Site -> Same-Site] expected: FAIL @@ -44,8 +29,5 @@ [sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL - [sec-fetch-mode] - expected: FAIL - - [sec-fetch-dest] + [sec-fetch-user] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini index f7602907106..6af80d8f7e8 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini @@ -4,3 +4,6 @@ [sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.https.sub.html.ini index 2280b961e90..f5c5d952e0c 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.https.sub.html.ini @@ -1,13 +1,4 @@ [element-picture.https.sub.html] - [sec-fetch-site - img[src\] - Same origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same origin, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same origin, no attributes] - expected: FAIL - [sec-fetch-site - img[src\] - Cross-site, no attributes] expected: FAIL @@ -17,15 +8,6 @@ [sec-fetch-site - source[srcset\] - Cross-site, no attributes] expected: FAIL - [sec-fetch-site - img[src\] - Same site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same site, no attributes] - expected: FAIL - [sec-fetch-site - img[src\] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] expected: FAIL @@ -35,15 +17,6 @@ [sec-fetch-site - source[srcset\] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] expected: FAIL - [sec-fetch-site - img[src\] - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - [sec-fetch-site - img[src\] - Cross-Site -> Same Origin, no attributes] expected: FAIL @@ -71,24 +44,6 @@ [sec-fetch-site - source[srcset\] - Cross-Site -> Cross-Site, no attributes] expected: FAIL - [sec-fetch-site - img[src\] - Same-Origin -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Origin -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Origin -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Same-Origin -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Origin -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Origin -> Same-Site, no attributes] - expected: FAIL - [sec-fetch-site - img[src\] - Same-Origin -> Cross-Site, no attributes] expected: FAIL @@ -98,24 +53,6 @@ [sec-fetch-site - source[srcset\] - Same-Origin -> Cross-Site, no attributes] expected: FAIL - [sec-fetch-site - img[src\] - Same-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Same-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Site -> Same-Site, no attributes] - expected: FAIL - [sec-fetch-site - img[src\] - Same-Site -> Cross-Site, no attributes] expected: FAIL @@ -125,21 +62,6 @@ [sec-fetch-site - source[srcset\] - Same-Site -> Cross-Site, no attributes] expected: FAIL - [sec-fetch-mode - img[src\] - no attributes] - expected: FAIL - - [sec-fetch-mode - img[srcset\] - no attributes] - expected: FAIL - - [sec-fetch-mode - source[srcset\] - no attributes] - expected: FAIL - - [sec-fetch-mode - img[src\] - attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode - img[srcset\] - attributes: crossorigin] - expected: FAIL - [sec-fetch-mode - source[srcset\] - attributes: crossorigin] expected: FAIL @@ -149,23 +71,8 @@ [sec-fetch-mode - img[srcset\] - attributes: crossorigin=anonymous] expected: FAIL - [sec-fetch-mode - source[srcset\] - attributes: crossorigin=anonymous] - expected: FAIL - [sec-fetch-mode - img[src\] - attributes: crossorigin=use-credentials] expected: FAIL [sec-fetch-mode - img[srcset\] - attributes: crossorigin=use-credentials] expected: FAIL - - [sec-fetch-mode - source[srcset\] - attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-dest - img[src\] - no attributes] - expected: FAIL - - [sec-fetch-dest - img[srcset\] - no attributes] - expected: FAIL - - [sec-fetch-dest - source[srcset\] - no attributes] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.sub.html.ini index 96ee7c6eafe..3232ec358eb 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-picture.sub.html.ini @@ -16,3 +16,12 @@ [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 + + [sec-fetch-site - img[srcset\] - HTTPS downgrade (header not sent), no attributes] + expected: FAIL + + [sec-fetch-site - source[srcset\] - HTTPS downgrade (header not sent), no attributes] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.https.sub.html.ini index ade689e17a5..217a1c62e79 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.https.sub.html.ini @@ -1,34 +1,16 @@ [element-script.https.sub.html] - [sec-fetch-site - Same origin, no attributes] - expected: FAIL - - [sec-fetch-site - Same origin, attributes: type=module] - expected: FAIL - [sec-fetch-site - Cross-site, no attributes] expected: FAIL [sec-fetch-site - Cross-site, attributes: type=module] expected: FAIL - [sec-fetch-site - Same site, no attributes] - expected: FAIL - - [sec-fetch-site - Same 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 - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, attributes: type=module] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin, no attributes] expected: FAIL @@ -47,56 +29,14 @@ [sec-fetch-site - Cross-Site -> Cross-Site, attributes: type=module] expected: FAIL - [sec-fetch-site - Same-Origin -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same Origin, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-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 -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same Origin, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site, attributes: type=module] - expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site, no attributes] expected: FAIL [sec-fetch-site - Same-Site -> Cross-Site, attributes: type=module] expected: FAIL - - [sec-fetch-mode - no attributes] - expected: FAIL - - [sec-fetch-mode - attributes: type=module] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin=anonymous] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-dest - no attributes] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.sub.html.ini index 247f8800f48..ef877c37311 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-script.sub.html.ini @@ -10,3 +10,9 @@ [sec-fetch-site - HTTPS downgrade-upgrade, attributes: type=module] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent), no attributes] + expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent), attributes: type=module] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.https.sub.html.ini index 56699467370..2978eb8f94f 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.https.sub.html.ini @@ -1,19 +1,10 @@ [element-video.https.sub.html] - [sec-fetch-site - Same origin, no attributes] - expected: FAIL - [sec-fetch-site - Cross-site, no attributes] expected: FAIL - [sec-fetch-site - Same site, no attributes] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin, no attributes] expected: FAIL @@ -23,38 +14,11 @@ [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 -> Same-Site, no attributes] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site, no attributes] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-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-mode - no attributes] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin=anonymous] - expected: FAIL - - [sec-fetch-mode - attributes: crossorigin=use-credentials] - expected: FAIL - - [sec-fetch-dest - no attributes] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.sub.html.ini index a33a4431dcc..70d776ac203 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/element-video.sub.html.ini @@ -4,3 +4,6 @@ [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-legacy-layout/fetch/metadata/generated/fetch.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.https.sub.html.ini index 7ae4931e7bc..6153b15aec8 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.https.sub.html.ini @@ -1,19 +1,10 @@ [fetch.https.sub.html] - [sec-fetch-site - Same origin, init: mode=no-cors] - expected: FAIL - [sec-fetch-site - Cross-site, init: mode=no-cors] expected: FAIL - [sec-fetch-site - Same 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 - Same-Origin -> Same-Site -> Same-Origin redirect, init: mode=no-cors] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin, init: mode=no-cors] expected: FAIL @@ -23,35 +14,8 @@ [sec-fetch-site - Cross-Site -> Cross-Site, init: mode=no-cors] expected: FAIL - [sec-fetch-site - Same-Origin -> Same Origin, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-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 -> Same Origin, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site, init: mode=no-cors] - expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site, init: mode=no-cors] expected: FAIL - - [sec-fetch-mode - no init] - expected: FAIL - - [sec-fetch-mode - init: mode=cors] - expected: FAIL - - [sec-fetch-mode - init: mode=no-cors] - expected: FAIL - - [sec-fetch-mode - init: mode=same-origin] - expected: FAIL - - [sec-fetch-dest - no init] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.sub.html.ini index b24c676699b..339edb2c742 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/fetch.sub.html.ini @@ -4,3 +4,6 @@ [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-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini index 03be57bbc6c..9da83749a21 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini @@ -1,19 +1,10 @@ [script-module-import-dynamic.https.sub.html] - [sec-fetch-site - Same origin] - expected: FAIL - [sec-fetch-site - Cross-site] expected: FAIL - [sec-fetch-site - Same site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin] expected: FAIL @@ -23,26 +14,8 @@ [sec-fetch-site - Cross-Site -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Origin -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site] expected: FAIL - - [sec-fetch-mode] - expected: FAIL - - [sec-fetch-dest] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini index 9359c473d82..318935e7f3d 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini @@ -4,3 +4,6 @@ [sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.https.sub.html.ini index bdea2870180..27b82550f15 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.https.sub.html.ini @@ -1,19 +1,10 @@ [script-module-import-static.https.sub.html] - [sec-fetch-site - Same origin] - expected: FAIL - [sec-fetch-site - Cross-site] expected: FAIL - [sec-fetch-site - Same site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin] expected: FAIL @@ -23,26 +14,8 @@ [sec-fetch-site - Cross-Site -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Origin -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site] expected: FAIL - - [sec-fetch-mode] - expected: FAIL - - [sec-fetch-dest] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.sub.html.ini index f2964cf3a1d..bc7a5e2d884 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/script-module-import-static.sub.html.ini @@ -4,3 +4,6 @@ [sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/window-location.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/window-location.sub.html.ini index 54042826d40..6643b0b2cc7 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/window-location.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/window-location.sub.html.ini @@ -22,3 +22,15 @@ [sec-fetch-site - HTTPS downgrade-upgrade - location.replace] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent) - location] + expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent) - location.href] + expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent) - location.assign] + expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent) - location.replace] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html.ini deleted file mode 100644 index 71a0d06a338..00000000000 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[worker-dedicated-constructor.https.sub.html] - [sec-fetch-mode - no options] - expected: FAIL - - [sec-fetch-mode - options: type=module] - expected: FAIL - - [sec-fetch-dest - no options] - expected: FAIL - - [sec-fetch-dest - options: type=module] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini index adf36ed21d4..c4c3f669fe2 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini @@ -1,19 +1,10 @@ [worker-dedicated-importscripts.https.sub.html] - [sec-fetch-site - Same origin] - expected: FAIL - [sec-fetch-site - Cross-site] expected: FAIL - [sec-fetch-site - Same site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] - expected: FAIL - [sec-fetch-site - Cross-Site -> Same Origin] expected: FAIL @@ -23,26 +14,8 @@ [sec-fetch-site - Cross-Site -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Origin -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Same-Site -> Same-Site] - expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site] expected: FAIL - - [sec-fetch-mode] - expected: FAIL - - [sec-fetch-dest] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini index 906554c2f3b..b5ee5020c7a 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini @@ -4,3 +4,6 @@ [sec-fetch-site - HTTPS downgrade-upgrade] expected: FAIL + + [sec-fetch-site - HTTPS downgrade (header not sent)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/navigation.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/navigation.https.sub.html.ini index a53ed577de8..e7801fc0b84 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/navigation.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/navigation.https.sub.html.ini @@ -1,2 +1,3 @@ [navigation.https.sub.html] - expected: TIMEOUT + [undefined: sec-fetch-site] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini index 9f8a81560a0..a04dff862ba 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini @@ -1,8 +1,5 @@ [multiple-redirect-https-downgrade-upgrade.sub.html] expected: TIMEOUT - [Https downgrade-upgrade top level navigation: sec-fetch-dest] - expected: FAIL - [Https downgrade-upgrade script => No headers: sec-fetch-dest] expected: FAIL @@ -18,9 +15,6 @@ [Https downgrade-upgrade object] expected: NOTRUN - [Https downgrade-upgrade top level navigation: sec-fetch-mode] - expected: FAIL - [Https downgrade-upgrade script => No headers: sec-fetch-mode] expected: FAIL @@ -44,3 +38,6 @@ [Https downgrade-upgrade preload] expected: TIMEOUT + + [Https downgrade-upgrade top level navigation: sec-fetch-user] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini index 24727d48899..f6c65ea2f19 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini @@ -17,3 +17,15 @@ [Https downgrade track] expected: NOTRUN + + [Https downgrade top level navigation: sec-fetch-dest] + expected: FAIL + + [Https downgrade top level navigation: sec-fetch-mode] + expected: FAIL + + [Https downgrade top level navigation: sec-fetch-site] + expected: FAIL + + [Https downgrade top level navigation: sec-fetch-user] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/style.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/style.https.sub.html.ini index 644e0f93c46..e977bc4e881 100644 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/style.https.sub.html.ini +++ b/tests/wpt/meta-legacy-layout/fetch/metadata/style.https.sub.html.ini @@ -1,37 +1,3 @@ [style.https.sub.html] - [Cross-Site style: sec-fetch-dest] - expected: FAIL - - [Same-Site style: sec-fetch-dest] - expected: FAIL - [Cross-Site style: sec-fetch-site] expected: FAIL - - [Same-Origin style: sec-fetch-mode] - expected: FAIL - - [Same-Origin, cors style: sec-fetch-mode] - expected: FAIL - - [Same-Site style: sec-fetch-mode] - expected: FAIL - - [Same-Site style: sec-fetch-site] - expected: FAIL - - [Same-Origin, cors style: sec-fetch-site] - expected: FAIL - - [Same-Origin style: sec-fetch-dest] - expected: FAIL - - [Same-Origin, cors style: sec-fetch-dest] - expected: FAIL - - [Same-Origin style: sec-fetch-site] - expected: FAIL - - [Cross-Site style: sec-fetch-mode] - expected: FAIL - diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/worker.https.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/worker.https.sub.html.ini deleted file mode 100644 index 49ad74b23a6..00000000000 --- a/tests/wpt/meta-legacy-layout/fetch/metadata/worker.https.sub.html.ini +++ /dev/null @@ -1,10 +0,0 @@ -[worker.https.sub.html] - [undefined: sec-fetch-mode] - expected: FAIL - - [undefined: sec-fetch-site] - expected: FAIL - - [undefined: sec-fetch-dest] - expected: FAIL - diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini new file mode 100644 index 00000000000..4ecd6d9f753 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini @@ -0,0 +1,3 @@ +[navigation-unload-cross-origin.sub.window.html] + [Cross-origin navigation started from unload handler must be ignored] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a1927668778 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..ef9c00de33f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..62eee6c2c0b --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..39cfa83a2dc --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..fdb0e9a81f1 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..146aa84730e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a195925f726 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..eb4b6f2408e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..a6edb5e7c8e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..99c3038f22f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..1167fcdd4df --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..8055e0e6233 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html.ini new file mode 100644 index 00000000000..142f3700afd --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-position.tentative.html] + [Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html.ini new file mode 100644 index 00000000000..ef0e5ba4fbd --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-range.tentative.html] + [Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini new file mode 100644 index 00000000000..034846a0a91 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-align.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini new file mode 100644 index 00000000000..42e0bb131e5 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-baseline.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a1927668778 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..1d2295f3217 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..ef9c00de33f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..6a6e343494b --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..62eee6c2c0b --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html.ini new file mode 100644 index 00000000000..0902ce494c4 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..39cfa83a2dc --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..2ded60b14cb --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..fdb0e9a81f1 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..322c7ef3429 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..146aa84730e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html.ini new file mode 100644 index 00000000000..602d69c0f16 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a195925f726 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..cd15152caf6 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..eb4b6f2408e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..eec2f16a70d --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..a6edb5e7c8e --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html.ini new file mode 100644 index 00000000000..087fd35298c --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..99c3038f22f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..5b9f81d55a7 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..1167fcdd4df --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..d56ee6bbf95 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..8055e0e6233 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html.ini new file mode 100644 index 00000000000..8108a9bc658 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html.ini new file mode 100644 index 00000000000..142f3700afd --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-position.tentative.html] + [Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js.ini new file mode 100644 index 00000000000..4cc1c748611 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-position.tentative.worker.html] + [Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html.ini new file mode 100644 index 00000000000..ef0e5ba4fbd --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-range.tentative.html] + [Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js.ini new file mode 100644 index 00000000000..ca35bd126f7 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-range.tentative.worker.html] + [Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini new file mode 100644 index 00000000000..034846a0a91 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-align.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html.ini new file mode 100644 index 00000000000..16b4355c27f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-align.tentative.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini new file mode 100644 index 00000000000..42e0bb131e5 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-baseline.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html.ini new file mode 100644 index 00000000000..3d7dd3b6b3a --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-baseline.tentative.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html.ini new file mode 100644 index 00000000000..2150f92957f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-font-change.tentative.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html.ini b/tests/wpt/meta-legacy-layout/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html.ini new file mode 100644 index 00000000000..5ce7adc27b8 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html.ini @@ -0,0 +1,3 @@ +[innertext-whitespace-pre-line.html] + [innerText has collapsed whitespace but preserved newlines with pre-line] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini index 6bec7a732b8..49e3449f144 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini @@ -1,4 +1,4 @@ [iframe_sandbox_popups_nonescaping-2.html] type: testharness [Check that popups from a sandboxed iframe do not escape the sandbox] - expected: FAIL + expected: NOTRUN diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini index 759ada2991f..fcbbf505b49 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini @@ -1,150 +1,169 @@ [parse-a-srcset-attribute.html] type: testharness - expected: CRASH - [" data:,a 1x "] + ["data:,a,, , "] expected: FAIL - ["\\t\\tdata:,a\\t\\t1x\\t\\t"] + [",,,data:,a"] expected: FAIL - ["\\n\\ndata:,a\\n\\n1x\\n\\n"] + [" , ,,data:,a"] expected: FAIL - ["\\v\\vdata:,a\\v\\v1x\\v\\v"] + ["data:,a \\\\,data:;\\,b, data:,c"] expected: FAIL - ["\\f\\fdata:,a\\f\\f1x\\f\\f"] + ["data:,a 0x"] expected: FAIL - ["\\r\\rdata:,a\\r\\r1x\\r\\r"] + ["data:,a -0x"] expected: FAIL - ["\\x0e\\x0edata:,a\\x0e\\x0e1x\\x0e\\x0e"] + ["data:,a 1.0w"] expected: FAIL - ["\\x0f\\x0fdata:,a\\x0f\\x0f1x\\x0f\\x0f"] + ["data:,a 1e0w"] expected: FAIL - ["\\x10\\x10data:,a\\x10\\x101x\\x10\\x10"] + ["data:,a 1www"] expected: FAIL - ["data:,a"] + ["data:,a +1w"] expected: FAIL - ["data:,a "] + ["data:,a 1\\x01w" (trailing U+0001)] expected: FAIL - ["data:,a ,"] + ["data:,a 1 w" (trailing U+00A0)] expected: FAIL - ["data:,a,"] + ["data:,a 1 w" (trailing U+1680)] expected: FAIL - ["data:,a, "] + ["data:,a 1 w" (trailing U+2000)] expected: FAIL - ["data:,a,,,"] + ["data:,a 1 w" (trailing U+2001)] expected: FAIL - ["data:,a,, , "] + ["data:,a 1 w" (trailing U+2002)] expected: FAIL - [" data:,a"] + ["data:,a 1 w" (trailing U+2003)] expected: FAIL - [",,,data:,a"] + ["data:,a 1 w" (trailing U+2004)] expected: FAIL - [" , ,,data:,a"] + ["data:,a 1 w" (trailing U+2005)] expected: FAIL - [" data:,a"] + ["data:,a 1 w" (trailing U+2006)] expected: FAIL - ["data:,a "] + ["data:,a 1 w" (trailing U+2007)] expected: FAIL - ["data:,a 1x"] + ["data:,a 1 w" (trailing U+2008)] expected: FAIL - ["data:,a 1x "] + ["data:,a 1 w" (trailing U+2009)] expected: FAIL - ["data:,a 1x,"] + ["data:,a 1 w" (trailing U+200A)] expected: FAIL - ["data:,a ( , data:,b 1x, ), data:,c"] + ["data:,a 1w" (trailing U+200C)] expected: FAIL - ["data:,a ((( , data:,b 1x, ), data:,c"] + ["data:,a 1w" (trailing U+200D)] expected: FAIL - ["data:,a [ , data:,b 1x, \], data:,c"] + ["data:,a 1 w" (trailing U+202F)] expected: FAIL - ["data:,a { , data:,b 1x, }, data:,c"] + ["data:,a 1 w" (trailing U+205F)] expected: FAIL - ["data:,a \\" , data:,b 1x, \\", data:,c"] + ["data:,a 1 w" (trailing U+3000)] expected: FAIL - ["data:,a \\\\,data:;\\,b, data:,c"] + ["data:,a 1w" (trailing U+FEFF)] expected: FAIL - ["data:,a, data:,b ("] + ["data:,a 1.x"] expected: FAIL - ["data:,a, data:,b ( "] + ["data:,a +1x"] expected: FAIL - ["data:,a, data:,b (,"] + ["data:,a 1w 1.0h"] expected: FAIL - ["data:,a, data:,b (x"] + ["data:,a 1w 1e0h"] expected: FAIL - ["data:,a, data:,b ()"] + ["data:,a 1w 1hhh"] expected: FAIL - ["data:,a /*, data:,b, data:,c */"] + ["data:,a 1w +1h"] expected: FAIL - ["data:,a //, data:,b"] + ["data:,a 1w 1\\x01h" (trailing U+0001)] expected: FAIL - ["data:,a 1w 1h"] + ["data:,a 1w 1 h" (trailing U+00A0)] expected: FAIL - ["data:,a 1h 1w"] + ["data:,a 1w 1 h" (trailing U+1680)] expected: FAIL - ["data:,a 1w"] + ["data:,a 1w 1 h" (trailing U+2000)] expected: FAIL - ["data:,a 0x"] + ["data:,a 1w 1 h" (trailing U+2001)] expected: FAIL - ["data:,a -0x"] + ["data:,a 1w 1 h" (trailing U+2002)] expected: FAIL - ["data:,a 1e0x"] + ["data:,a 1w 1 h" (trailing U+2003)] expected: FAIL - ["data:,a 1E0x"] + ["data:,a 1w 1 h" (trailing U+2004)] expected: FAIL - ["data:,a 1e-1x"] + ["data:,a 1w 1 h" (trailing U+2005)] expected: FAIL - ["data:,a 1.5e1x"] + ["data:,a 1w 1 h" (trailing U+2006)] expected: FAIL - ["data:,a .5x"] + ["data:,a 1w 1 h" (trailing U+2007)] expected: FAIL - ["data:,a .5e1x"] + ["data:,a 1w 1 h" (trailing U+2008)] expected: FAIL - ["data:,a 1.0x"] + ["data:,a 1w 1 h" (trailing U+2009)] expected: FAIL + ["data:,a 1w 1 h" (trailing U+200A)] + expected: FAIL + + ["data:,a 1w 1h" (trailing U+200C)] + expected: FAIL + + ["data:,a 1w 1h" (trailing U+200D)] + expected: FAIL + + ["data:,a 1w 1 h" (trailing U+202F)] + expected: FAIL + + ["data:,a 1w 1 h" (trailing U+205F)] + expected: FAIL + + ["data:,a 1w 1 h" (trailing U+3000)] + expected: FAIL + + ["data:,a 1w 1h" (trailing U+FEFF)] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini index 19b3d41fe42..373ba604823 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini @@ -16,3 +16,6 @@ [Divs and imgs should be allowed as direct children of select and within options without a datalist.] expected: FAIL + + [Input tags should parse inside select instead of closing the select.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini index f7b6c87f9c5..d566064c0e0 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini @@ -16,3 +16,18 @@ [dialog.showModal() should coalesce asynchronous toggle events.] expected: FAIL + + [dialog.show() should not open if beforetoggle removes] + expected: FAIL + + [dialog.show() should not open if beforetoggle calls showPopover] + expected: FAIL + + [dialog.showModal() should not double-set open/close if beforetoggle re-opens] + expected: FAIL + + [dialog.showModal() should not open if beforetoggle removes] + expected: FAIL + + [dialog.showModal() should not open if beforetoggle calls showPopover] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini b/tests/wpt/meta-legacy-layout/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini deleted file mode 100644 index 53acb938c1b..00000000000 --- a/tests/wpt/meta-legacy-layout/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[module-static-import-delayed.html] - [document.write in an imported module] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/webappapis/update-rendering/child-document-raf-order.html.ini b/tests/wpt/meta-legacy-layout/html/webappapis/update-rendering/child-document-raf-order.html.ini new file mode 100644 index 00000000000..312c6689170 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/webappapis/update-rendering/child-document-raf-order.html.ini @@ -0,0 +1,3 @@ +[child-document-raf-order.html] + [Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/selection/caret-position-should-be-correct-while-moveup-movedown.html.ini b/tests/wpt/meta-legacy-layout/selection/caret-position-should-be-correct-while-moveup-movedown.html.ini new file mode 100644 index 00000000000..32a129e1440 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/selection/caret-position-should-be-correct-while-moveup-movedown.html.ini @@ -0,0 +1,72 @@ +[caret-position-should-be-correct-while-moveup-movedown.html] + [Caret position should be correct in moving up horizontal div when selection was left to right with line granularity] + expected: FAIL + + [Caret position should be correct in moving up horizontal div when selection was right to left with line granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was left to right with line granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was right to left with line granularity] + expected: FAIL + + [Caret position should be correct in moving up horizontal div when selection was left to right with paragraph granularity] + expected: FAIL + + [Caret position should be correct in moving up horizontal div when selection was right to left with paragraph granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was left to right with paragraph granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was right to left with paragraph granularity] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-rl div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-rl div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-rl div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-rl div when selection was bottom to top] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html.ini b/tests/wpt/meta-legacy-layout/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html.ini new file mode 100644 index 00000000000..4448f3238a0 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html.ini @@ -0,0 +1,32 @@ +[Selection-getComposedRanges-dom-mutations-removal.html?mode=closed] + [Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.] + expected: FAIL + + [Range is fully in shadow tree. Removing parent of shadow host collapses composed StaticRange.] + expected: FAIL + + [Range is in light DOM. Removing startContainer rescopes new composed range to its parent.] + expected: FAIL + + [Range is across shadow trees. Replacing shadowRoot content rescopes new composed range to the shadowRoot.] + expected: FAIL + + [Range is between two light slotted contents. Removing start container rescopes to its parent in light tree.] + expected: FAIL + + +[Selection-getComposedRanges-dom-mutations-removal.html?mode=open] + [Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.] + expected: FAIL + + [Range is fully in shadow tree. Removing parent of shadow host collapses composed StaticRange.] + expected: FAIL + + [Range is in light DOM. Removing startContainer rescopes new composed range to its parent.] + expected: FAIL + + [Range is across shadow trees. Replacing shadowRoot content rescopes new composed range to the shadowRoot.] + expected: FAIL + + [Range is between two light slotted contents. Removing start container rescopes to its parent in light tree.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html.ini b/tests/wpt/meta-legacy-layout/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html.ini new file mode 100644 index 00000000000..97d7f6316fd --- /dev/null +++ b/tests/wpt/meta-legacy-layout/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html.ini @@ -0,0 +1,9 @@ +[Selection-getComposedRanges-slot.html] + [Setting the range to start on slotted content and end in shadow tree, should follow DOM tree order.] + expected: FAIL + + [Setting the range to start and end on slotted content, should follow DOM tree order.] + expected: FAIL + + [Setting the range to start on unslotted content and end in shadow tree, should follow DOM tree order.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/url/failure.html.ini b/tests/wpt/meta-legacy-layout/url/failure.html.ini index e739baf2ea5..c1929ede7ab 100644 --- a/tests/wpt/meta-legacy-layout/url/failure.html.ini +++ b/tests/wpt/meta-legacy-layout/url/failure.html.ini @@ -728,3 +728,6 @@ [Location's href: stun://[:1\] should throw] expected: FAIL + + [Location's href: non-special://host\\a should throw] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/url/percent-encoding.window.js.ini b/tests/wpt/meta-legacy-layout/url/percent-encoding.window.js.ini index 47e8f02f61e..41167982b64 100644 --- a/tests/wpt/meta-legacy-layout/url/percent-encoding.window.js.ini +++ b/tests/wpt/meta-legacy-layout/url/percent-encoding.window.js.ini @@ -1,10 +1,4 @@ [percent-encoding.window.html] - [Input † with encoding windows-1252] - expected: FAIL - - [Input − with encoding shift_jis] - expected: FAIL - [Input \x0eA with encoding iso-2022-jp] expected: FAIL @@ -14,11 +8,5 @@ [Input † with encoding big5] expected: FAIL - [Input † with encoding euc-kr] - expected: FAIL - - [Input ‾\\ with encoding iso-2022-jp] - expected: FAIL - [Input U+d800 with encoding windows-1252] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/wasm/jsapi/jspi/js-promise-integration.any.js.ini b/tests/wpt/meta-legacy-layout/wasm/jsapi/jspi/js-promise-integration.any.js.ini new file mode 100644 index 00000000000..bcf0c39c471 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/wasm/jsapi/jspi/js-promise-integration.any.js.ini @@ -0,0 +1,63 @@ +[js-promise-integration.any.html] + expected: ERROR + [Promising function always entered] + expected: FAIL + + [Always get a Promise] + expected: FAIL + + [Suspend once] + expected: FAIL + + [Suspend/resume in a loop] + expected: FAIL + + [Suspending with mismatched args and via Proxy] + expected: FAIL + + [Make sure we actually suspend] + expected: FAIL + + [Do not suspend if the import's return value is not a Promise] + expected: FAIL + + [Catch rejected promise] + expected: FAIL + + [Promising with no return] + expected: FAIL + + [Suspend two modules] + expected: FAIL + + +[js-promise-integration.any.worker.html] + [Promising function always entered] + expected: FAIL + + [Always get a Promise] + expected: FAIL + + [Suspend once] + expected: FAIL + + [Suspend/resume in a loop] + expected: FAIL + + [Suspending with mismatched args and via Proxy] + expected: FAIL + + [Make sure we actually suspend] + expected: FAIL + + [Do not suspend if the import's return value is not a Promise] + expected: FAIL + + [Catch rejected promise] + expected: FAIL + + [Promising with no return] + expected: FAIL + + [Suspend two modules] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/wasm/jsapi/jspi/rejects.any.js.ini b/tests/wpt/meta-legacy-layout/wasm/jsapi/jspi/rejects.any.js.ini new file mode 100644 index 00000000000..94e3c87d1a7 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/wasm/jsapi/jspi/rejects.any.js.ini @@ -0,0 +1,32 @@ +[rejects.any.worker.html] + [Throw after the first suspension] + expected: FAIL + + [Throw before suspending] + expected: FAIL + + [Throw and propagate via Promise] + expected: FAIL + + [Stack overflow] + expected: FAIL + + [Try to suspend JS] + expected: FAIL + + +[rejects.any.html] + [Throw after the first suspension] + expected: FAIL + + [Throw before suspending] + expected: FAIL + + [Throw and propagate via Promise] + expected: FAIL + + [Stack overflow] + expected: FAIL + + [Try to suspend JS] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/webmessaging/with-ports/017.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/with-ports/017.html.ini deleted file mode 100644 index c7946fc91b4..00000000000 --- a/tests/wpt/meta-legacy-layout/webmessaging/with-ports/017.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[017.html] - expected: TIMEOUT - [origin of the script that invoked the method, about:blank] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini deleted file mode 100644 index b7b36c1d3a4..00000000000 --- a/tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[018.html] - expected: TIMEOUT - [origin of the script that invoked the method, javascript:] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html.ini b/tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html.ini new file mode 100644 index 00000000000..76d85b5bdf6 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html.ini @@ -0,0 +1,4 @@ +[localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html] + expected: TIMEOUT + [StorageKey: test 3P about:blank window opened from a 3P iframe] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/workers/WorkerGlobalScope-close.html.ini b/tests/wpt/meta-legacy-layout/workers/WorkerGlobalScope-close.html.ini new file mode 100644 index 00000000000..24daae4c2e7 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/workers/WorkerGlobalScope-close.html.ini @@ -0,0 +1,3 @@ +[WorkerGlobalScope-close.html] + [Test sending a message after closing.] + expected: FAIL diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index f19ef328fdd..239e5bf47d6 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -3745,6 +3745,13 @@ {} ] ], + "text-box-trim-end-and-widows.html": [ + "8ff033342c19062e5a30a13b9758120329e5f8c1", + [ + null, + {} + ] + ], "text-in-inline-interrupted-by-float.html": [ "fbb26507a21c3d93cd47c0595f697e3e92ac9fb9", [ @@ -5182,6 +5189,13 @@ null, {} ] + ], + "text-overflow-ellipsis-multiline-crash.html": [ + "a281df3a28068f38c370b786c94c532066c7e505", + [ + null, + {} + ] ] }, "neg-outline-offset-border-radius-crash.html": [ @@ -115349,7 +115363,7 @@ ] ], "overflow-applies-to-009.xht": [ - "5867a68b7a574334d28b8850e0ddb47301ab6c61", + "1a82a0806544a565e5c6564edc3f7c276b41f09a", [ null, [ @@ -146484,6 +146498,19 @@ {} ] ], + "text-indent-and-wide-float.html": [ + "59885e7c2c08805241e93004eeb5a6c9e374e828", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "trailing-child-margin-000.html": [ "d204483a33ebff421cf9f3da9fab2d1183fcd1c0", [ @@ -146783,6 +146810,19 @@ {} ] ], + "transform-025.html": [ + "58020065dc112080cc1e6b5bdacf52f75a976f70", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "truncated-margin-at-fragmentainer-end-001.html": [ "cfb8590f9026194020afaea854f1d4d9fc570b49", [ @@ -218995,6 +219035,19 @@ {} ] ], + "webkit-line-clamp-050.html": [ + "973871b72d85328aa1b8f32a8c539cd657392102", + [ + null, + [ + [ + "/css/css-overflow/line-clamp/reference/webkit-line-clamp-050-ref.html", + "==" + ] + ], + {} + ] + ], "webkit-line-clamp-block-in-inline-001.html": [ "75d1de3bf5bcf5d00d6980de4a70845e9f7ae8e4", [ @@ -225516,6 +225569,19 @@ {} ] ], + "first-line-below-float.html": [ + "2e32513e9c7be3cb548732d821a453db89268f45", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "first-line-change-inline-color-nested.html": [ "4a58f1ea5b623ffa5acd2993be16de399cd24127", [ @@ -240753,6 +240819,86 @@ {} ] ], + "stretch": { + "abspos-1.html": [ + "a64f0d05fdf39c3afd0cfb2818b4f2c9912efee1", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "abspos-2.html": [ + "80d815113d18cbc30548c1f928fe70dfefd09b4a", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "bfc-next-to-float-1.html": [ + "9c2a60e6c01917f590d09710adb43c2203294fb2", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "min-width-1.html": [ + "a1a39073e88d4626be7c469611e3593415849e7a", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "positioned-non-replaced-1.html": [ + "b66916b8ab486742a67b4f33027640e4ff84142d", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "positioned-replaced-1.html": [ + "60b817933d33301c755be3785fd7cf56607c4539", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ] + }, "svg-intrinsic-size-005.html": [ "68be3f2e1156271e3c2139ee764abd8ec8d045a0", [ @@ -252133,6 +252279,19 @@ {} ] ], + "below-float.html": [ + "a386232fd0e062c449ddadb3c23289f0df4c21b3", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "text-indent-each-line-hanging.html": [ "2c3ac08df4a8a7962ec3ce1e1d1318ee39bdd7fb", [ @@ -289251,6 +289410,19 @@ {} ] ], + "text-overflow-ellipsis-multiline-001.html": [ + "5987817a5c98bdef181c37d37ff2de4cfd9db2f8", + [ + null, + [ + [ + "/css/css-ui/reference/text-overflow-ellipsis-multiline-001-ref.html", + "==" + ] + ], + {} + ] + ], "text-overflow-ruby.html": [ "c8abebb7206b57444051937c171b2884ec750403", [ @@ -295115,6 +295287,19 @@ {} ] ], + "inline-child-with-overflow-shadow.html": [ + "2c2d50af60c1b1eceff434253e432cf6bb70587c", + [ + null, + [ + [ + "/css/css-view-transitions/inline-child-with-overflow-shadow-ref.html", + "==" + ] + ], + {} + ] + ], "inline-element-size.html": [ "a571ace718a32882d727ac965bb2431451d8046c", [ @@ -295129,7 +295314,7 @@ ] ], "inline-with-offset-from-containing-block.html": [ - "026ecb240a35f1ca1c7044f95f4d09468af9e05f", + "6bbb8b49392c84adecf32f972e4889f2ba356968", [ null, [ @@ -295149,7 +295334,7 @@ ], [ 0, - 1400 + 1500 ] ] ] @@ -295171,6 +295356,122 @@ ] ], "layered-capture": { + "capture-mode-flat.tentative.html": [ + "beed17c89735e419a8bcd33d903d913aa7c7227b", + [ + null, + [ + [ + "/css/css-view-transitions/layered-capture/nested-opacity-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 255 + ], + [ + 0, + 515 + ] + ] + ] + ] + } + ] + ], + "capture-mode-layered.tentative.html": [ + "d1f190343b0c6e1526dbc44ee207b2896732ec06", + [ + null, + [ + [ + "/css/css-view-transitions/layered-capture/nested-opacity-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 255 + ], + [ + 0, + 515 + ] + ] + ] + ] + } + ] + ], + "nested-opacity-backdrop-blend-animated.tentative.html": [ + "73100015cddd61558b01b092c18f25be6ae3ad08", + [ + null, + [ + [ + "/css/css-view-transitions/layered-capture/nested-opacity-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 255 + ], + [ + 0, + 515 + ] + ] + ] + ] + } + ] + ], + "nested-opacity-backdrop-blend.tentative.html": [ + "0042d9676f2fbb26f2140ae8843995d478ab0942", + [ + null, + [ + [ + "/css/css-view-transitions/layered-capture/nested-opacity-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 255 + ], + [ + 0, + 515 + ] + ] + ] + ] + } + ] + ], "opacity-capture-observable-when-flat.tentative.html": [ "6d4ddbe86b175ff0cae19b3ed4a4cb0d827e22ec", [ @@ -295200,6 +295501,64 @@ } ] ], + "opacity-resets-after-done.tentative.html": [ + "7616638dc5ee816a3f9c9442a00eea3e32c73741", + [ + null, + [ + [ + "/css/css-view-transitions/layered-capture/nested-opacity-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 255 + ], + [ + 0, + 515 + ] + ] + ] + ] + } + ] + ], + "opacity-resets-after-skip.tentative.html": [ + "e7a11ebe33125707f381c15f848c5f10ed25d50a", + [ + null, + [ + [ + "/css/css-view-transitions/layered-capture/nested-opacity-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 255 + ], + [ + 0, + 515 + ] + ] + ] + ] + } + ] + ], "tree-effects.tentative.sub.html": [ "31bb324e633117f3a2e4fd7d6fb0826fae4dce0b", [ @@ -296951,42 +297310,13 @@ } ] ], - "opacity-backdrop-blend-animated.tentative.html": [ - "835f068c49211a10e0d8259953a918ffd5f2236b", - [ - null, - [ - [ - "/css/css-view-transitions/nested/nested-opacity-ref.html", - "==" - ] - ], - { - "fuzzy": [ - [ - null, - [ - [ - 0, - 255 - ], - [ - 0, - 515 - ] - ] - ] - ] - } - ] - ], - "opacity-backdrop-blend.tentative.html": [ - "ea8acfc86b070ca375d4ebda54d48c6a42018696", + "render-element.tentative.html": [ + "59a5a108314c0270b561339bf9a8a0cb6fdfe27d", [ null, [ [ - "/css/css-view-transitions/nested/nested-opacity-ref.html", + "/css/css-view-transitions/nested/nested-ref-100.html", "==" ] ], @@ -297008,97 +297338,40 @@ ] } ] - ], - "opacity-resets-after-done.tentative.html": [ - "7616638dc5ee816a3f9c9442a00eea3e32c73741", + ] + }, + "nested-elements-in-overflow.html": [ + "cce8fe8d8ffee2ffec953fc2207aed280b809be4", + [ + null, [ - null, [ + "/css/css-view-transitions/nested-elements-in-overflow-ref.html", + "==" + ] + ], + { + "fuzzy": [ [ - "/css/css-view-transitions/nested/nested-opacity-ref.html", - "==" - ] - ], - { - "fuzzy": [ + null, [ - null, [ - [ - 0, - 255 - ], - [ - 0, - 515 - ] - ] - ] - ] - } - ] - ], - "opacity-resets-after-skip.tentative.html": [ - "e7a11ebe33125707f381c15f848c5f10ed25d50a", - [ - null, - [ - [ - "/css/css-view-transitions/nested/nested-opacity-ref.html", - "==" - ] - ], - { - "fuzzy": [ - [ - null, + 0, + 60 + ], [ - [ - 0, - 255 - ], - [ - 0, - 515 - ] + 0, + 500 ] ] ] - } - ] - ], - "render-element.tentative.html": [ - "59a5a108314c0270b561339bf9a8a0cb6fdfe27d", - [ - null, - [ - [ - "/css/css-view-transitions/nested/nested-ref-100.html", - "==" - ] ], - { - "fuzzy": [ - [ - null, - [ - [ - 0, - 255 - ], - [ - 0, - 515 - ] - ] - ] - ] - } - ] + "timeout": "long" + } ] - }, + ], "new-and-old-sizes-match.html": [ - "f23f63d28ffa31c185858d5af8f639a905329ad8", + "7245e4b42f26a00710be23f8d545b1fcb6c8766e", [ null, [ @@ -297114,11 +297387,11 @@ [ [ 0, - 15 + 25 ], [ 0, - 500 + 1500 ] ] ] @@ -298304,6 +298577,19 @@ {} ] ], + "outer-padding-inner-background.html": [ + "6bbcf514ab47241fee2a4f5475cc364e176ed26c", + [ + null, + [ + [ + "/css/css-view-transitions/outer-padding-inner-background-ref.html", + "==" + ] + ], + {} + ] + ], "paint-holding-in-iframe.html": [ "4f2aa5360b03b8eaf65400203251ba936b947144", [ @@ -316135,7 +316421,7 @@ ] ], "backdrop-filter-plus-filter.html": [ - "546786d8e60ac87e4d1dbf2c6bfdd7332cab1e01", + "5c83faae8686bd1b22f655f9aac2c50f1ab32a0a", [ null, [ @@ -316144,7 +316430,23 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 1 + ], + [ + 0, + 210 + ] + ] + ] + ] + } ] ], "backdrop-filter-plus-opacity.html": [ @@ -326913,6 +327215,354 @@ ] } ] + ], + "2d.composite.grid.filter.no_shadow.drawImage.html": [ + "8e6b95ae2210375f6e0db2cfa408bf4a7694deb3", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.fillRect.html": [ + "5dca89e3c12b884f9d226d9b6b8f10f1a67d68ae", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.pattern.html": [ + "6b3c4c6a5890f555e3831ea7a27c5896a2f08b5f", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.drawImage.html": [ + "f6872b221274b543dd16aa7568dc9f5b36da3791", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.fillRect.html": [ + "1c68c0e454059db077a2469143608ad7f95cdb7c", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.pattern.html": [ + "1e3f14fb9a3c1b62ec7b21c4ac7152d958811616", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage.html": [ + "31e0fba79189df8fab876b886a278509abbc8581", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect.html": [ + "e14c336868ecdef5024ba8fd2f9d4b6bdb202d25", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.pattern.html": [ + "6f8159466dbd72bf6ae879484d2eb2a2b5db00fa", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.drawImage.html": [ + "84527f5a2832d77cbd1e358ebee7bb9fbf2ae483", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.fillRect.html": [ + "46bc366c8ac0cdad497c6145db3c8b16e96ee80e", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.pattern.html": [ + "e636330c59f5b3b37f790c060e729730640b37af", + [ + null, + [ + [ + "/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] ] }, "filters": { @@ -329300,6 +329950,45 @@ {} ] ], + "2d.text.measure.text-clusters-rendering-align.tentative.html": [ + "159efb4fee4dd290f35faa76d86b407418a4680b", + [ + null, + [ + [ + "/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-baseline.tentative.html": [ + "c20e076a3514921f6a82b10304c04fdb01c1da0e", + [ + null, + [ + [ + "/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-font-change.tentative.html": [ + "a927cfcd33094f502c3d46fd88da7bd26381256b", + [ + null, + [ + [ + "/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html", + "==" + ] + ], + {} + ] + ], "2d.text.writingmode.html": [ "3d2fe020b0bb4298318ba0a854a19a4d9117319a", [ @@ -329355,6 +330044,704 @@ } }, "offscreen": { + "compositing": { + "2d.composite.grid.filter.no_shadow.drawImage.html": [ + "72b23aeeafb87787e402a298b2b9c6b87a6a1cb5", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.drawImage.w.html": [ + "89f4dba75b570cc5ff514cd02d52b7597a3c9dfe", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.fillRect.html": [ + "3f8fdc8164d1fc971fd30d881d4a7ad4d28580fc", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.fillRect.w.html": [ + "37839bf8a8b460c1a500c6ba05047210edc3120f", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.pattern.html": [ + "0bb970ab3f84683b2ce40a140bd7288c13112838", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.no_shadow.pattern.w.html": [ + "81d0a8e6a693ef89a730a7bbc12bddd09c0a8fc6", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.drawImage.html": [ + "5c9e992c7ce72164d04615a9d4fda9b629b21a85", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.drawImage.w.html": [ + "08e66abd46439ecb07fa8312fc5c0dad1bd28854", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.fillRect.html": [ + "0f6b88fd5e9e16e69213bdeb4dc66bb49c21427d", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.fillRect.w.html": [ + "f754f538b560b5bfd95539d4fd2033f3dbbea34a", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.pattern.html": [ + "e89aff9196dc194b5a4dd12a41f24312a0173e3d", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.filter.shadow.pattern.w.html": [ + "79f7aab01cd4e14509bc951dd3e67bdfb1e60667", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage.html": [ + "54a53b46576b55657183a59248937405efe3031a", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage.w.html": [ + "4750ed210ffe98e6b7de2443764fd648e69e1254", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect.html": [ + "e69af8a79a92adbc0b3eff5e27a6295e873180f4", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect.w.html": [ + "0cfc23ab86a5d823f695bc11d1ac2a24a94feb5d", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.pattern.html": [ + "b6008b7c79f3106750ec7e07bdf1d98582e02843", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.no_shadow.pattern.w.html": [ + "ef952ce12cdaa3ea260cbc0ff4aa0ed4de3ea68e", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.drawImage.html": [ + "d25f183aeb8bc510e76a09c5571332e066c30aed", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.drawImage.w.html": [ + "c66b467d627df12414affa25f21a23d6088cff6a", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.fillRect.html": [ + "3fdbfa72cafc7fe9a5e2e8eaf41662fd2c4013d8", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.fillRect.w.html": [ + "519631612f05abd4f078c6d6a632dcbfb4913ace", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.pattern.html": [ + "d9df6be84f174dde2a3d1f4b957cf4f8315d32ad", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ], + "2d.composite.grid.no_filter.shadow.pattern.w.html": [ + "5c698e8c7603057f8e6207dcca9396aae585b43e", + [ + null, + [ + [ + "/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 10210 + ] + ] + ] + ] + } + ] + ] + }, "filters": { "2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html": [ "cc6c548499afb98698e2d498ba4392fcbb931507", @@ -332026,6 +333413,84 @@ {} ] ], + "2d.text.measure.text-clusters-rendering-align.tentative.html": [ + "4fc41c79cc44eba408bba38829ee42e1c7ead945", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-align.tentative.w.html": [ + "35ddd54bfd78bad7f43ac91d0dfff53a541dbd49", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-baseline.tentative.html": [ + "84def142a9ba38c3901d4fb45d53f9ec9ffecc8c", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-baseline.tentative.w.html": [ + "9227776d8c8f5c274638be3c4acd0cfec4632ed9", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-font-change.tentative.html": [ + "c8e3383a4623ae1ba9b9c76fd5073a4defb36a3b", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.measure.text-clusters-rendering-font-change.tentative.w.html": [ + "6bca8ebbc3515d3c40039390737cd9171d74be95", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html", + "==" + ] + ], + {} + ] + ], "canvas.2d.fontStretch.condensed.html": [ "0cbd5e3c1f18935d04a18359caa8c91c89fd1806", [ @@ -334844,6 +336309,19 @@ {} ] ], + "table-align-float.xhtml": [ + "05de0d6b2807d7df911a88d2429e2f265152478b", + [ + null, + [ + [ + "/html/rendering/non-replaced-elements/tables/table-align-float-ref.xhtml", + "==" + ] + ], + {} + ] + ], "table-border-1.html": [ "333881399555a8018be91b9c6053b15be694def3", [ @@ -347033,6 +348511,19 @@ }, "svg": { "animations": { + "animate-display-to-none-001.html": [ + "ce8e493840e9743bdf211bd5e52b0d2fe7f84cb5", + [ + null, + [ + [ + "/svg/struct/reftests/reference/green-100x100.html", + "==" + ] + ], + {} + ] + ], "conditional-processing-01.html": [ "fe3958f71f3ba6fdc37b65afd02aeabe5dc88bb7", [ @@ -349189,6 +350680,19 @@ {} ] ], + "small-nested-viewbox.html": [ + "3d9fb8cb45f57cc2e2fcf6293e9ebef5987704ce", + [ + null, + [ + [ + "/svg/painting/reftests/small-nested-viewbox-ref.html", + "==" + ] + ], + {} + ] + ], "symbol-in-mask.html": [ "da1e11f1704468c2ec77476ea1c566299737d9f9", [ @@ -355114,12 +356618,16 @@ "bb0cea9f396c41faf9f045b402fb3b8ee99e1f4a", [] ], + "safari-wptrunner.yml": [ + "0860533dc92a398d23c965e7b72d3c65a2a491e4", + [] + ], "safari_stable.yml": [ - "0df13f43d4403b5aa5bf61868849f7ce37832168", + "7c344fe667f7dbf738f114bdc82893c8130e466e", [] ], "safari_technology_preview.yml": [ - "01380aa718e325b5a4b31b4db1833afe0afb8a93", + "70827a365ac048f374a8f98ecf5d695bc472d78e", [] ], "wpt_fyi_notify.yml": [ @@ -355541,7 +357049,7 @@ [] ], "okp_importKey.js": [ - "5699341d9e49d4ab5af1cf4bc33fa515d969f01e", + "0e6a016fe2096015686e5616215f9bb81915f50a", [] ], "okp_importKey_failures_fixtures.js": [ @@ -357953,7 +359461,7 @@ [] ], "helpers.js": [ - "0f20a71237c83589f676afeacb4660b39457fea3", + "56e2a2812b65a7978242654cf9cd82ff756a9fa9", [] ], "reporting_origin.py": [ @@ -420860,6 +422368,10 @@ "7a3591b5eead803163450acc1cfed4a3e8fd39d1", [] ], + "webkit-line-clamp-050-ref.html": [ + "1fa0720aeaf433714bfc80a3dd425197565e58e2", + [] + ], "webkit-line-clamp-block-in-inline-001-ref.html": [ "79f2e409109d72a76e12374220bd423aba16f4eb", [] @@ -433253,6 +434765,10 @@ "660a7c4d52e7e2a763bfffc7582469896a5835b8", [] ], + "text-overflow-ellipsis-multiline-001-ref.html": [ + "a26b8260eae55de6c9a9e0d2f3b6df3bb439b93b", + [] + ], "transparent-accent-color-001-ref.html": [ "91a9600e180cd9636b2ec3aa0ad63f79bbc334b5", [] @@ -435138,6 +436654,10 @@ "44a41f1bf93366e06f2eae0cbfcd4acb126d192f", [] ], + "inline-child-with-overflow-shadow-ref.html": [ + "69ed62da57db63215db71f234e80f6b369ca0614", + [] + ], "inline-element-size-ref.html": [ "ea791930e9bdf51a25125062b7da7cedafea1b95", [] @@ -435400,6 +436920,10 @@ ] } }, + "nested-elements-in-overflow-ref.html": [ + "a05172fa40eb5171a773bcfb25709bddc2e4939b", + [] + ], "new-and-old-sizes-match-ref.html": [ "79e89801391530b6fb074545a92db68493667f05", [] @@ -435588,6 +437112,10 @@ "2927b468d08d452afc6a66267bf9786a6b00498e", [] ], + "outer-padding-inner-background-ref.html": [ + "7c7ee533f5c6d94a6b855ecb304371daadb2403d", + [] + ], "paint-holding-in-iframe-ref.html": [ "23852cf6a7cae7868ee19a52315be1f20c47ac84", [] @@ -441391,7 +442919,7 @@ [] ], "iframe.html": [ - "6f3c072f29f9681042e55f044badf138304108c6", + "3ec761e08a6266ab24fcea357d866f76d8c9ed2f", [] ] }, @@ -442603,11 +444131,11 @@ [] ], "inserthtml.js": [ - "bdfc1d34020bd9094fa5da591607c4c6a884d336", + "412fa63ef3144aca159e3848ea85e8b35887aa2d", [] ], "insertimage.js": [ - "b62331e152098ed6d63e294119cfe7abeddb174d", + "f92a570919189e30717b86f39c0a5ad1de006671", [] ], "insertlinebreak.js": [ @@ -442623,7 +444151,7 @@ [] ], "inserttext.js": [ - "8fa8127f2df30800abb2097096a60b4e5ad35326", + "568b467f153c486b3792ca16947920b14d0a0859", [] ], "insertunorderedlist.js": [ @@ -451302,6 +452830,102 @@ "0ae6b502a9b2ce79b26dcf1059ea66382a1c11cc", [] ], + "2d.composite.grid.filter.no_shadow.drawImage-expected.html": [ + "eea78248a836f217a93d176c60b45ca202ea43ed", + [] + ], + "2d.composite.grid.filter.no_shadow.drawImage.png": [ + "2318c1ec94e401b19677b4c4b5e7badff8cea77e", + [] + ], + "2d.composite.grid.filter.no_shadow.fillRect-expected.html": [ + "08ed3566fd11df66e8d9e6ec4c84150be8e683bc", + [] + ], + "2d.composite.grid.filter.no_shadow.fillRect.png": [ + "2318c1ec94e401b19677b4c4b5e7badff8cea77e", + [] + ], + "2d.composite.grid.filter.no_shadow.pattern-expected.html": [ + "22c84f42e89b91df473f435c3c10b3399215eb72", + [] + ], + "2d.composite.grid.filter.no_shadow.pattern.png": [ + "2318c1ec94e401b19677b4c4b5e7badff8cea77e", + [] + ], + "2d.composite.grid.filter.shadow.drawImage-expected.html": [ + "2072348f904966cd1630efc1243aadddfbfe11e9", + [] + ], + "2d.composite.grid.filter.shadow.drawImage.png": [ + "fde787731168e3a2565ca15d6da5e160a03ef484", + [] + ], + "2d.composite.grid.filter.shadow.fillRect-expected.html": [ + "1e119bcbde5a2996567214e864ad33d00cc0d877", + [] + ], + "2d.composite.grid.filter.shadow.fillRect.png": [ + "fde787731168e3a2565ca15d6da5e160a03ef484", + [] + ], + "2d.composite.grid.filter.shadow.pattern-expected.html": [ + "f45fe82c302917293852ced72f3dd53628f398c2", + [] + ], + "2d.composite.grid.filter.shadow.pattern.png": [ + "fde787731168e3a2565ca15d6da5e160a03ef484", + [] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage-expected.html": [ + "923d8360a9d73c9c336e8c460090b0e197e33a12", + [] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage.png": [ + "ce392a1dcccc5e06a3d163dff873a5647ecdb65c", + [] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect-expected.html": [ + "c809e56cac391699d5f4bd284424164833d09419", + [] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect.png": [ + "ce392a1dcccc5e06a3d163dff873a5647ecdb65c", + [] + ], + "2d.composite.grid.no_filter.no_shadow.pattern-expected.html": [ + "f052442a637ed64db37ad12ea7f799f667ff9cd8", + [] + ], + "2d.composite.grid.no_filter.no_shadow.pattern.png": [ + "ce392a1dcccc5e06a3d163dff873a5647ecdb65c", + [] + ], + "2d.composite.grid.no_filter.shadow.drawImage-expected.html": [ + "ad07c35d3101c61b1e1ac4df2ec05348af251439", + [] + ], + "2d.composite.grid.no_filter.shadow.drawImage.png": [ + "aca03a61b220c1022c65b71dbd092f7b6de3c754", + [] + ], + "2d.composite.grid.no_filter.shadow.fillRect-expected.html": [ + "e16a5fcf4582efd0e691da4057f501e4be3702d3", + [] + ], + "2d.composite.grid.no_filter.shadow.fillRect.png": [ + "aca03a61b220c1022c65b71dbd092f7b6de3c754", + [] + ], + "2d.composite.grid.no_filter.shadow.pattern-expected.html": [ + "01e1d4d7b264624b94066ddd3b9e0f696b8c8517", + [] + ], + "2d.composite.grid.no_filter.shadow.pattern.png": [ + "aca03a61b220c1022c65b71dbd092f7b6de3c754", + [] + ], "2d.composite.image.clear.png": [ "eeedd0ff05889ffd4468bf19a2e8e9e0a094201c", [] @@ -452931,19 +454555,19 @@ }, "text": { "2d.text.draw.fill.basic.png": [ - "8021427a07dc4ed754e2b3b1357aca7029bb0fe3", + "70d7b046cb226cfcb2bfeebe3477d3b580d8270a", [] ], "2d.text.draw.fill.maxWidth.large.png": [ - "8021427a07dc4ed754e2b3b1357aca7029bb0fe3", + "70d7b046cb226cfcb2bfeebe3477d3b580d8270a", [] ], "2d.text.draw.fill.rtl.png": [ - "8021427a07dc4ed754e2b3b1357aca7029bb0fe3", + "70d7b046cb226cfcb2bfeebe3477d3b580d8270a", [] ], "2d.text.draw.stroke.basic.png": [ - "d4f6dc1ee883e0a25a17149bc04154be3e7b5738", + "fb3b5b830d345d2aa858e41673e08f99977baf08", [] ], "2d.text.drawing.style.reset.fontKerning.none2-expected.html": [ @@ -452974,6 +454598,18 @@ "ad55a2083a740c2eb188da37fbf8dbee60386ff0", [] ], + "2d.text.measure.text-clusters-rendering-align.tentative-expected.html": [ + "967ae7e46365ff181f4323b39f9ff13bb62a34c7", + [] + ], + "2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html": [ + "2dffe90aadc57ae07067fa7decab24fd43fc8728", + [] + ], + "2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html": [ + "9a9443962dfb988da61453159d02d953e620be6c", + [] + ], "2d.text.writingmode-expected.html": [ "81259c11b7d9226fe659fc437f69b222093079fd", [] @@ -453003,6 +454639,104 @@ "b1f003a745f43bce7e24744902c9668a65fa5338", [] ], + "compositing": { + "2d.composite.grid.filter.no_shadow.drawImage-expected.html": [ + "eea78248a836f217a93d176c60b45ca202ea43ed", + [] + ], + "2d.composite.grid.filter.no_shadow.drawImage.png": [ + "2318c1ec94e401b19677b4c4b5e7badff8cea77e", + [] + ], + "2d.composite.grid.filter.no_shadow.fillRect-expected.html": [ + "08ed3566fd11df66e8d9e6ec4c84150be8e683bc", + [] + ], + "2d.composite.grid.filter.no_shadow.fillRect.png": [ + "2318c1ec94e401b19677b4c4b5e7badff8cea77e", + [] + ], + "2d.composite.grid.filter.no_shadow.pattern-expected.html": [ + "22c84f42e89b91df473f435c3c10b3399215eb72", + [] + ], + "2d.composite.grid.filter.no_shadow.pattern.png": [ + "2318c1ec94e401b19677b4c4b5e7badff8cea77e", + [] + ], + "2d.composite.grid.filter.shadow.drawImage-expected.html": [ + "2072348f904966cd1630efc1243aadddfbfe11e9", + [] + ], + "2d.composite.grid.filter.shadow.drawImage.png": [ + "fde787731168e3a2565ca15d6da5e160a03ef484", + [] + ], + "2d.composite.grid.filter.shadow.fillRect-expected.html": [ + "1e119bcbde5a2996567214e864ad33d00cc0d877", + [] + ], + "2d.composite.grid.filter.shadow.fillRect.png": [ + "fde787731168e3a2565ca15d6da5e160a03ef484", + [] + ], + "2d.composite.grid.filter.shadow.pattern-expected.html": [ + "f45fe82c302917293852ced72f3dd53628f398c2", + [] + ], + "2d.composite.grid.filter.shadow.pattern.png": [ + "fde787731168e3a2565ca15d6da5e160a03ef484", + [] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage-expected.html": [ + "923d8360a9d73c9c336e8c460090b0e197e33a12", + [] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage.png": [ + "ce392a1dcccc5e06a3d163dff873a5647ecdb65c", + [] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect-expected.html": [ + "c809e56cac391699d5f4bd284424164833d09419", + [] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect.png": [ + "ce392a1dcccc5e06a3d163dff873a5647ecdb65c", + [] + ], + "2d.composite.grid.no_filter.no_shadow.pattern-expected.html": [ + "f052442a637ed64db37ad12ea7f799f667ff9cd8", + [] + ], + "2d.composite.grid.no_filter.no_shadow.pattern.png": [ + "ce392a1dcccc5e06a3d163dff873a5647ecdb65c", + [] + ], + "2d.composite.grid.no_filter.shadow.drawImage-expected.html": [ + "ad07c35d3101c61b1e1ac4df2ec05348af251439", + [] + ], + "2d.composite.grid.no_filter.shadow.drawImage.png": [ + "aca03a61b220c1022c65b71dbd092f7b6de3c754", + [] + ], + "2d.composite.grid.no_filter.shadow.fillRect-expected.html": [ + "e16a5fcf4582efd0e691da4057f501e4be3702d3", + [] + ], + "2d.composite.grid.no_filter.shadow.fillRect.png": [ + "aca03a61b220c1022c65b71dbd092f7b6de3c754", + [] + ], + "2d.composite.grid.no_filter.shadow.pattern-expected.html": [ + "01e1d4d7b264624b94066ddd3b9e0f696b8c8517", + [] + ], + "2d.composite.grid.no_filter.shadow.pattern.png": [ + "aca03a61b220c1022c65b71dbd092f7b6de3c754", + [] + ] + }, "fill-and-stroke-styles": { "2d.gradient.interpolate.alpha.png": [ "af5ac0f07d64e7598e0ea6a8e37cff2a5c4ea2a0", @@ -453441,19 +455175,19 @@ }, "text": { "2d.text.draw.fill.basic.png": [ - "8021427a07dc4ed754e2b3b1357aca7029bb0fe3", + "70d7b046cb226cfcb2bfeebe3477d3b580d8270a", [] ], "2d.text.draw.fill.maxWidth.large.png": [ - "8021427a07dc4ed754e2b3b1357aca7029bb0fe3", + "70d7b046cb226cfcb2bfeebe3477d3b580d8270a", [] ], "2d.text.draw.fill.rtl.png": [ - "8021427a07dc4ed754e2b3b1357aca7029bb0fe3", + "70d7b046cb226cfcb2bfeebe3477d3b580d8270a", [] ], "2d.text.draw.stroke.basic.png": [ - "d4f6dc1ee883e0a25a17149bc04154be3e7b5738", + "fb3b5b830d345d2aa858e41673e08f99977baf08", [] ], "2d.text.drawing.style.reset.fontKerning.none2-expected.html": [ @@ -453488,6 +455222,18 @@ "ad55a2083a740c2eb188da37fbf8dbee60386ff0", [] ], + "2d.text.measure.text-clusters-rendering-align.tentative-expected.html": [ + "967ae7e46365ff181f4323b39f9ff13bb62a34c7", + [] + ], + "2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html": [ + "2dffe90aadc57ae07067fa7decab24fd43fc8728", + [] + ], + "2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html": [ + "9a9443962dfb988da61453159d02d953e620be6c", + [] + ], "WEB_FEATURES.yml": [ "1d9e4bab82191d72c374c7399e666bd6bfe42bc2", [] @@ -453558,7 +455304,7 @@ [] ], "gentestutilsunion.py": [ - "2ec2e20886b5bb16c6443daf98e502c408f55c0c", + "629b596b51347f196407a11113cbdc3178eda167", [] ], "name2dir-canvas.yaml": [ @@ -453590,6 +455336,14 @@ "9147899efc0b08fa7a293a26d2f667a58b7ec4dc", [] ], + "reftest_img.html": [ + "c058406d49a9e7a1a19a68b43fff84a9dffacdf0", + [] + ], + "reftest_img_grid.html": [ + "20026c3e82c1e9c358f01b690bce9425501c189e", + [] + ], "reftest_offscreen.html": [ "9e29bd0a9da8bf3a3c6b3ef383ec7da4ae87095b", [] @@ -453655,7 +455409,7 @@ [] ], "compositing.yaml": [ - "6bd0aaad8a51bb6d5eb90163886f8439f041a0b0", + "1db0c590db2bce8d1e3429e92ec1f7880cbb3cb9", [] ], "conformance_requirements.yaml": [ @@ -453703,7 +455457,7 @@ [] ], "text.yaml": [ - "4c2ae798596ee9d1a20fd8220b29992b5c72bd05", + "78312640c08938cf81e38ca0671b82280093e43b", [] ], "the-canvas-state.yaml": [ @@ -459232,6 +460986,10 @@ [] ] }, + "table-align-float-ref.xhtml": [ + "fc6b78605755f9096b51eaa4c6908176d212c720", + [] + ], "table-background-print-ref.html": [ "3aa0abd3207469be60d54475e92b4f882f69dcdc", [] @@ -467788,7 +469546,7 @@ [] ], "turtledove.idl": [ - "ff48d311914e49e9de8a96f7ac3a26da144da818", + "0309f5047b36491be282892acb661bfda6562ae5", [] ], "ua-client-hints.idl": [ @@ -471329,6 +473087,14 @@ ] } }, + "state": { + "resources": { + "helpers.js": [ + "658d267351bd568399d81cd720b6b0b9f0fbcbb5", + [] + ] + } + }, "updateCurrentEntry-method": { "resources": { "opaque-origin-page.html": [ @@ -472407,7 +474173,7 @@ [] ], "digital-credentials-get.html": [ - "489e42913592ae72641b6f4d55eb6d308b8e79ca", + "543417f230a59b3d09705b20775a38cbabaf7a22", [] ], "nested-sandbox.html": [ @@ -476140,6 +477906,10 @@ [] ], "support": { + "html5lib-testcase-support.js": [ + "4f15e46a7eb0498658417639aa8f61e3cc46d0c6", + [] + ], "testcases.sub.js": [ "7ce755ca060b951db57d41fdf0eccf4cf70eaa22", [] @@ -479819,7 +481589,7 @@ [] ], "simple-module.js": [ - "11b650811dcc9cea02d541a72314ea84a335f3fb", + "eeb0ce95b040687a57a7eaa65be7c17a88b592fe", [] ], "simple-module.js.headers": [ @@ -480368,7 +482138,7 @@ [] ], "csp-script-src-self.html": [ - "8dc382068a347990c91aeaafc8b509553cac8767", + "61a8f31396c89b3c29dfd593f961cb0b7c8b2e1e", [] ], "csp-script-src-strict-dynamic.html": [ @@ -481643,6 +483413,10 @@ "610a3ddb2d21da119fb4a53f5f351dff0190880c", [] ], + "small-nested-viewbox-ref.html": [ + "f737b09ff49ad1cbe252c7f7da707e37fb382c9d", + [] + ], "support": { "resources.svg": [ "85b6833a6601a45d1847320efb7259080cba5359", @@ -482353,11 +484127,11 @@ [] ], "cacert.key": [ - "421cae4c51a6dae556ad586f54af40ab439346bc", + "dd47af3f939c7dd3479810a82670c4c3f3cd212e", [] ], "cacert.pem": [ - "cf16ae8aea3022ba7312a753e1d989ed0e2286b1", + "7b3fb3da14d0d228bfc83a58affd11b535ab0b69", [] ], "config.json": [ @@ -482365,11 +484139,11 @@ [] ], "web-platform.test.key": [ - "0df3f579240d2c80e84804ebcc3a6812ef4a02d5", + "4f68bb3caa0ddaef5799966bb88477273bbdcc0d", [] ], "web-platform.test.pem": [ - "1c5859d2066ad96bfaea9231e2ccbae48c13dcb7", + "02a2d94e935ab6c760b282665d3ec409d51a739e", [] ] }, @@ -482493,7 +484267,7 @@ [] ], "jobs.py": [ - "fe8eaae069eb3c548cf22af0fa5e7e65063a1b2a", + "a831d24bebec2cdaf05635a7f3f3250a7078bcd0", [] ], "macos_color_profile.py": [ @@ -493815,7 +495589,7 @@ [] ], "chrome_spki_certs.py": [ - "08ff16145cc4564696262672a58ae07b307903f5", + "875ae3ea4a7ea7e1241023e9b31b097c1d44e2c4", [] ], "chromium.py": [ @@ -493911,11 +495685,11 @@ [] ], "executorchrome.py": [ - "53c11f133e5e0197b86435a62b18442315cbbcc0", + "914c5d1c0e3c1acce82a7337e5c35fb4457959d0", [] ], "executoredge.py": [ - "75a3313c55c3dff4f63104953204b6095949703d", + "95b40bd8db14f6d59c1bdd2eed10f857b613dcc9", [] ], "executormarionette.py": [ @@ -493935,7 +495709,7 @@ [] ], "executorwebdriver.py": [ - "3c1bdfd7a726e7359a9050ad840240c61a980fdf", + "f04d615ee11be079504209bc6c68fdacb1c71370", [] ], "executorwktr.py": [ @@ -493947,7 +495721,7 @@ [] ], "protocol.py": [ - "75edc14676784a1cbaad702d4499077c026588c0", + "5b59482d9bd6e6960de8e8345247684c177f5a63", [] ], "pytestrunner": { @@ -494805,7 +496579,7 @@ [] ], "navigation-report-only-support.html": [ - "a16995ba903688327d5b58dc9d7c5457583ec758", + "791559f7a19bec50648245c15c1e92723034d5b9", [] ], "navigation-report-only-support.html.headers": [ @@ -494813,13 +496587,17 @@ [] ], "navigation-support.html": [ - "c2c8a82f5145885f64e5ce99a9e8c6f039efa370", + "47f33c9fb6430cb0ded9f09facd8a3974901d1f5", [] ], "navigation-support.html.headers": [ "604e765da46d85fe8ab85d3097fe7c2cbe00a930", [] ], + "navigation-support.js": [ + "41dce761def94a328ac75f05699a6f079e0d0bee", + [] + ], "resolve-spv.js": [ "89e58b2a8b75e0200d145b028d032caa688f32cd", [] @@ -495513,7 +497291,7 @@ [] ], "urltestdata.json": [ - "9dbe5456a96950085aa4ee11fe757b90350b6bad", + "0ebaf4cd4c42e785bcfafd4a49faec318c8fee4a", [] ] }, @@ -495782,20 +497560,30 @@ [] ] }, + "jspi": { + "README.txt": [ + "c65b9893c6fd30b535009390b86d275e33085643", + [] + ], + "testharness-additions.js": [ + "e146c52f96dfbace060f135bdc047bf787a990b8", + [] + ] + }, "memory": { "assertions.js": [ - "b539513adcab7d84e67d65fcf97453e9bc22de43", + "1430c523882307d025c81788ac90322de5a9d66b", [] ] }, "table": { "assertions.js": [ - "19cc5c3b92d6fa6748c3831f3629c92b62ed757f", + "4fcd3517a6a869545ab62ba7a757c6e432823ca4", [] ] }, "wasm-module-builder.js": [ - "90ccc954a5dba362f9ea2c57560bbe8d64002800", + "7fa196c58c17fd5e2bafe336b0182b754de09d6c", [] ] }, @@ -497793,7 +499581,7 @@ }, "network": { "__init__.py": [ - "0c3338362d309f859fb660b043ed2c081e0db4dc", + "5decb28a1a97fb91ad832c1c0ef05cecd1fc2643", [] ], "add_intercept": { @@ -498887,7 +500675,7 @@ ], "resources": { "utils.js": [ - "460fe46115476b073c5e650e119a6f6dd263b9ee", + "973c16baca760264cd71dc8b28288a8b01a68d51", [] ], "utils_validation.js": [ @@ -505454,11 +507242,83 @@ } ] ], - "cursor-overloads.htm": [ - "7beeaa2bb39cdedb01eb8b8d7a414c6a4b37e067", + "cursor-overloads.any.js": [ + "dd80d2f40382407ac468028c5aa294374f4b561b", [ - null, - {} + "IndexedDB/cursor-overloads.any.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/cursor-overloads.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/cursor-overloads.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/cursor-overloads.any.worker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } ] ], "database-names-by-origin.html": [ @@ -505503,18 +507363,162 @@ } ] ], - "delete-request-queue.html": [ - "d8dfbf9a6061dd89244841e9edc42426b5f3e9bb", + "delete-request-queue.any.js": [ + "6b2034c7f6b65380d5e15398676598759d084b5a", [ - null, - {} + "IndexedDB/delete-request-queue.any.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/delete-request-queue.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/delete-request-queue.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/delete-request-queue.any.worker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } ] ], - "error-attributes.html": [ - "d65bf21790a16a81eae57f1f3fb1c85235e3890a", + "error-attributes.any.js": [ + "9b5003040b273b14a086025425a4a0af06e73274", [ - null, - {} + "IndexedDB/error-attributes.any.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/error-attributes.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/error-attributes.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } + ], + [ + "IndexedDB/error-attributes.any.worker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ] + ] + } ] ], "event-dispatch-active-flag.html": [ @@ -510677,32 +512681,384 @@ {} ] ], - "upgrade-transaction-deactivation-timing.html": [ - "8119c9ab261ee632b3ee4f9c08a4ce25ea626adc", + "upgrade-transaction-deactivation-timing.any.js": [ + "d11f821201cb9d2ca4d7b1f8e69dc3ac61293445", [ - null, - {} + "IndexedDB/upgrade-transaction-deactivation-timing.any.html", + { + "script_metadata": [ + [ + "title", + "Upgrade transaction deactivation timing" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-deactivation-timing.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "Upgrade transaction deactivation timing" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-deactivation-timing.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "Upgrade transaction deactivation timing" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-deactivation-timing.any.worker.html", + { + "script_metadata": [ + [ + "title", + "Upgrade transaction deactivation timing" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } ] ], - "upgrade-transaction-lifecycle-backend-aborted.html": [ - "862e85144d64a12eda04e0b48c6954ff996486a0", + "upgrade-transaction-lifecycle-backend-aborted.any.js": [ + "841a83c6e0d1c214e6c63573657fe4011ae16aa6", [ - null, - {} + "IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: backend-aborted versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: backend-aborted versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: backend-aborted versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.worker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: backend-aborted versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } ] ], - "upgrade-transaction-lifecycle-committed.html": [ - "347d940aeefae01f9a41c8c460ae29135ccee4d0", + "upgrade-transaction-lifecycle-committed.any.js": [ + "85b447ea95131dad441ddd44cc66eec77ed7c156", [ - null, - {} + "IndexedDB/upgrade-transaction-lifecycle-committed.any.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: committed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-committed.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: committed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-committed.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: committed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-committed.any.worker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: committed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } ] ], - "upgrade-transaction-lifecycle-user-aborted.html": [ - "4094ce34f34aa06d8ce4433b963819cf4f39f6b6", + "upgrade-transaction-lifecycle-user-aborted.any.js": [ + "4346e1a675dfa8ff1a8dea3f7f141a1971f92f8e", [ - null, - {} + "IndexedDB/upgrade-transaction-lifecycle-user-aborted.any.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: user-abort()ed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-user-aborted.any.serviceworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: user-abort()ed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-user-aborted.any.sharedworker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: user-abort()ed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } + ], + [ + "IndexedDB/upgrade-transaction-lifecycle-user-aborted.any.worker.html", + { + "script_metadata": [ + [ + "title", + "IndexedDB: user-abort()ed versionchange transaction lifecycle" + ], + [ + "global", + "window,worker" + ], + [ + "script", + "resources/support.js" + ], + [ + "script", + "resources/support-promises.js" + ] + ] + } ] ], "value.any.js": [ @@ -519832,7 +522188,7 @@ ] }, "aggregatable-report-no-contributions.sub.https.html": [ - "b42a61b7bd50a2934b0b7f479618d466047146bc", + "b84f1905626fcfd2b3344abc3518c22aca9186b9", [ null, { @@ -519982,7 +522338,7 @@ ] ], "simple-verbose-debug-report.sub.https.html": [ - "8a477f732f494a84e5802ace639d8cbec4e2a6c9", + "cc2e37cae8eb826b1182c40d7fa2ad81e789c12f", [ null, { @@ -528636,7 +530992,7 @@ ] ], "async-navigator-clipboard-basics.https.html": [ - "5d6f701bdb751641343feda37cea44f31ecaf338", + "f7aed80b17ebd0af8f4c255ef83dfc85a7eb71ce", [ null, { @@ -529393,6 +531749,24 @@ } ] ], + "y-dialog-disconnected.html": [ + "0bd41b5bb2461c6add5c10def3507800547f15e0", + [ + null, + { + "testdriver": true + } + ] + ], + "y-popover-disconnected.html": [ + "22fbdbfe73b04a8cdd32dd96c505ce2bfddb5844", + [ + null, + { + "testdriver": true + } + ] + ], "y.html": [ "78c432de3888eed80fcaf1cdd3d3c03e1a2b3257", [ @@ -542108,7 +544482,7 @@ ] ], "justify-self-block-in-inline.html": [ - "3a326016bc15914958600156c3a72b5bb77e41b8", + "0a3facf3ef7768797031796a93cdbb2424b23c99", [ null, {} @@ -543579,7 +545953,7 @@ ] ], "anchor-scope-basic.html": [ - "147aef8c764863ae2bc305aa92a8e71ef0852be8", + "47cb3b8d86a106f37af3e32149b79fbd9c8c2056", [ null, {} @@ -544381,7 +546755,7 @@ ] ], "try-tactic-wm.html": [ - "8dcf98f893979c0511d3bbf6675df16b331a62c9", + "69d9c2dff8889e3f6e619ede92f9623296a5e506", [ null, {} @@ -547904,7 +550278,7 @@ ] ], "color-computed-relative-color.html": [ - "8407e527017ec0440e90d5cbacfc5bcc0569907d", + "23ee07d177ac525c2ce2b4e60cd1861a33cc23c5", [ null, {} @@ -548051,7 +550425,7 @@ ] ], "color-valid-relative-color.html": [ - "2c4dc0f8e60bf0df1668f9f840b379fda18bd786", + "142f96bcf9b562e399b9b47b5cf1babadcb2ad72", [ null, {} @@ -548274,20 +550648,6 @@ {} ] ], - "at-container-overflowing-parsing.html": [ - "5c15a825853f7e545d43fe6f2c73cb0cc4bc45b4", - [ - null, - {} - ] - ], - "at-container-overflowing-serialization.html": [ - "f55cfeb63433cda37e1dd3393fc990107679b522", - [ - null, - {} - ] - ], "at-container-parsing.html": [ "5c9d8c1bb9ea63a34016ca1a4b9931186a9c2209", [ @@ -548302,34 +550662,6 @@ {} ] ], - "at-container-snapped-parsing.html": [ - "0a8fe50bc38e7bb297cb2f0e9092680918599472", - [ - null, - {} - ] - ], - "at-container-snapped-serialization.html": [ - "59cc3d37f4f3fb9293568d5f82c5a060dc3fd456", - [ - null, - {} - ] - ], - "at-container-stuck-parsing.html": [ - "a3a1f01458d1ce321b21089ba3f65ffa12ee34d4", - [ - null, - {} - ] - ], - "at-container-stuck-serialization.html": [ - "d5abede45c25be5b6c191482dee9936785d48068", - [ - null, - {} - ] - ], "at-container-style-parsing.html": [ "c63cc76560b4680d5a33863bda747c9fdde9cada", [ @@ -548338,7 +550670,7 @@ ] ], "at-container-style-serialization.html": [ - "a30acef9ac21acadf3bddd7099709ffa032a43dc", + "bd9d23a4b705de1e842018e94c76b6431412b0cb", [ null, {} @@ -548554,27 +550886,6 @@ {} ] ], - "container-type-scroll-state-computed.html": [ - "4e80712beab2dc63f7d22bbe0973a5d8e84a56cf", - [ - null, - {} - ] - ], - "container-type-scroll-state-containment.html": [ - "cc1af5a08ebb1454ef3ea8ae64fd27de4cbe446c", - [ - null, - {} - ] - ], - "container-type-scroll-state-parsing.html": [ - "7f3779bc39d1850d423434fbe94f71e8dfb133cb", - [ - null, - {} - ] - ], "container-units-animation.html": [ "79e59dc2a186fb3dc207547df9add7d327a357d5", [ @@ -548981,73 +551292,159 @@ {} ] ], - "scroll-state-initially-snapped.html": [ - "64a171c361e7c93f1339887ed224a305c980ef99", - [ - null, - {} - ] - ], - "scroll-state-initially-stuck.html": [ - "c0d59b61e768d77afd44a3ae344718a6e83ef728", - [ - null, - {} - ] - ], - "scroll-state-snapped-change.html": [ - "6e9843b8b755b163acaa6f8137a86566803044e9", - [ - null, - {} - ] - ], - "scroll-state-snapped-container-type-change.html": [ - "556e4c2445b3f313f9bb83ff6beba015d780a260", - [ - null, - {} - ] - ], - "scroll-state-snapped-none.html": [ - "8c7aae56bebf34adb9214a36b3779ff45d085dcd", - [ - null, - {} - ] - ], - "scroll-state-snapped-snap-changing.html": [ - "161c2e1368dd2ba88442c367cd1f1a06ac9b8b3f", - [ - null, - { - "testdriver": true - } - ] - ], - "scroll-state-snapped-wm.html": [ - "b6703e81142a3e22726ccd826aaab873b09b43a4", - [ - null, - {} + "scroll-state": { + "at-container-overflowing-parsing.html": [ + "5c15a825853f7e545d43fe6f2c73cb0cc4bc45b4", + [ + null, + {} + ] + ], + "at-container-overflowing-serialization.html": [ + "f55cfeb63433cda37e1dd3393fc990107679b522", + [ + null, + {} + ] + ], + "at-container-snapped-parsing.html": [ + "0a8fe50bc38e7bb297cb2f0e9092680918599472", + [ + null, + {} + ] + ], + "at-container-snapped-serialization.html": [ + "59cc3d37f4f3fb9293568d5f82c5a060dc3fd456", + [ + null, + {} + ] + ], + "at-container-stuck-parsing.html": [ + "a3a1f01458d1ce321b21089ba3f65ffa12ee34d4", + [ + null, + {} + ] + ], + "at-container-stuck-serialization.html": [ + "d5abede45c25be5b6c191482dee9936785d48068", + [ + null, + {} + ] + ], + "container-type-scroll-state-computed.html": [ + "4e80712beab2dc63f7d22bbe0973a5d8e84a56cf", + [ + null, + {} + ] + ], + "container-type-scroll-state-containment.html": [ + "cc1af5a08ebb1454ef3ea8ae64fd27de4cbe446c", + [ + null, + {} + ] + ], + "container-type-scroll-state-parsing.html": [ + "7f3779bc39d1850d423434fbe94f71e8dfb133cb", + [ + null, + {} + ] + ], + "scroll-state-initially-snapped.html": [ + "64a171c361e7c93f1339887ed224a305c980ef99", + [ + null, + {} + ] + ], + "scroll-state-initially-stuck.html": [ + "c0d59b61e768d77afd44a3ae344718a6e83ef728", + [ + null, + {} + ] + ], + "scroll-state-snapped-change.html": [ + "6e9843b8b755b163acaa6f8137a86566803044e9", + [ + null, + {} + ] + ], + "scroll-state-snapped-container-type-change.html": [ + "4eb5de2679ef423ca3269d8e557d85ca609b20d4", + [ + null, + {} + ] + ], + "scroll-state-snapped-none.html": [ + "8c7aae56bebf34adb9214a36b3779ff45d085dcd", + [ + null, + {} + ] + ], + "scroll-state-snapped-snap-changing.html": [ + "161c2e1368dd2ba88442c367cd1f1a06ac9b8b3f", + [ + null, + { + "testdriver": true + } + ] + ], + "scroll-state-snapped-wm.html": [ + "b6703e81142a3e22726ccd826aaab873b09b43a4", + [ + null, + {} + ] + ], + "scroll-state-stuck-container-type-change.html": [ + "9c6df64832288706b6748dfdf2db9b3a907eab8c", + [ + null, + {} + ] + ], + "scroll-state-stuck-writing-direction.html": [ + "eb0c1c4a84ec54a1c167455c50f793711bdcffea", + [ + null, + {} + ] + ], + "scroll-state-target-query-change.html": [ + "33459f470b9920e81092a93bc82a72ef01c195b5", + [ + null, + {} + ] ] - ], - "scroll-state-target-query-change.html": [ - "33459f470b9920e81092a93bc82a72ef01c195b5", + }, + "sibling-layout-dependency.html": [ + "eb3df2ba410d34b62686351fc6834287fbd73baa", [ null, {} ] ], - "sibling-layout-dependency.html": [ - "eb3df2ba410d34b62686351fc6834287fbd73baa", + "size-container-no-principal-box.html": [ + "730bb1d7361ae449d7c129a318d89cd6f9c6adb4", [ null, {} ] ], - "size-container-no-principal-box.html": [ - "730bb1d7361ae449d7c129a318d89cd6f9c6adb4", + "size-container-writing-mode-change.html": [ + "dd709388b7ddffb951f52b2c84d9bbb4e8b93bac", [ null, {} @@ -562833,6 +565230,13 @@ {} ] ], + "the-check-pseudo-element.tentative.html": [ + "70f35091bc9484ae6e6802e64aa18bab9b0b8610", + [ + null, + {} + ] + ], "tree-abiding-pseudo-elements.html": [ "7839a38049a190135149c0d3d3b35fbc2d29d207", [ @@ -563131,7 +565535,7 @@ ] ], "has-slotted-functional-changing-001.tentative.html": [ - "209a47298e3554f59a0b02ae6f2d53a3aab20498", + "858a8e5abb75902048c3a343df71eed296c3b975", [ null, { @@ -563140,7 +565544,7 @@ ] ], "has-slotted-functional-changing-002.tentative.html": [ - "36fafcb1dcc49b45d6380efdba33955ca294d34b", + "76b726a0a4fcc26bab56cf60803b263c042466c2", [ null, { @@ -563149,7 +565553,7 @@ ] ], "has-slotted-functional-changing-003.tentative.html": [ - "9914e452088066d860fd57edb80ec865fba3bcf8", + "0b1d710d770d300fca10483e9840de2c6aedd398", [ null, { @@ -563158,7 +565562,7 @@ ] ], "has-slotted-functional-changing-004.tentative.html": [ - "669162050aab4ec3f32c778d78b3f9ab7dae7f2b", + "f4fd54f3d487af230764b596298833af29ee3ee1", [ null, { @@ -563768,7 +566172,7 @@ ] ], "start-edge-in-block-layout-direction.html": [ - "043844d05646a0955f21a24f65e7467dd9df632e", + "09b1655f86c2997182b22834148d9467ab3e4d17", [ null, {} @@ -566448,7 +568852,7 @@ ] ], "height-interpolation.html": [ - "75e0977fa1164ae25c0c675523ab00599516712a", + "7539dcb0161cee5e3d254313e231541aad31a63c", [ null, {} @@ -566893,7 +569297,7 @@ ] ], "keyword-sizes-on-inline-block.html": [ - "a66e118c203678bae777c1fbd572a30dde6e0a5f", + "d91d8e6ed9cd2ab7c7f0e418b7715fc88a03b4e1", [ null, {} @@ -567076,6 +569480,29 @@ {} ] ], + "stretch": { + "block-height-1.html": [ + "94960f15b96f9fbb6370e94fbbffb9336373c76c", + [ + null, + {} + ] + ], + "block-height-2.html": [ + "7028adf90543f4da49b5549fd4a62d777e92b180", + [ + null, + {} + ] + ], + "parsing.html": [ + "1f5bd39059ebffe59925dd616ad79e7d0a0f7f78", + [ + null, + {} + ] + ] + }, "svg-intrinsic-size-001.html": [ "c0ba59819b7b2b14e847acc208456a5e48a40397", [ @@ -575940,7 +578367,7 @@ ] ], "calc-serialization-002.html": [ - "28a7de5cdabfa2d84140106284921b4457fd9908", + "a3b99cf87bbe8bbb9b52b4b762abab979707880b", [ null, {} @@ -575956,7 +578383,7 @@ "calc-size": { "animation": { "calc-size-height-interpolation.html": [ - "2126bd8faed1c263c0d3d4132f2c61664bf4fbb3", + "20b7b8ba317489feb23ec5191da3204e843e88fb", [ null, { @@ -575981,7 +578408,7 @@ ] ], "interpolate-size-height-composition.html": [ - "22f62b8edac28fe1a6219926839c87660c3248ad", + "9a3caa747bbef04ae69a09017d0685235e4cc3a6", [ null, {} @@ -576009,7 +578436,7 @@ ] ], "interpolate-size-max-height-composition.html": [ - "e356fb60746d4dae08dcf234dc843ecf07f4a11c", + "958022d4cd0b179da34b2f2e517d85276c4c6bf9", [ null, {} @@ -576023,7 +578450,7 @@ ] ], "interpolate-size-max-width-composition.html": [ - "1e540eaee64a679a7d9d74d39a5b68a88531b6e5", + "852e1eed7935a253aef25a001e0036b2457c64bc", [ null, {} @@ -576037,7 +578464,7 @@ ] ], "interpolate-size-min-height-composition.html": [ - "520ec75aaf8e4efa5bac81645913ee66dc034314", + "0c3b4d2c7e39174b29dae0e430f89270272fd5ff", [ null, {} @@ -576051,7 +578478,7 @@ ] ], "interpolate-size-min-width-composition.html": [ - "4f9e91394a556a679b7ae369e1cdb350a1eb0315", + "2472f8055267bfcc6384cd94fc27b33252c79156", [ null, {} @@ -576072,7 +578499,7 @@ ] ], "interpolate-size-width-composition.html": [ - "a84e0bec3d517a382067c98f3d234d6ecb078fcc", + "529eac2f7ff23452010c054e3660aa9fc5224983", [ null, {} @@ -576480,7 +578907,7 @@ ] ], "minmax-length-percent-serialize.html": [ - "0a109d7c18ecfb30855cf6b147ea9b423385ac99", + "5d11b85046741b6665775cb5549e87c00d1fd477", [ null, {} @@ -576627,7 +579054,7 @@ ] ], "round-function.html": [ - "338ecaed9044d9dc270557bc15c97b4531b74ace", + "fd35567a575b3dfee00fa2ff60cb9ebec163485e", [ null, {} @@ -577229,6 +579656,31 @@ } ] ], + "layered-capture": { + "opacity-computed-style.tentative.html": [ + "f370b7b03d268f9abdaa0e3782e2ef41d4a17f00", + [ + null, + {} + ] + ], + "parsing": { + "view-transition-capture-mode-invalid.tentative.html": [ + "6bcd77cdae03e0399a039c846caa273b7f054a0c", + [ + null, + {} + ] + ], + "view-transition-capture-mode-valid.tentative.html": [ + "2b739fcfe289127f6d88b9235d84417a0746d3a3", + [ + null, + {} + ] + ] + } + }, "mix-blend-mode-only-on-transition.html": [ "4149142cf326e0de0deed808e99561ca89d9870a", [ @@ -577482,15 +579934,6 @@ ] ] }, - "nested": { - "opacity-computed-style.tentative.html": [ - "f370b7b03d268f9abdaa0e3782e2ef41d4a17f00", - [ - null, - {} - ] - ] - }, "no-crash-set-exception.html": [ "bc0d764a590aaed95d2e6afe487f2477385a9c94", [ @@ -583650,7 +586093,7 @@ ] ], "CustomElementRegistry.html": [ - "5b75fc651fcf74685e7f6cd6e753c9cbfd44de48", + "87da806bcab72e02c6c54bee8c1d0e5781700c1c", [ null, {} @@ -584931,10 +587374,12 @@ }, "digital-credentials": { "allow-attribute.https.html": [ - "412236268086d805fb74346c2411db91dcfdc459", + "d988e94cd23547803873616432359ebd572e1242", [ null, - {} + { + "testdriver": true + } ] ], "create.tentative.https.html": [ @@ -588963,6 +591408,13 @@ {} ] ], + "custom-element-move-reactions.html": [ + "ce0302cd7342d1222746645331f79a57099c0bec", + [ + null, + {} + ] + ], "focus-preserve.html": [ "a00e8b77880697a51d4418fc15637b1dcef6914b", [ @@ -590426,6 +592878,37 @@ } ] ], + "delete-before-invisible-line-break.html": [ + "ec88079d31e7f9fe819ee0e8f00156872cc5ea05", + [ + "editing/other/delete-before-invisible-line-break.html?white-space=normal", + { + "testdriver": true, + "timeout": "long" + } + ], + [ + "editing/other/delete-before-invisible-line-break.html?white-space=pre", + { + "testdriver": true, + "timeout": "long" + } + ], + [ + "editing/other/delete-before-invisible-line-break.html?white-space=pre-line", + { + "testdriver": true, + "timeout": "long" + } + ], + [ + "editing/other/delete-before-invisible-line-break.html?white-space=pre-wrap", + { + "testdriver": true, + "timeout": "long" + } + ] + ], "delete-in-child-of-head.tentative.html": [ "978cf83d47add5ef754e588074844d0e624dfa27", [ @@ -590620,6 +593103,24 @@ {} ] ], + "double-click-range-selection-in-floating-list-item.html": [ + "898f42b9b0428a22287d11bb55819b77a6d13df4", + [ + null, + { + "testdriver": true + } + ] + ], + "double-click-range-selection-in-list-item.html": [ + "18dee19966a2d469d78fb1c4140ddf4b8ce52d76", + [ + null, + { + "testdriver": true + } + ] + ], "edit-in-textcontrol-immediately-after-hidden.tentative.html": [ "2cdffd6e2c07b93810e9ff115e2e92bdb4bc27f0", [ @@ -590907,6 +593408,37 @@ } ] ], + "forwarddelete-before-invisible-line-break.html": [ + "aebfdc2899eeda47600ecf6c1b0758dbd67ac064", + [ + "editing/other/forwarddelete-before-invisible-line-break.html?white-space=normal", + { + "testdriver": true, + "timeout": "long" + } + ], + [ + "editing/other/forwarddelete-before-invisible-line-break.html?white-space=pre", + { + "testdriver": true, + "timeout": "long" + } + ], + [ + "editing/other/forwarddelete-before-invisible-line-break.html?white-space=pre-line", + { + "testdriver": true, + "timeout": "long" + } + ], + [ + "editing/other/forwarddelete-before-invisible-line-break.html?white-space=pre-wrap", + { + "testdriver": true, + "timeout": "long" + } + ] + ], "html-text-copy-paste-of-anchor-with-href-in-content-editable.html": [ "5724b59ada4bb34fe416cb0031643e1fd4973667", [ @@ -593938,7 +596470,7 @@ ] ], "insertText.html": [ - "9045e04d368f3fa1b5bfac5f7d22a429d3c9701c", + "664b9befb8d33b81e28971d69345cc2142f21a0b", [ "editing/plaintext-only/insertText.html?white-space=normal", { @@ -609051,6 +611583,24 @@ "testdriver": true } ] + ], + "idlharness.https.window.js": [ + "891d334e9f63128312448764a5c42126eba088d4", + [ + "eyedropper/idlharness.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ] + ] + } + ] ] }, "feature-policy": { @@ -610790,6 +613340,13 @@ {} ] ], + "http-localhost-url.https.html": [ + "a8b16d75c858bdd7ebfa3d782754f0c2e878b11b", + [ + null, + {} + ] + ], "ignore-child-fenced-frame-onload-event.https.html": [ "a542c25909102e7b3ad8daf5837efb59f467f86e", [ @@ -630997,7 +633554,7 @@ ] ], "get-interest-group-auction-data.https.window.js": [ - "3788045c8c21556114f91c432a5d4d4f3e74fd0e", + "453d0f8e64285694e8ff30cba41331d331151970", [ "fledge/tentative/get-interest-group-auction-data.https.window.html?1-4", { @@ -658867,6 +661424,20 @@ {} ] ], + "2d.text.measure.text-clusters-position.tentative.html": [ + "cc6f366e0722600d2a1775df27c1664f68e69191", + [ + null, + {} + ] + ], + "2d.text.measure.text-clusters-range.tentative.html": [ + "effa53c4c954b623d7d28b91cd3bfbe29cb490ef", + [ + null, + {} + ] + ], "2d.text.measure.text-clusters-split.tentative.html": [ "63c7cce72be7c1ede567c2f00001d7a57addadbc", [ @@ -660515,6 +663086,90 @@ {} ] ], + "2d.composite.grid.filter.no_shadow.drawImage.worker.js": [ + "45329fcd9c8b222abe33fff963358e4b8ae728d6", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.html", + {} + ] + ], + "2d.composite.grid.filter.no_shadow.fillRect.worker.js": [ + "dff55436a40b07924332b17725d930f9c3956a4c", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.html", + {} + ] + ], + "2d.composite.grid.filter.no_shadow.pattern.worker.js": [ + "d3e79cd2d156f65378c8e9ddeb4f7ee326a0c2c4", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.html", + {} + ] + ], + "2d.composite.grid.filter.shadow.drawImage.worker.js": [ + "9a9c2f9363225722249284b1ac48709482b1f204", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.html", + {} + ] + ], + "2d.composite.grid.filter.shadow.fillRect.worker.js": [ + "f495009b301eeb9c36286f6fe8dc6edcc835427c", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.html", + {} + ] + ], + "2d.composite.grid.filter.shadow.pattern.worker.js": [ + "d960d0d54014226083b2d86e922048aea84a6db1", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.html", + {} + ] + ], + "2d.composite.grid.no_filter.no_shadow.drawImage.worker.js": [ + "de1686a76e80b558ca3b9b40f86b9ea80a053a1d", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.html", + {} + ] + ], + "2d.composite.grid.no_filter.no_shadow.fillRect.worker.js": [ + "cb60645b70402e4e97a34d78687e12365215613c", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.html", + {} + ] + ], + "2d.composite.grid.no_filter.no_shadow.pattern.worker.js": [ + "e1479261ce22afe939a593343c1dcacc01dc0050", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.html", + {} + ] + ], + "2d.composite.grid.no_filter.shadow.drawImage.worker.js": [ + "c7827238f6936c67f0a1a705008c38d4c75bc310", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.html", + {} + ] + ], + "2d.composite.grid.no_filter.shadow.fillRect.worker.js": [ + "217fe38a8de678c2dc69b21faf5bc8abb6c2fd50", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.html", + {} + ] + ], + "2d.composite.grid.no_filter.shadow.pattern.worker.js": [ + "f26657b521426a8773ef674b1be07c31411adbc8", + [ + "html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.html", + {} + ] + ], "2d.composite.image.clear.html": [ "f001c4409c3e2c2ca59b64de64174cf6251624f6", [ @@ -672563,6 +675218,34 @@ {} ] ], + "2d.text.measure.text-clusters-position.tentative.html": [ + "780a4f52623252e4ecbda532fa18c7d1bf25884c", + [ + null, + {} + ] + ], + "2d.text.measure.text-clusters-position.tentative.worker.js": [ + "90ee50fa50f222975939362de77fdbea7afc468e", + [ + "html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.html", + {} + ] + ], + "2d.text.measure.text-clusters-range.tentative.html": [ + "9bd2a026618c252d32141287f8d9c1d8b93300a9", + [ + null, + {} + ] + ], + "2d.text.measure.text-clusters-range.tentative.worker.js": [ + "db76d19edf362013e64a7609c42e37332e8eda07", + [ + "html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.html", + {} + ] + ], "2d.text.measure.text-clusters-split.tentative.html": [ "6a5fd475795e140ff8b8533b8d070baf97f0ebfe", [ @@ -678426,7 +681109,7 @@ ] ], "nameditem-names.html": [ - "3f76d85a1bca783df916b159409a94c30488a2dd", + "111738a1444652b9e7e1eed61bb55f2615445923", [ null, {} @@ -678924,6 +681607,13 @@ {} ] ], + "innertext-whitespace-pre-line.html": [ + "c5696df9de87fa86803b87ed95101d320f146197", + [ + null, + {} + ] + ], "multiple-text-nodes.window.js": [ "07c55e966933924d49ef82d98f35e639e5659669", [ @@ -691243,6 +693933,15 @@ ] ], "customizable-select": { + "button-in-popover.tentative.html": [ + "da217f03e15e521ca08265a6f069893c8b0d0a36", + [ + null, + { + "testdriver": true + } + ] + ], "nested-options.tenative.html": [ "7e89a5ad428f69b04d21d1ba7dbd56a8d06ff988", [ @@ -691331,7 +694030,7 @@ ] ], "select-parsing.tentative.html": [ - "5aa4638f0be81919e01d53ea4bae5b0c1ba60cc5", + "1a5b059997bac428f70e406169d27684462cd5c6", [ null, {} @@ -692354,6 +695053,15 @@ {} ] ], + "popover-dialog-does-not-block-mouse-events.html": [ + "97f17410f70a9311b19a77dcb4496e1c654a41bd", + [ + null, + { + "testdriver": true + } + ] + ], "remove-dialog-should-unblock-document.html": [ "2f2fbad1fc65b02296fbc05ad4bc9c17e66f584e", [ @@ -692392,7 +695100,7 @@ ] ], "toggle-events.tentative.html": [ - "b30433f4a92a3e043ccef6d75305408e6a75d6f0", + "555dc03b019e6293047322c278febf80d9e99cbe", [ null, {} @@ -703330,7 +706038,7 @@ }, "update-rendering": { "child-document-raf-order.html": [ - "eccc1bde7fb83449275ed61e0dacaeb13d684456", + "222c1af444e5c3f7aab2ac466b6bd1a7e2c93e3e", [ null, {} @@ -712509,7 +715217,7 @@ ] ], "VideoTrackGenerator-with-window-tracks.https.html": [ - "36fc4135e23443c404c8255fbae1132effa9100d", + "dfe000fbddb6cddd52538dfdcb686c2357ca1ff7", [ null, {} @@ -718101,9 +720809,13 @@ }, "state": { "cross-document-away-and-back.html": [ - "cccaebdf7b9af3bf4f5715f1592b29f12ee12022", + "f531ec6771544f62a81c113f7a945cb6ac8b1066", [ - null, + "navigation-api/state/cross-document-away-and-back.html?method=navigate", + {} + ], + [ + "navigation-api/state/cross-document-away-and-back.html?method=updateCurrentEntry", {} ] ], @@ -718122,30 +720834,46 @@ ] ], "cross-document-location-api.html": [ - "395d95c6fbe64556e9de5869fd48e368190b66a7", + "5a22473e6bbfd1b3d3e8f5314e580fefcf032103", [ - null, + "navigation-api/state/cross-document-location-api.html?method=navigate", + {} + ], + [ + "navigation-api/state/cross-document-location-api.html?method=updateCurrentEntry", {} ] ], "history-pushState.html": [ - "7d3c79ba6ca2872754bdbf6073390405d9c13e99", + "8c63f72e53ba36071e599b81981fb9ffe3d6ed4d", [ - null, + "navigation-api/state/history-pushState.html?method=navigate", + {} + ], + [ + "navigation-api/state/history-pushState.html?method=updateCurrentEntry", {} ] ], "history-replaceState.html": [ - "bdf3561639321ff4d307544d8ca19fceadebbd93", + "7098201caa748ead09b7ca92b5d88560d6c76263", [ - null, + "navigation-api/state/history-replaceState.html?method=navigate", + {} + ], + [ + "navigation-api/state/history-replaceState.html?method=updateCurrentEntry", {} ] ], "location-reload.html": [ - "bf1bc105fbfc84885b9f5b47c0962b751271b3b0", + "5a566c66fd5a4da476b7215009f74fb92e34136e", [ - null, + "navigation-api/state/location-reload.html?method=navigate", + {} + ], + [ + "navigation-api/state/location-reload.html?method=updateCurrentEntry", {} ] ], @@ -718172,20 +720900,6 @@ {} ] ], - "cross-document-away-and-back.html": [ - "c37d5e979a069f73faf7972801792bc36c5a6f01", - [ - null, - {} - ] - ], - "cross-document-location-api.html": [ - "26191fb8761b6dfbca7881f5b5bb2e62d7690155", - [ - null, - {} - ] - ], "exception-order-initial-about-blank-unserializablestate.html": [ "010632a40fcda3c98ff76965c61453919d6f42ba", [ @@ -718200,20 +720914,6 @@ {} ] ], - "history-pushState.html": [ - "852294c64f4e8fd596637032ecc363076ca86ee7", - [ - null, - {} - ] - ], - "history-replaceState.html": [ - "3eb91a9a80cef8e1a2036181503867ec490c1168", - [ - null, - {} - ] - ], "initial-about-blank.html": [ "c28137c082a3b30fd9f575abd797c107108d0851", [ @@ -718221,13 +720921,6 @@ {} ] ], - "location-reload.html": [ - "8589eeb694e73cb08852ec31c0577cb5d21e2a30", - [ - null, - {} - ] - ], "no-args.html": [ "3fd011e3d37335cacc2c02c3d6649e9a3dc22fd8", [ @@ -740169,6 +742862,13 @@ {} ] ], + "html5lib-basics.tentative.html": [ + "1df4d49f704daa2e8f8370774df5d2b421972eff", + [ + null, + {} + ] + ], "idlharness.https.window.js": [ "384317b8e55bd318464c68e20ca737bfb5b2c966", [ @@ -742428,7 +745128,7 @@ ] ], "animation-timeline-computed.html": [ - "1e621eee531c22e80d98fb3dc30517cf4153ce07", + "51454f6853d3a6dc04ef7cdfd0b71100ec6af952", [ null, {} @@ -742477,7 +745177,7 @@ ] ], "animation-timeline-parsing.html": [ - "9e3c1078b5b416ac8402abe8901ca8e1c8d0a9fa", + "44e9caf002e5b5c05d5bd5653fe5fd81f3843900", [ null, {} @@ -743021,7 +745721,7 @@ ] ], "setting-current-time.html": [ - "f6c826db6993663462727f8ec4629e62adf28f61", + "5daa459bbeb88523a8713afed25b5d35785a61f0", [ null, {} @@ -743035,7 +745735,7 @@ ] ], "setting-start-time.html": [ - "aae1849565b15271105614d198b161f27d091940", + "d950eb8188de218be712b6fedbf0f7b312e7d27c", [ null, {} @@ -743924,6 +746624,13 @@ ] ] }, + "caret-position-should-be-correct-while-moveup-movedown.html": [ + "45d95a96b040a6f168068f975fb203503024ac49", + [ + null, + {} + ] + ], "collapse-00.html": [ "6adaca4002dc7b4e103e72c75e8f44b0ffeefd70", [ @@ -744321,7 +747028,25 @@ ] ], "Selection-getComposedRanges-collapsed.html": [ - "99ab82eb39cf44ac19cc32b42bd50eb1eef1b93a", + "3ea6e0c62c734a8b13f5737daca5c4684b4b0bfa", + [ + null, + {} + ] + ], + "Selection-getComposedRanges-dom-mutations-removal.html": [ + "d89dcb2ce9ddb9318c36a66b64b1abb3ce1aef7c", + [ + "selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html?mode=closed", + {} + ], + [ + "selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html?mode=open", + {} + ] + ], + "Selection-getComposedRanges-slot.html": [ + "d9664b0e1505fad35444628d707de390fac0e11f", [ null, {} @@ -748825,7 +751550,7 @@ ] ], "grid-order-across-scopes.html": [ - "76e5af8c74b24201bd73911c3f3720d6f5861292", + "629bfea2aff5c66a179d304e2a14c48c5426ec93", [ null, { @@ -748853,7 +751578,7 @@ ] ], "grid-order-with-display-contents.html": [ - "b69f3d20799abdd562cff016818252818ceac8bc", + "6d012f49cea56be6d11f7249639c757d41e9878e", [ null, { @@ -748912,7 +751637,7 @@ ] ], "grid-order-with-slots.html": [ - "f52c9ebdc817a4813d3f521c63caa447ddc87db6", + "eff412296d9627ff46bc7c298f91d78eb15d71c0", [ null, { @@ -750037,6 +752762,13 @@ {} ] ], + "interest-groups.tentative.https.sub.html": [ + "2889500be232ee2fbbc11ef379a96028cd150af0", + [ + null, + {} + ] + ], "run-operation-in-detached-frame.tentative.https.sub.html": [ "a7ef103d00fe8f707043be171acfc4d206fee749", [ @@ -750416,6 +753148,13 @@ null, {} ] + ], + "web-locks.tentative.https.sub.html": [ + "49a039368a36322f0f0579015695aee15798529d", + [ + null, + {} + ] ] }, "shared-storage-selecturl-limit": { @@ -754636,13 +757375,6 @@ } ] ], - "quotachange-in-detached-iframe.tentative.https.html": [ - "123af50e3ce6a3f98756d0377a166dbecfa146fe", - [ - null, - {} - ] - ], "storagemanager-estimate.https.any.js": [ "3b6f4d8edc4c2e51d6e9efbc2a2929e75d6b6725", [ @@ -765376,7 +768108,7 @@ ] ], "block-string-assignment-to-Element-insertAdjacentHTML.html": [ - "e4fec3a8a70dbfbdb92668a8b84395163557d0b1", + "af1f982e5a1fa562be28f33783fa076467b389b0", [ null, {} @@ -765674,7 +768406,7 @@ ] ], "trusted-types-navigation.html": [ - "2113711902ae787cb3ad5d0e44eaed0fc2e99b87", + "74a25fa3480c3779da87705812e26a3043edd2bc", [ null, {} @@ -772783,6 +775515,118 @@ ] ] }, + "jspi": { + "js-promise-integration.any.js": [ + "19de3146f921f600046f68014290a9ef607e0a7f", + [ + null, + { + "jsshell": true, + "script_metadata": [ + [ + "global", + "window,dedicatedworker,jsshell" + ], + [ + "script", + "/wasm/jsapi/wasm-module-builder.js" + ] + ] + } + ], + [ + "wasm/jsapi/jspi/js-promise-integration.any.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,jsshell" + ], + [ + "script", + "/wasm/jsapi/wasm-module-builder.js" + ] + ] + } + ], + [ + "wasm/jsapi/jspi/js-promise-integration.any.worker.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,jsshell" + ], + [ + "script", + "/wasm/jsapi/wasm-module-builder.js" + ] + ] + } + ] + ], + "rejects.any.js": [ + "3ec3b90592a2a829a226d8f5bdd0e84538fcdcca", + [ + null, + { + "jsshell": true, + "script_metadata": [ + [ + "global", + "window,dedicatedworker,jsshell" + ], + [ + "script", + "/wasm/jsapi/wasm-module-builder.js" + ], + [ + "script", + "/wasm/jsapi/jspi/testharness-additions.js" + ] + ] + } + ], + [ + "wasm/jsapi/jspi/rejects.any.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,jsshell" + ], + [ + "script", + "/wasm/jsapi/wasm-module-builder.js" + ], + [ + "script", + "/wasm/jsapi/jspi/testharness-additions.js" + ] + ] + } + ], + [ + "wasm/jsapi/jspi/rejects.any.worker.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,jsshell" + ], + [ + "script", + "/wasm/jsapi/wasm-module-builder.js" + ], + [ + "script", + "/wasm/jsapi/jspi/testharness-additions.js" + ] + ] + } + ] + ] + }, "memory": { "buffer.any.js": [ "fb1d1200b892be1eb7aea66db343db491e921a8d", @@ -778262,6 +781106,15 @@ } ] ], + "test-analyser-resume-after-suspended.html": [ + "82b17faa5a262c2b0e5d77310c5355754168aa26", + [ + null, + { + "timeout": "long" + } + ] + ], "test-analyser-scale.html": [ "904b14bede544ac63a08dc422df63fb59d53c048", [ @@ -778551,7 +781404,7 @@ ] ], "processing-after-resume.https.html": [ - "a456f88e186c20b58856fdec2beb1493b0657a0d", + "e000ab124fefa6f0eea4e5517d04436428c0cd8c", [ null, {} @@ -789847,7 +792700,7 @@ ] ], "byob_readtensor.https.any.js": [ - "b99c8704d236c0f18f006514eb65a64566a3369e", + "f43cca0ea4eb7de5cdd3070cf4581bf90c1ae6a2", [ "webnn/conformance_tests/byob_readtensor.https.any.html?cpu", { @@ -792031,7 +794884,7 @@ ] ], "dequantizeLinear.https.any.js": [ - "c6acb042a2462605ae46b3e388a706081ff0670f", + "8a04d0e6b8a36f1f4b5e3a0a9b04feec1acf7ab3", [ "webnn/conformance_tests/dequantizeLinear.https.any.html?cpu", { @@ -793783,7 +796636,7 @@ ] ], "gather.https.any.js": [ - "3cdd411ecb3fada629dd458cf51e5916bf1b322c", + "17c314137586e44c259292e46b64fd283e2e236f", [ "webnn/conformance_tests/gather.https.any.html?cpu", { @@ -794221,7 +797074,7 @@ ] ], "gatherND.https.any.js": [ - "e8f31d5617b40879853fcd9df31aa1d51cfaf796", + "b40507d2dcebd95590a74e0279dea160e513ba5f", [ "webnn/conformance_tests/gatherND.https.any.html?cpu", { @@ -796411,7 +799264,7 @@ ] ], "inputs-are-not-modified.https.any.js": [ - "ffd2d93a557f69798d5e975bad5f0db1f483690d", + "730941fbd8b6ec7f61a364b88a68ba84cb33d9b8", [ "webnn/conformance_tests/inputs-are-not-modified.https.any.html?cpu", { @@ -798163,7 +801016,7 @@ ] ], "logical_and.https.any.js": [ - "be379de157c5d0406afd11b3d4ffc68b29676859", + "3d46c0b2406c7253ccc18ebc351a1bb5063f7855", [ "webnn/conformance_tests/logical_and.https.any.html?cpu", { @@ -798601,7 +801454,7 @@ ] ], "logical_or.https.any.js": [ - "f5eb21de7295af5a67a516318f0bf02434896e81", + "3be3b0090f2435a28b81036c232a90baabbe43b0", [ "webnn/conformance_tests/logical_or.https.any.html?cpu", { @@ -798820,7 +801673,7 @@ ] ], "logical_xor.https.any.js": [ - "b678b04065b2cfa57aaa7f17ebbd61309b57c9b9", + "cab96c27237f16e8773b9539e173271d3f335eb0", [ "webnn/conformance_tests/logical_xor.https.any.html?cpu", { @@ -801010,7 +803863,7 @@ ] ], "parallel-dispatch.https.any.js": [ - "dfdf70a6aa46fed4aabc9d9db32f5f4c9912dfee", + "4051645771fa0c70531bff2fe4cd7132a20c5d26", [ "webnn/conformance_tests/parallel-dispatch.https.any.html?cpu", { @@ -801886,7 +804739,7 @@ ] ], "quantizeLinear.https.any.js": [ - "0871c881b717b7eae1a8c016a363c4b39b59d63f", + "8aa9d7f3bcc407d92762ddbf67be894a7d17c34e", [ "webnn/conformance_tests/quantizeLinear.https.any.html?cpu", { @@ -805170,6 +808023,225 @@ } ] ], + "scatterElements.https.any.js": [ + "561260d47ecf66943cb8c3a463ba3f6dc7c22c06", + [ + "webnn/conformance_tests/scatterElements.https.any.html?cpu", + { + "script_metadata": [ + [ + "title", + "test WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "webnn/conformance_tests/scatterElements.https.any.html?gpu", + { + "script_metadata": [ + [ + "title", + "test WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "webnn/conformance_tests/scatterElements.https.any.html?npu", + { + "script_metadata": [ + [ + "title", + "test WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "webnn/conformance_tests/scatterElements.https.any.worker.html?cpu", + { + "script_metadata": [ + [ + "title", + "test WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "webnn/conformance_tests/scatterElements.https.any.worker.html?gpu", + { + "script_metadata": [ + [ + "title", + "test WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "webnn/conformance_tests/scatterElements.https.any.worker.html?npu", + { + "script_metadata": [ + [ + "title", + "test WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], "scatterND.https.any.js": [ "002ee3e4914e7a2d4d2c4d68c27743ddd596a9ae", [ @@ -808237,7 +811309,7 @@ ] ], "tensor.https.any.js": [ - "51905bbaf3c590ee3f5c2e801ae9988c5cb37152", + "0bc51614608f514dbb3879fcb0bb468c88af9bb7", [ "webnn/conformance_tests/tensor.https.any.html?cpu", { @@ -810929,7 +814001,7 @@ ] ], "constant.https.any.js": [ - "b9b75e372b0169ca459def7a9152873c78c70bce", + "fc0243197dba43d5e53052ebc56cc9ce12f281fb", [ "webnn/validation_tests/constant.https.any.html?cpu", { @@ -812063,7 +815135,7 @@ ] ], "destroyContext.https.any.js": [ - "b4027e23dba0f1d5fe527def8e3fa3a323049ff7", + "abed6b09bde43c10e33214129a0df5681d3739c2", [ "webnn/validation_tests/destroyContext.https.any.html?cpu", { @@ -812258,7 +815330,7 @@ ] ], "destroyGraph.https.any.js": [ - "f7eb01eafef7ef57676c8b9d21a5579503da6d8a", + "4d883e9f3c3eaf5e28e6936980a8c399d0b537c6", [ "webnn/validation_tests/destroyGraph.https.any.html?cpu", { @@ -815099,7 +818171,7 @@ ] ], "input.https.any.js": [ - "0649c67f086e16beb8665de28210573a55987034", + "b5b257d8bb02a2a93bf4af2c86d7944298530fc3", [ "webnn/validation_tests/input.https.any.html?cpu", { @@ -818554,6 +821626,195 @@ } ] ], + "scatterElements.https.any.js": [ + "15551b2bbe5b48bb50813ee02a69b75351aed8ba", + [ + "webnn/validation_tests/scatterElements.https.any.html?cpu", + { + "script_metadata": [ + [ + "title", + "validation tests for WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils_validation.js" + ] + ] + } + ], + [ + "webnn/validation_tests/scatterElements.https.any.html?gpu", + { + "script_metadata": [ + [ + "title", + "validation tests for WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils_validation.js" + ] + ] + } + ], + [ + "webnn/validation_tests/scatterElements.https.any.html?npu", + { + "script_metadata": [ + [ + "title", + "validation tests for WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils_validation.js" + ] + ] + } + ], + [ + "webnn/validation_tests/scatterElements.https.any.worker.html?cpu", + { + "script_metadata": [ + [ + "title", + "validation tests for WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils_validation.js" + ] + ] + } + ], + [ + "webnn/validation_tests/scatterElements.https.any.worker.html?gpu", + { + "script_metadata": [ + [ + "title", + "validation tests for WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils_validation.js" + ] + ] + } + ], + [ + "webnn/validation_tests/scatterElements.https.any.worker.html?npu", + { + "script_metadata": [ + [ + "title", + "validation tests for WebNN API scatterElements operation" + ], + [ + "global", + "window,dedicatedworker" + ], + [ + "variant", + "?cpu" + ], + [ + "variant", + "?gpu" + ], + [ + "variant", + "?npu" + ], + [ + "script", + "../resources/utils_validation.js" + ] + ] + } + ] + ], "scatterND.https.any.js": [ "5e28471fffa47aa985bc2d6a681156a029f7661b", [ @@ -821195,7 +824456,7 @@ ] ], "RTCPeerConnection-getStats-timestamp.https.html": [ - "9345d5838d126beccbe025bf32a45ada5a1d2b89", + "af97521901890e0fc7a4511010b44118c3679bfe", [ null, { @@ -821534,6 +824795,13 @@ {} ] ], + "RTCRtpEncodingParameters-codec-opus-stereo.https.html": [ + "49335eada4ff3548fcf9173ea93aef7a52f75955", + [ + null, + {} + ] + ], "RTCRtpParameters-codec.html": [ "9903776cceb7de610d0aa3d24625d1ee16206aba", [ @@ -844975,7 +848243,7 @@ ] ], "constructor-submitter-coordinate.html": [ - "992f64b721749b85e6d60ed701883242e8faf0fd", + "b7bf128bd1207a7f52327216304794c2fb6d048d", [ null, {} @@ -845215,6 +848483,15 @@ ] } ] + ], + "submitter-coordinate-value.html": [ + "69bea0ac3f94f48fec9e201b6eda640870557756", + [ + null, + { + "testdriver": true + } + ] ] }, "formdata.html": [ @@ -867842,7 +871119,7 @@ {} ] ], - "frame.py": [ + "frame_tentative.py": [ "bab97a31d209f30e0861e7ba768109c717523a4a", [ null, @@ -868186,7 +871463,14 @@ ] ], "context.py": [ - "f8074b71b43096ba3965f5c64002c4641fb7f0ac", + "2530eedb1b3cbf7b8555e6fbd8fe81c5dc2a30ad", + [ + null, + {} + ] + ], + "frame_tentative.py": [ + "98972d86245c8e5e261b6a2e4b53f454decbb3fb", [ null, {} @@ -868728,7 +872012,7 @@ ] ], "before_request_sent_cached.py": [ - "4177d316c5157fa3b68e7a84dfb64619b18086ee", + "a042e7510b4914b4b2f07294eac6e45d1ec8170c", [ null, {} @@ -868971,7 +872255,7 @@ ] ], "response_completed_cached.py": [ - "dac13abf61b9147cb4efa9dd95ac7ab8672e2c30", + "0a624dcfaedb72ff9c72a0e67700b9bbfaf258e4", [ null, {} @@ -868987,7 +872271,7 @@ ] ], "response_started_cached.py": [ - "ccb7a97300d90874be06b5a6bed7af989209d828", + "db0a2514c9322776d19a9861cf3f905cdf4157f8", [ null, {} diff --git a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini index 6615fe1a314..4908d521ddc 100644 --- a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js.ini @@ -92,6 +92,99 @@ [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), {name: Ed25519}, false, [sign, sign\])] expected: FAIL + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign, sign\])] + expected: FAIL + [okp_importKey_Ed25519.https.any.worker.html] [Good parameters: Ed25519 bits (spki, buffer(44), {name: Ed25519}, true, [verify\])] @@ -186,3 +279,96 @@ [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), {name: Ed25519}, false, [sign, sign\])] expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(kty, crv, x), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed25519 (jwk, object(crv, d, x, kty), Ed25519, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [\])] + expected: FAIL + + [Good parameters: Ed25519 bits (spki, buffer(44), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(kty, crv, x), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (raw, buffer(32), Ed25519, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (pkcs8, buffer(48), Ed25519, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed25519 bits (jwk, object(crv, d, x, kty), Ed25519, false, [sign, sign\])] + expected: FAIL diff --git a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini index 558ee948191..dae94493d3a 100644 --- a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js.ini @@ -92,6 +92,99 @@ [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), {name: Ed448}, false, [sign, sign\])] expected: FAIL + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign, sign\])] + expected: FAIL + [okp_importKey_Ed448.https.any.worker.html] [Good parameters: Ed448 bits (spki, buffer(69), {name: Ed448}, true, [verify\])] @@ -186,3 +279,96 @@ [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), {name: Ed448}, false, [sign, sign\])] expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(kty, crv, x), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, true, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters with ignored JWK alg: Ed448 (jwk, object(crv, d, x, kty), Ed448, true, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [\])] + expected: FAIL + + [Good parameters: Ed448 bits (spki, buffer(69), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(kty, crv, x), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (raw, buffer(57), Ed448, false, [verify, verify\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (pkcs8, buffer(73), Ed448, false, [sign, sign\])] + expected: FAIL + + [Good parameters: Ed448 bits (jwk, object(crv, d, x, kty), Ed448, false, [sign, sign\])] + expected: FAIL diff --git a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini index 809f315a565..d396d9eb1ac 100644 --- a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js.ini @@ -80,6 +80,87 @@ [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), {name: X25519}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + [Good parameters: X25519 bits (spki, buffer(44), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (spki, buffer(44), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + [okp_importKey_X25519.https.any.html] [Good parameters: X25519 bits (spki, buffer(44), {name: X25519}, true, [\])] @@ -162,3 +243,84 @@ [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), {name: X25519}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + + [Good parameters: X25519 bits (spki, buffer(44), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(kty, crv, x), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, true, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X25519 (jwk, object(crv, d, x, kty), X25519, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (spki, buffer(44), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(kty, crv, x), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (raw, buffer(32), X25519, false, [\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (pkcs8, buffer(48), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X25519 bits (jwk, object(crv, d, x, kty), X25519, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL diff --git a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini index 327e034f189..56f2d119204 100644 --- a/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini +++ b/tests/wpt/meta/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js.ini @@ -80,6 +80,87 @@ [Good parameters: X448 bits (jwk, object(crv, d, x, kty), {name: X448}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + [Good parameters: X448 bits (spki, buffer(68), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (spki, buffer(68), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + [okp_importKey_X448.https.any.worker.html] [Good parameters: X448 bits (spki, buffer(68), {name: X448}, true, [\])] @@ -162,3 +243,84 @@ [Good parameters: X448 bits (jwk, object(crv, d, x, kty), {name: X448}, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] expected: FAIL + + [Good parameters: X448 bits (spki, buffer(68), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(kty, crv, x), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, true, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters with ignored JWK alg: X448 (jwk, object(crv, d, x, kty), X448, true, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (spki, buffer(68), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(kty, crv, x), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (raw, buffer(56), X448, false, [\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits, deriveKey\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (pkcs8, buffer(72), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL + + [Good parameters: X448 bits (jwk, object(crv, d, x, kty), X448, false, [deriveKey, deriveBits, deriveKey, deriveBits\])] + expected: FAIL diff --git a/tests/wpt/meta/css/css-color/parsing/color-computed-relative-color.html.ini b/tests/wpt/meta/css/css-color/parsing/color-computed-relative-color.html.ini index d4e0b6dccc5..70aa2015799 100644 --- a/tests/wpt/meta/css/css-color/parsing/color-computed-relative-color.html.ini +++ b/tests/wpt/meta/css/css-color/parsing/color-computed-relative-color.html.ini @@ -3697,3 +3697,9 @@ [Property background-color value 'hsl(from currentColor calc((h / 360) * 360deg) s l)'] expected: FAIL + + [Property color value 'light-dark(rgb(from rebeccapurple r g b), rgb(from rebeccapurple r g b))'] + expected: FAIL + + [Property color value 'light-dark(color-mix(in srgb, rgb(from rebeccapurple none g b), rebeccapurple), color-mix(in srgb, rgb(from rebeccapurple none g b), rebeccapurple))'] + expected: FAIL diff --git a/tests/wpt/meta/css/css-color/parsing/color-valid-relative-color.html.ini b/tests/wpt/meta/css/css-color/parsing/color-valid-relative-color.html.ini index 3d655cd0048..380c9a54f3f 100644 --- a/tests/wpt/meta/css/css-color/parsing/color-valid-relative-color.html.ini +++ b/tests/wpt/meta/css/css-color/parsing/color-valid-relative-color.html.ini @@ -3724,3 +3724,6 @@ [e.style['color'\] = "color(from color-mix(in xyz-d65, color(xyz-d65 0.7 0.5 0.3), color(xyz-d65 0.7 0.5 0.3)) xyz-d65 x y z / alpha)" should set the property value] expected: FAIL + + [e.style['color'\] = "oklch(from red calc(1 / l) c h)" should set the property value] + expected: FAIL diff --git a/tests/wpt/meta/css/css-conditional/container-queries/at-container-overflowing-parsing.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-overflowing-parsing.html.ini index 72f4601118a..72f4601118a 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/at-container-overflowing-parsing.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-overflowing-parsing.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/at-container-overflowing-serialization.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-overflowing-serialization.html.ini index 18c1abafcc7..18c1abafcc7 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/at-container-overflowing-serialization.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-overflowing-serialization.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/at-container-snapped-parsing.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-snapped-parsing.html.ini index 6ad6378fe26..6ad6378fe26 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/at-container-snapped-parsing.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-snapped-parsing.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/at-container-snapped-serialization.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-snapped-serialization.html.ini index 35c90640507..35c90640507 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/at-container-snapped-serialization.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-snapped-serialization.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/at-container-stuck-parsing.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-stuck-parsing.html.ini index 849d4af452a..849d4af452a 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/at-container-stuck-parsing.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-stuck-parsing.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/at-container-stuck-serialization.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-stuck-serialization.html.ini index 95ca2e600cb..95ca2e600cb 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/at-container-stuck-serialization.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/at-container-stuck-serialization.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/container-type-scroll-state-computed.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-computed.html.ini index bf71bdf192b..bf71bdf192b 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/container-type-scroll-state-computed.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-computed.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/container-type-scroll-state-containment.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-containment.html.ini index 6816d82fe23..6816d82fe23 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/container-type-scroll-state-containment.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-containment.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/container-type-scroll-state-parsing.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-parsing.html.ini index 77be49bdc31..77be49bdc31 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/container-type-scroll-state-parsing.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-parsing.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-initially-snapped.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-initially-snapped.html.ini index 0b354083d7a..0b354083d7a 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-initially-snapped.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-initially-snapped.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-initially-stuck.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-initially-stuck.html.ini index 7260020fd97..7260020fd97 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-initially-stuck.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-initially-stuck.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-change.html.ini index 346d353eab5..346d353eab5 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-change.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-change.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-container-type-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-container-type-change.html.ini index a1cd47a47cc..a1cd47a47cc 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-container-type-change.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-container-type-change.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-none.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-none.html.ini index e5d314021fb..e5d314021fb 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-none.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-none.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-wm.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-wm.html.ini index a91d853ebd3..a91d853ebd3 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-snapped-wm.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-wm.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html.ini new file mode 100644 index 00000000000..f0b3a1e7a8a --- /dev/null +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html.ini @@ -0,0 +1,2 @@ +[scroll-state-stuck-container-type-change.html] + expected: ERROR diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html.ini new file mode 100644 index 00000000000..3caa58f120b --- /dev/null +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html.ini @@ -0,0 +1,2 @@ +[scroll-state-stuck-writing-direction.html] + expected: ERROR diff --git a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-target-query-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-target-query-change.html.ini index 8125d4e9608..8125d4e9608 100644 --- a/tests/wpt/meta/css/css-conditional/container-queries/scroll-state-target-query-change.html.ini +++ b/tests/wpt/meta/css/css-conditional/container-queries/scroll-state/scroll-state-target-query-change.html.ini diff --git a/tests/wpt/meta/css/css-conditional/container-queries/size-container-writing-mode-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/size-container-writing-mode-change.html.ini new file mode 100644 index 00000000000..7e0cf86879c --- /dev/null +++ b/tests/wpt/meta/css/css-conditional/container-queries/size-container-writing-mode-change.html.ini @@ -0,0 +1,2 @@ +[size-container-writing-mode-change.html] + expected: ERROR diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/webkit-line-clamp-050.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/webkit-line-clamp-050.html.ini new file mode 100644 index 00000000000..9a1676cf418 --- /dev/null +++ b/tests/wpt/meta/css/css-overflow/line-clamp/webkit-line-clamp-050.html.ini @@ -0,0 +1,2 @@ +[webkit-line-clamp-050.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-pseudo/first-line-below-float.html.ini b/tests/wpt/meta/css/css-pseudo/first-line-below-float.html.ini new file mode 100644 index 00000000000..077242949df --- /dev/null +++ b/tests/wpt/meta/css/css-pseudo/first-line-below-float.html.ini @@ -0,0 +1,2 @@ +[first-line-below-float.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html.ini b/tests/wpt/meta/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html.ini new file mode 100644 index 00000000000..e06425a5209 --- /dev/null +++ b/tests/wpt/meta/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html.ini @@ -0,0 +1,18 @@ +[the-check-pseudo-element.tentative.html] + ["::check" should be a valid selector] + expected: FAIL + + ["*::check" should be a valid selector] + expected: FAIL + + ["foo.bar[baz\]::check" should be a valid selector] + expected: FAIL + + ["::check::marker" should be a valid selector] + expected: FAIL + + ["::slotted(*)::check" should be a valid selector] + expected: FAIL + + ["::part(foo)::check" should be a valid selector] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini b/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini index 88ff05eb181..1797743c462 100644 --- a/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini +++ b/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini @@ -496,3 +496,27 @@ [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <height> from [max-content\] to [stretch\] at (0.3) should be [max-content\]] expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (0.5) should be [100px\]] + expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (0.6) should be [100px\]] + expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (1) should be [100px\]] + expected: FAIL + + [CSS Animations: property <height> from neutral to [100px\] at (1.5) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (0.5) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (0.6) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (1) should be [100px\]] + expected: FAIL + + [Web Animations: property <height> from neutral to [100px\] at (1.5) should be [100px\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/abspos-1.html.ini b/tests/wpt/meta/css/css-sizing/stretch/abspos-1.html.ini new file mode 100644 index 00000000000..c57e026f684 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/abspos-1.html.ini @@ -0,0 +1,2 @@ +[abspos-1.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/abspos-2.html.ini b/tests/wpt/meta/css/css-sizing/stretch/abspos-2.html.ini new file mode 100644 index 00000000000..c5dc50ec598 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/abspos-2.html.ini @@ -0,0 +1,2 @@ +[abspos-2.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/block-height-1.html.ini b/tests/wpt/meta/css/css-sizing/stretch/block-height-1.html.ini new file mode 100644 index 00000000000..51f953f5c6a --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/block-height-1.html.ini @@ -0,0 +1,27 @@ +[block-height-1.html] + [[data-expected-height\] 1] + expected: FAIL + + [[data-expected-height\] 2] + expected: FAIL + + [[data-expected-height\] 3] + expected: FAIL + + [[data-expected-height\] 7] + expected: FAIL + + [[data-expected-height\] 8] + expected: FAIL + + [[data-expected-height\] 9] + expected: FAIL + + [[data-expected-height\] 13] + expected: FAIL + + [[data-expected-height\] 14] + expected: FAIL + + [[data-expected-height\] 15] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/block-height-2.html.ini b/tests/wpt/meta/css/css-sizing/stretch/block-height-2.html.ini new file mode 100644 index 00000000000..9b6449c79e3 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/block-height-2.html.ini @@ -0,0 +1,6 @@ +[block-height-2.html] + [[data-expected-height\] 1] + expected: FAIL + + [[data-expected-height\] 2] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/min-width-1.html.ini b/tests/wpt/meta/css/css-sizing/stretch/min-width-1.html.ini new file mode 100644 index 00000000000..e3446c9bc89 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/min-width-1.html.ini @@ -0,0 +1,2 @@ +[min-width-1.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/positioned-non-replaced-1.html.ini b/tests/wpt/meta/css/css-sizing/stretch/positioned-non-replaced-1.html.ini new file mode 100644 index 00000000000..025f23f9b67 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/positioned-non-replaced-1.html.ini @@ -0,0 +1,2 @@ +[positioned-non-replaced-1.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/stretch/positioned-replaced-1.html.ini b/tests/wpt/meta/css/css-sizing/stretch/positioned-replaced-1.html.ini new file mode 100644 index 00000000000..062731ceee4 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/stretch/positioned-replaced-1.html.ini @@ -0,0 +1,2 @@ +[positioned-replaced-1.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-ui/text-overflow-ellipsis-multiline-001.html.ini b/tests/wpt/meta/css/css-ui/text-overflow-ellipsis-multiline-001.html.ini new file mode 100644 index 00000000000..6f62710f6d1 --- /dev/null +++ b/tests/wpt/meta/css/css-ui/text-overflow-ellipsis-multiline-001.html.ini @@ -0,0 +1,2 @@ +[text-overflow-ellipsis-multiline-001.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-serialization-002.html.ini b/tests/wpt/meta/css/css-values/calc-serialization-002.html.ini new file mode 100644 index 00000000000..e933384770c --- /dev/null +++ b/tests/wpt/meta/css/css-values/calc-serialization-002.html.ini @@ -0,0 +1,3 @@ +[calc-serialization-002.html] + [testing calc((min(10px, 20%) + max(1rem, 2%)) * 2)] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini index 1ff5d2a7b72..a0f3ecf08a5 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/calc-size-height-interpolation.html.ini @@ -3796,3 +3796,123 @@ [Web Animations: property <height> from [calc-size(50px, size)\] to [calc-size(min-content, size)\] at (1) should be [100px\]] expected: FAIL + + [CSS Transitions: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [auto\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(auto, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [min-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(min-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [fit-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(fit-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Animations: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [Web Animations: property <height> from [max-content\] to [calc-size(any, 50px)\] at (1.1) should be [45.00000000000001px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(max-content, size * 2)\] at (-0.05) should be [42.5px\]] + expected: FAIL + + [CSS Transitions: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [CSS Animations: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [Web Animations: property <height> from [stretch\] to [calc-size(any, 50px)\] at (1.1) should be [25.000000000000007px\]] + expected: FAIL + + [CSS Transitions: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL + + [CSS Transitions with transition: all: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL + + [CSS Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL + + [Web Animations: property <height> from [calc-size(any, 50px)\] to [calc-size(stretch, size * 2)\] at (-0.05) should be [22.5px\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-height-composition.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-height-composition.html.ini index 96b318a33c0..2fee6654d57 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-height-composition.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-height-composition.html.ini @@ -25,3 +25,12 @@ [Compositing: property <height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1.5) should be [275px\]] expected: FAIL + + [Compositing: property <height> underlying [fit-content\] from add [min-content\] to add [200px\] at (0.5) should be [250px\]] + expected: FAIL + + [Compositing: property <height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1) should be [250px\]] + expected: FAIL + + [Compositing: property <height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1.5) should be [250px\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini index c480e928296..7b0fbe413b9 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html.ini @@ -28,3 +28,33 @@ [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1.5) should be [calc-size(min-content, 300px + size * -0.5)\]] expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (-0.3) should be [calc-size(fit-content, (100px + size) * 1.3 + (200px + size) * -0.3)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0) should be [calc-size(fit-content, (100px + size) * 1 + (200px + size) * 0)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0.5) should be [calc-size(fit-content, (100px + size) * 0.5 + (200px + size) * 0.5)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1) should be [calc-size(fit-content, (100px + size) * 0 + (200px + size) * 1)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1.5) should be [calc-size(fit-content, (100px + size) * -0.5 + (200px + size) * 1.5)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (-0.3) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (0) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (0.5) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <max-height> underlying [fit-content\] from add [min-content\] to add [200px\] at (1.5) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini index 3a8389477a1..c8802fc001d 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html.ini @@ -43,3 +43,33 @@ [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [calc-size(min-content, -50px + size * 1.5)\]] expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (-0.3) should be [calc-size(fit-content, 260px + (100px + size) * -0.3)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (0) should be [calc-size(fit-content, 200px + (100px + size) * 0)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (0.5) should be [calc-size(fit-content, 100px + (100px + size) * 0.5)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (1) should be [calc-size(fit-content, 0px + (100px + size) * 1)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [100px\] from add [100px\] to add [fit-content\] at (1.5) should be [calc-size(fit-content, -100px + (100px + size) * 1.5)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (-0.3) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0.5) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1) should be [min-content\]] + expected: FAIL + + [Compositing: property <max-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [min-content\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini index 67c9993b16a..f973fc571e9 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html.ini @@ -28,3 +28,33 @@ [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (1.5) should be [calc-size(min-content, -100px + size * 1.5)\]] expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (-0.3) should be [calc-size(fit-content, (100px + size) * 1.3 + (200px + size) * -0.3)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0) should be [calc-size(fit-content, (100px + size) * 1 + (200px + size) * 0)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (0.5) should be [calc-size(fit-content, (100px + size) * 0.5 + (200px + size) * 0.5)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1) should be [calc-size(fit-content, (100px + size) * 0 + (200px + size) * 1)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [100px\] to add [200px\] at (1.5) should be [calc-size(fit-content, (100px + size) * -0.5 + (200px + size) * 1.5)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (-0.3) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (0) should be [calc-size(fit-content, 200px + size)\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (0.5) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (1) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-height> underlying [fit-content\] from add [200px\] to add [min-content\] at (1.5) should be [min-content\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini index ab115e64efe..e3ee8af41b7 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html.ini @@ -43,3 +43,33 @@ [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [calc-size(min-content, -50px + size * 1.5)\]] expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (-0.3) should be [calc-size(max-content, (100px + size) * 1.3 + -60px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (0) should be [calc-size(max-content, (100px + size) * 1 + 0px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (0.5) should be [calc-size(max-content, (100px + size) * 0.5 + 100px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (1) should be [calc-size(max-content, (100px + size) * 0 + 200px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [100px\] from add [max-content\] to add [100px\] at (1.5) should be [calc-size(max-content, (100px + size) * -0.5 + 300px)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (-0.3) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0) should be [calc-size(max-content, 100px + size)\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (0.5) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1) should be [min-content\]] + expected: FAIL + + [Compositing: property <min-width> underlying [max-content\] from add [100px\] to add [min-content\] at (1.5) should be [min-content\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-width-composition.html.ini b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-width-composition.html.ini index 7db347d1dc9..4c55fcb3f11 100644 --- a/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-width-composition.html.ini +++ b/tests/wpt/meta/css/css-values/calc-size/animation/interpolate-size-width-composition.html.ini @@ -40,3 +40,9 @@ [Compositing: property <width> underlying [max-content\] from add [100px\] to add [auto\] at (1.5) should be [250px\]] expected: FAIL + + [Compositing: property <width> underlying [max-content\] from add [200px\] to add [auto\] at (-0.3) should be [300px\]] + expected: FAIL + + [Compositing: property <width> underlying [max-content\] from add [200px\] to add [auto\] at (0) should be [300px\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/minmax-length-percent-serialize.html.ini b/tests/wpt/meta/css/css-values/minmax-length-percent-serialize.html.ini index 2028f309e92..0b7996ae56c 100644 --- a/tests/wpt/meta/css/css-values/minmax-length-percent-serialize.html.ini +++ b/tests/wpt/meta/css/css-values/minmax-length-percent-serialize.html.ini @@ -4,3 +4,9 @@ ['max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)' as a computed value should serialize as 'max(10px + (10px + min(10%, 30px)) * 2, 5% + 80px)'.] expected: FAIL + + ['max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)' as a specified value should serialize as 'max(10px + (2 * (10px + min(10%, 30px))), 5% + 5em)'.] + expected: FAIL + + ['max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)' as a computed value should serialize as 'max(10px + (2 * (10px + min(10%, 30px))), 5% + 80px)'.] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/round-function.html.ini b/tests/wpt/meta/css/css-values/round-function.html.ini new file mode 100644 index 00000000000..819fbf742db --- /dev/null +++ b/tests/wpt/meta/css/css-values/round-function.html.ini @@ -0,0 +1,3 @@ +[round-function.html] + [round(down, (7 - 1) / 3, 1) should be used-value-equivalent to 2] + expected: FAIL diff --git a/tests/wpt/meta/css/cssom-view/MediaQueryList-extends-EventTarget.html.ini b/tests/wpt/meta/css/cssom-view/MediaQueryList-extends-EventTarget.html.ini deleted file mode 100644 index 23065cc9e36..00000000000 --- a/tests/wpt/meta/css/cssom-view/MediaQueryList-extends-EventTarget.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[MediaQueryList-extends-EventTarget.html] - [onchange adds listener] - expected: FAIL diff --git a/tests/wpt/meta/custom-elements/CustomElementRegistry.html.ini b/tests/wpt/meta/custom-elements/CustomElementRegistry.html.ini index 94fedb15835..7b862b2d71c 100644 --- a/tests/wpt/meta/custom-elements/CustomElementRegistry.html.ini +++ b/tests/wpt/meta/custom-elements/CustomElementRegistry.html.ini @@ -1,3 +1,6 @@ [CustomElementRegistry.html] [customElements.define must upgrade elements in the shadow-including tree order] expected: FAIL + + [customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present] + expected: FAIL diff --git a/tests/wpt/meta/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html.ini b/tests/wpt/meta/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html.ini new file mode 100644 index 00000000000..d8b66a385b9 --- /dev/null +++ b/tests/wpt/meta/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html.ini @@ -0,0 +1,12 @@ +[custom-element-move-reactions.html] + [the disconnected/connected callbacks should be called when no other callback is defined] + expected: FAIL + + [the element should stay connected during the callbacks] + expected: FAIL + + [When connectedMoveCallback is defined, it is called instead of disconnectedCallback/connectedCallback] + expected: FAIL + + [Reactions to atomic move are called in order of element, not in order of operation] + expected: FAIL diff --git a/tests/wpt/meta/encoding/legacy-mb-tchinese/big5/big5-decode-csbig5.html.ini b/tests/wpt/meta/encoding/legacy-mb-tchinese/big5/big5-decode-csbig5.html.ini deleted file mode 100644 index 1b45084ecc7..00000000000 --- a/tests/wpt/meta/encoding/legacy-mb-tchinese/big5/big5-decode-csbig5.html.ini +++ /dev/null @@ -1,29 +0,0 @@ -[big5-decode-csbig5.html?1-1000] - -[big5-decode-csbig5.html?5001-6000] - -[big5-decode-csbig5.html?4001-5000] - -[big5-decode-csbig5.html?6001-7000] - -[big5-decode-csbig5.html?3001-4000] - -[big5-decode-csbig5.html?11001-12000] - -[big5-decode-csbig5.html?14001-last] - -[big5-decode-csbig5.html?2001-3000] - -[big5-decode-csbig5.html?7001-8000] - -[big5-decode-csbig5.html?1001-2000] - -[big5-decode-csbig5.html?8001-9000] - -[big5-decode-csbig5.html?9001-10000] - -[big5-decode-csbig5.html?13001-14000] - -[big5-decode-csbig5.html?10001-11000] - -[big5-decode-csbig5.html?12001-13000] diff --git a/tests/wpt/meta/fetch/metadata/generated/css-font-face.https.sub.tentative.html.ini b/tests/wpt/meta/fetch/metadata/generated/css-font-face.https.sub.tentative.html.ini index 37454f3ed97..4dcac5c96b4 100644 --- a/tests/wpt/meta/fetch/metadata/generated/css-font-face.https.sub.tentative.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/css-font-face.https.sub.tentative.html.ini @@ -46,3 +46,6 @@ [sec-fetch-user] expected: FAIL + + [sec-fetch-dest] + expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini b/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini index 4b5c3e26586..7b4cf2c5ae7 100644 --- a/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini @@ -185,3 +185,6 @@ [border-image sec-fetch-site - HTTPS downgrade (header not sent)] expected: FAIL + + [background-image sec-fetch-site - HTTPS downgrade (header not sent)] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a1927668778 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..ef9c00de33f --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..62eee6c2c0b --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..39cfa83a2dc --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..fdb0e9a81f1 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..146aa84730e --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a195925f726 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..eb4b6f2408e --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..a6edb5e7c8e --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..99c3038f22f --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..1167fcdd4df --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..8055e0e6233 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.pattern.html] + 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/text/2d.text.measure.text-clusters-position.tentative.html.ini b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html.ini new file mode 100644 index 00000000000..142f3700afd --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-position.tentative.html] + [Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html.ini b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html.ini new file mode 100644 index 00000000000..ef0e5ba4fbd --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-range.tentative.html] + [Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini new file mode 100644 index 00000000000..034846a0a91 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-align.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini new file mode 100644 index 00000000000..42e0bb131e5 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-baseline.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a1927668778 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..1d2295f3217 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.js.ini new file mode 100644 index 00000000000..b864accf02f --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.filter.no_shadow.drawImage.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..ef9c00de33f --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..6a6e343494b --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.js.ini new file mode 100644 index 00000000000..0f37ae87455 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.filter.no_shadow.fillRect.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..62eee6c2c0b --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html.ini new file mode 100644 index 00000000000..0902ce494c4 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.no_shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.js.ini new file mode 100644 index 00000000000..47935a7a5d0 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.filter.no_shadow.pattern.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..39cfa83a2dc --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..2ded60b14cb --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.js.ini new file mode 100644 index 00000000000..f430bd98558 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.filter.shadow.drawImage.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..fdb0e9a81f1 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..322c7ef3429 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.js.ini new file mode 100644 index 00000000000..958c1fb9bea --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.filter.shadow.fillRect.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..146aa84730e --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html.ini new file mode 100644 index 00000000000..602d69c0f16 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.filter.shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.js.ini new file mode 100644 index 00000000000..79398738220 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.filter.shadow.pattern.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini new file mode 100644 index 00000000000..a195925f726 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..cd15152caf6 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.js.ini new file mode 100644 index 00000000000..92758eb9bd1 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.no_filter.no_shadow.drawImage.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini new file mode 100644 index 00000000000..eb4b6f2408e --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..eec2f16a70d --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.js.ini new file mode 100644 index 00000000000..e619d9eb9ee --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.no_filter.no_shadow.fillRect.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini new file mode 100644 index 00000000000..a6edb5e7c8e --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html.ini new file mode 100644 index 00000000000..087fd35298c --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.js.ini new file mode 100644 index 00000000000..bee6d9d0775 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.no_filter.no_shadow.pattern.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini new file mode 100644 index 00000000000..99c3038f22f --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.drawImage.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html.ini new file mode 100644 index 00000000000..5b9f81d55a7 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.drawImage.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.js.ini new file mode 100644 index 00000000000..a798b37c417 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.no_filter.shadow.drawImage.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini new file mode 100644 index 00000000000..1167fcdd4df --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.fillRect.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html.ini new file mode 100644 index 00000000000..d56ee6bbf95 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.fillRect.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.js.ini new file mode 100644 index 00000000000..33a8dc42b8b --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.no_filter.shadow.fillRect.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini new file mode 100644 index 00000000000..8055e0e6233 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.pattern.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html.ini new file mode 100644 index 00000000000..8108a9bc658 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html.ini @@ -0,0 +1,2 @@ +[2d.composite.grid.no_filter.shadow.pattern.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.js.ini new file mode 100644 index 00000000000..b5d883b658d --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.js.ini @@ -0,0 +1,78 @@ +[2d.composite.grid.no_filter.shadow.pattern.worker.html] + [2d] + expected: FAIL + + [2d 1] + expected: FAIL + + [2d 2] + expected: FAIL + + [2d 3] + expected: FAIL + + [2d 4] + expected: FAIL + + [2d 5] + expected: FAIL + + [2d 6] + expected: FAIL + + [2d 7] + expected: FAIL + + [2d 8] + expected: FAIL + + [2d 9] + expected: FAIL + + [2d 10] + expected: FAIL + + [2d 11] + expected: FAIL + + [2d 12] + expected: FAIL + + [2d 13] + expected: FAIL + + [2d 14] + expected: FAIL + + [2d 15] + expected: FAIL + + [2d 16] + expected: FAIL + + [2d 17] + expected: FAIL + + [2d 18] + expected: FAIL + + [2d 19] + expected: FAIL + + [2d 20] + expected: FAIL + + [2d 21] + expected: FAIL + + [2d 22] + expected: FAIL + + [2d 23] + expected: FAIL + + [2d 24] + expected: FAIL + + [2d 25] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html.ini new file mode 100644 index 00000000000..142f3700afd --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-position.tentative.html] + [Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js.ini new file mode 100644 index 00000000000..4cc1c748611 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-position.tentative.worker.html] + [Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html.ini new file mode 100644 index 00000000000..ef0e5ba4fbd --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-range.tentative.html] + [Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js.ini new file mode 100644 index 00000000000..ca35bd126f7 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js.ini @@ -0,0 +1,3 @@ +[2d.text.measure.text-clusters-range.tentative.worker.html] + [Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini new file mode 100644 index 00000000000..034846a0a91 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-align.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html.ini new file mode 100644 index 00000000000..16b4355c27f --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-align.tentative.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini new file mode 100644 index 00000000000..42e0bb131e5 --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-baseline.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html.ini new file mode 100644 index 00000000000..3d7dd3b6b3a --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-baseline.tentative.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html.ini new file mode 100644 index 00000000000..2150f92957f --- /dev/null +++ b/tests/wpt/meta/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html.ini @@ -0,0 +1,2 @@ +[2d.text.measure.text-clusters-rendering-font-change.tentative.w.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html.ini b/tests/wpt/meta/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html.ini new file mode 100644 index 00000000000..5ce7adc27b8 --- /dev/null +++ b/tests/wpt/meta/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html.ini @@ -0,0 +1,3 @@ +[innertext-whitespace-pre-line.html] + [innerText has collapsed whitespace but preserved newlines with pre-line] + expected: FAIL 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 d7d0d3ef89d..f455bb20528 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: FAIL diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini index 96d866bf3cc..e8872b3585b 100644 --- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini +++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini @@ -1,4 +1,4 @@ [iframe_sandbox_popups_nonescaping-1.html] expected: TIMEOUT [Check that popups from a sandboxed iframe do not escape the sandbox] - expected: FAIL + expected: NOTRUN diff --git a/tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini b/tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini new file mode 100644 index 00000000000..7682a4830bf --- /dev/null +++ b/tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini @@ -0,0 +1,4 @@ +[reparent-form-during-planned-navigation-task.html] + expected: TIMEOUT + [reparent-form-during-planned-navigation-task] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini b/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini index 19b3d41fe42..373ba604823 100644 --- a/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini +++ b/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini @@ -16,3 +16,6 @@ [Divs and imgs should be allowed as direct children of select and within options without a datalist.] expected: FAIL + + [Input tags should parse inside select instead of closing the select.] + expected: FAIL diff --git a/tests/wpt/meta/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini b/tests/wpt/meta/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini index f7b6c87f9c5..d566064c0e0 100644 --- a/tests/wpt/meta/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini +++ b/tests/wpt/meta/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html.ini @@ -16,3 +16,18 @@ [dialog.showModal() should coalesce asynchronous toggle events.] expected: FAIL + + [dialog.show() should not open if beforetoggle removes] + expected: FAIL + + [dialog.show() should not open if beforetoggle calls showPopover] + expected: FAIL + + [dialog.showModal() should not double-set open/close if beforetoggle re-opens] + expected: FAIL + + [dialog.showModal() should not open if beforetoggle removes] + expected: FAIL + + [dialog.showModal() should not open if beforetoggle calls showPopover] + expected: FAIL diff --git a/tests/wpt/meta/selection/caret-position-should-be-correct-while-moveup-movedown.html.ini b/tests/wpt/meta/selection/caret-position-should-be-correct-while-moveup-movedown.html.ini new file mode 100644 index 00000000000..32a129e1440 --- /dev/null +++ b/tests/wpt/meta/selection/caret-position-should-be-correct-while-moveup-movedown.html.ini @@ -0,0 +1,72 @@ +[caret-position-should-be-correct-while-moveup-movedown.html] + [Caret position should be correct in moving up horizontal div when selection was left to right with line granularity] + expected: FAIL + + [Caret position should be correct in moving up horizontal div when selection was right to left with line granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was left to right with line granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was right to left with line granularity] + expected: FAIL + + [Caret position should be correct in moving up horizontal div when selection was left to right with paragraph granularity] + expected: FAIL + + [Caret position should be correct in moving up horizontal div when selection was right to left with paragraph granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was left to right with paragraph granularity] + expected: FAIL + + [Caret position should be correct in moving down horizontal div when selection was right to left with paragraph granularity] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-lr div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-lr div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with line granularity for vertical-rl div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with line granularity for vertical-rl div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move left with paragraph granularity for vertical-rl div when selection was bottom to top] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-rl div when selection was top to bottom] + expected: FAIL + + [Caret position should be correct in move right with paragraph granularity for vertical-rl div when selection was bottom to top] + expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html.ini b/tests/wpt/meta/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html.ini new file mode 100644 index 00000000000..f257677237d --- /dev/null +++ b/tests/wpt/meta/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html.ini @@ -0,0 +1,32 @@ +[Selection-getComposedRanges-dom-mutations-removal.html?mode=open] + [Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.] + expected: FAIL + + [Range is fully in shadow tree. Removing parent of shadow host collapses composed StaticRange.] + expected: FAIL + + [Range is in light DOM. Removing startContainer rescopes new composed range to its parent.] + expected: FAIL + + [Range is across shadow trees. Replacing shadowRoot content rescopes new composed range to the shadowRoot.] + expected: FAIL + + [Range is between two light slotted contents. Removing start container rescopes to its parent in light tree.] + expected: FAIL + + +[Selection-getComposedRanges-dom-mutations-removal.html?mode=closed] + [Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.] + expected: FAIL + + [Range is fully in shadow tree. Removing parent of shadow host collapses composed StaticRange.] + expected: FAIL + + [Range is in light DOM. Removing startContainer rescopes new composed range to its parent.] + expected: FAIL + + [Range is across shadow trees. Replacing shadowRoot content rescopes new composed range to the shadowRoot.] + expected: FAIL + + [Range is between two light slotted contents. Removing start container rescopes to its parent in light tree.] + expected: FAIL diff --git a/tests/wpt/meta/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html.ini b/tests/wpt/meta/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html.ini new file mode 100644 index 00000000000..97d7f6316fd --- /dev/null +++ b/tests/wpt/meta/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html.ini @@ -0,0 +1,9 @@ +[Selection-getComposedRanges-slot.html] + [Setting the range to start on slotted content and end in shadow tree, should follow DOM tree order.] + expected: FAIL + + [Setting the range to start and end on slotted content, should follow DOM tree order.] + expected: FAIL + + [Setting the range to start on unslotted content and end in shadow tree, should follow DOM tree order.] + expected: FAIL diff --git a/tests/wpt/meta/url/failure.html.ini b/tests/wpt/meta/url/failure.html.ini index a3abebff51e..e49fb61f308 100644 --- a/tests/wpt/meta/url/failure.html.ini +++ b/tests/wpt/meta/url/failure.html.ini @@ -724,3 +724,6 @@ [Location's href: stun://[:1\] should throw] expected: FAIL + + [Location's href: non-special://host\\a should throw] + expected: FAIL diff --git a/tests/wpt/meta/wasm/jsapi/jspi/js-promise-integration.any.js.ini b/tests/wpt/meta/wasm/jsapi/jspi/js-promise-integration.any.js.ini new file mode 100644 index 00000000000..0d5f0447d7e --- /dev/null +++ b/tests/wpt/meta/wasm/jsapi/jspi/js-promise-integration.any.js.ini @@ -0,0 +1,63 @@ +[js-promise-integration.any.worker.html] + [Promising function always entered] + expected: FAIL + + [Always get a Promise] + expected: FAIL + + [Suspend once] + expected: FAIL + + [Suspend/resume in a loop] + expected: FAIL + + [Suspending with mismatched args and via Proxy] + expected: FAIL + + [Make sure we actually suspend] + expected: FAIL + + [Do not suspend if the import's return value is not a Promise] + expected: FAIL + + [Catch rejected promise] + expected: FAIL + + [Promising with no return] + expected: FAIL + + [Suspend two modules] + expected: FAIL + + +[js-promise-integration.any.html] + expected: ERROR + [Promising function always entered] + expected: FAIL + + [Always get a Promise] + expected: FAIL + + [Suspend once] + expected: FAIL + + [Suspend/resume in a loop] + expected: FAIL + + [Suspending with mismatched args and via Proxy] + expected: FAIL + + [Make sure we actually suspend] + expected: FAIL + + [Do not suspend if the import's return value is not a Promise] + expected: FAIL + + [Catch rejected promise] + expected: FAIL + + [Promising with no return] + expected: FAIL + + [Suspend two modules] + expected: FAIL diff --git a/tests/wpt/meta/wasm/jsapi/jspi/rejects.any.js.ini b/tests/wpt/meta/wasm/jsapi/jspi/rejects.any.js.ini new file mode 100644 index 00000000000..5fc1ddb57d1 --- /dev/null +++ b/tests/wpt/meta/wasm/jsapi/jspi/rejects.any.js.ini @@ -0,0 +1,32 @@ +[rejects.any.html] + [Throw after the first suspension] + expected: FAIL + + [Throw before suspending] + expected: FAIL + + [Throw and propagate via Promise] + expected: FAIL + + [Stack overflow] + expected: FAIL + + [Try to suspend JS] + expected: FAIL + + +[rejects.any.worker.html] + [Throw after the first suspension] + expected: FAIL + + [Throw before suspending] + expected: FAIL + + [Throw and propagate via Promise] + expected: FAIL + + [Stack overflow] + expected: FAIL + + [Try to suspend JS] + expected: FAIL diff --git a/tests/wpt/meta/webxr/render_state_update.https.html.ini b/tests/wpt/meta/webxr/render_state_update.https.html.ini new file mode 100644 index 00000000000..0e57356683e --- /dev/null +++ b/tests/wpt/meta/webxr/render_state_update.https.html.ini @@ -0,0 +1,2 @@ +[render_state_update.https.html] + expected: ERROR diff --git a/tests/wpt/tests/.github/workflows/safari-wptrunner.yml b/tests/wpt/tests/.github/workflows/safari-wptrunner.yml new file mode 100644 index 00000000000..0860533dc92 --- /dev/null +++ b/tests/wpt/tests/.github/workflows/safari-wptrunner.yml @@ -0,0 +1,115 @@ +name: Run Safari Tests + +on: + workflow_call: + inputs: + artifact-name: + description: "Prefix for the artifact uploaded" + required: true + type: string + safari-technology-preview: + description: "Run Safari Technology Preview rather than the system Safari" + required: true + type: boolean + safaridriver-diagnose: + description: "Run safaridriver capturing diagnostics" + required: true + type: boolean + +# We never interact with the GitHub API, thus we can simply disable all +# permissions the GitHub token would have. +permissions: {} + +jobs: + safari-results: + name: ${{ inputs.safari-technology-preview && 'Safari Technology Preview' || 'Safari' }} + runs-on: + - self-hosted + - webkit-ews + timeout-minutes: 180 + strategy: + matrix: + current-chunk: [1, 2, 3, 4, 5, 6, 7, 8] + total-chunks: [8] + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1 + - name: Set display color profile + run: |- + ./wpt macos-color-profile + - name: Enable safaridriver diagnostics + if: inputs.safaridriver-diagnose + run: |- + rm -rf ~/Library/Logs/com.apple.WebDriver/ + defaults write com.apple.WebDriver DiagnosticsEnabled 1 + - name: Enable safaridriver (Safari) + if: ${{ !inputs.safari-technology-preview }} + run: |- + set -eux -o pipefail + sudo safaridriver --enable + - name: Enable safaridriver (Safari Technology Preview) + if: ${{ inputs.safari-technology-preview }} + run: |- + set -eux -o pipefail + export SYSTEM_VERSION_COMPAT=0 + ./wpt install --channel preview --download-only -d . --rename STP safari browser + sudo installer -pkg STP.pkg -target LocalSystem + sudo /Applications/Safari\ Technology\ Preview.app/Contents/MacOS/safaridriver --enable + - name: Update hosts + run: |- + set -eux -o pipefail + ./wpt make-hosts-file | sudo tee -a /etc/hosts + - name: Update manifest + run: ./wpt manifest + - name: Run tests + run: |- + set -eux -o pipefail + export SYSTEM_VERSION_COMPAT=0 + ./wpt run \ + --no-manifest-update \ + --no-restart-on-unexpected \ + --no-fail-on-unexpected \ + --this-chunk=${{ matrix.current-chunk }} \ + --total-chunks=${{ matrix.total-chunks }} \ + --chunk-type hash \ + --log-wptreport ${{ runner.temp }}/wpt_report_${{ matrix.current-chunk }}.json \ + --log-wptscreenshot ${{ runner.temp }}/wpt_screenshot_${{ matrix.current-chunk }}.txt \ + --log-mach - \ + --log-mach-level info \ + --channel ${{ inputs.safari-technology-preview && 'preview' || 'stable' }} \ + --kill-safari \ + --max-restarts 100 \ + safari + - name: Publish results + uses: actions/upload-artifact@v4.1.0 + with: + name: ${{ inputs.artifact-name }}-${{ matrix.current-chunk }} + path: | + ${{ runner.temp }}/wpt_report_*.json + ${{ runner.temp }}/wpt_screenshot_*.txt + if-no-files-found: "error" + - name: Publish safaridriver logs + if: inputs.safaridriver-diagnose + uses: actions/upload-artifact@v4.1.0 + with: + name: ${{ inputs.artifact-name }}-safaridriver-logs-${{ matrix.current-chunk }} + path: ~/Library/Logs/com.apple.WebDriver/ + if-no-files-found: warn + - name: Disable safaridriver diagnostics + if: inputs.safaridriver-diagnose + run: |- + defaults write com.apple.WebDriver DiagnosticsEnabled 0 + rm -rf ~/Library/Logs/com.apple.WebDriver/ + - name: Cleanup + if: always() + run: |- + set -ux + sudo sed -i '' '/^# Start web-platform-tests hosts$/,/^# End web-platform-tests hosts$/d' /etc/hosts + + safari-notify: + needs: safari-results + uses: ./.github/workflows/wpt_fyi_notify.yml + with: + artifact-name: "${{ inputs.artifact-name }}-*" diff --git a/tests/wpt/tests/.github/workflows/safari_stable.yml b/tests/wpt/tests/.github/workflows/safari_stable.yml index 0df13f43d44..7c344fe667f 100644 --- a/tests/wpt/tests/.github/workflows/safari_stable.yml +++ b/tests/wpt/tests/.github/workflows/safari_stable.yml @@ -15,12 +15,6 @@ on: - epochs/daily - triggers/safari_stable -env: - # Set SAFARIDRIVER_DIAGNOSE to true to enable safaridriver diagnostics. The - # logs won't appear in `./wpt run` output but will be uploaded as an - # artifact. - SAFARIDRIVER_DIAGNOSE: false - jobs: check-workflow-run: name: "Check for appropriate epochs" @@ -35,81 +29,8 @@ jobs: needs: check-workflow-run if: | github.event_name != 'workflow_run' || fromJSON(needs.check-workflow-run.outputs.updated-refs)[0] != null - runs-on: - - self-hosted - - webkit-ews - timeout-minutes: 180 - strategy: - matrix: - current-chunk: [1, 2, 3, 4, 5, 6, 7, 8] - total-chunks: [8] - steps: - - name: checkout - uses: actions/checkout@v4.1.0 - with: - fetch-depth: 1 - - name: Enable safaridriver diagnostics - if: env.SAFARIDRIVER_DIAGNOSE == true - run: |- - rm -rf ~/Library/Logs/com.apple.WebDriver/ - defaults write com.apple.WebDriver DiagnosticsEnabled 1 - - name: Enable safaridriver - run: |- - set -eux -o pipefail - sudo safaridriver --enable - - name: Update hosts - run: |- - set -eux -o pipefail - ./wpt make-hosts-file | sudo tee -a /etc/hosts - - name: Update manifest - run: ./wpt manifest - - name: Run tests - run: |- - set -eux -o pipefail - export SYSTEM_VERSION_COMPAT=0 - ./wpt run \ - --no-manifest-update \ - --no-restart-on-unexpected \ - --no-fail-on-unexpected \ - --this-chunk=${{ matrix.current-chunk }} \ - --total-chunks=${{ matrix.total-chunks }} \ - --chunk-type hash \ - --log-wptreport ${{ runner.temp }}/wpt_report_${{ matrix.current-chunk }}.json \ - --log-wptscreenshot ${{ runner.temp }}/wpt_screenshot_${{ matrix.current-chunk }}.txt \ - --log-mach - \ - --log-mach-level info \ - --channel stable \ - --kill-safari \ - --max-restarts 100 \ - safari - - name: Publish results - uses: actions/upload-artifact@v4.1.0 - with: - name: safari-results-${{ matrix.current-chunk }} - path: | - ${{ runner.temp }}/wpt_report_*.json - ${{ runner.temp }}/wpt_screenshot_*.txt - if-no-files-found: "error" - - name: Publish safaridriver logs - if: env.SAFARIDRIVER_DIAGNOSE == true - uses: actions/upload-artifact@v4.1.0 - with: - name: safaridriver-logs-${{ matrix.current-chunk }} - path: ~/Library/Logs/com.apple.WebDriver/ - if-no-files-found: warn - - name: Disable safaridriver diagnostics - if: env.SAFARIDRIVER_DIAGNOSE == true - run: |- - defaults write com.apple.WebDriver DiagnosticsEnabled 0 - rm -rf ~/Library/Logs/com.apple.WebDriver/ - - name: Cleanup - if: always() - run: |- - set -ux - sudo sed -i '' '/^# Start web-platform-tests hosts$/,/^# End web-platform-tests hosts$/d' /etc/hosts - - safari-stable-results-notify: - needs: safari-stable-results - uses: ./.github/workflows/wpt_fyi_notify.yml + uses: ./.github/workflows/safari-wptrunner.yml with: - artifact-name: 'safari-results-*' + artifact-name: "safari-results" + safari-technology-preview: false + safaridriver-diagnose: false diff --git a/tests/wpt/tests/.github/workflows/safari_technology_preview.yml b/tests/wpt/tests/.github/workflows/safari_technology_preview.yml index 01380aa718e..70827a365ac 100644 --- a/tests/wpt/tests/.github/workflows/safari_technology_preview.yml +++ b/tests/wpt/tests/.github/workflows/safari_technology_preview.yml @@ -15,12 +15,6 @@ on: - epochs/three_hourly - triggers/safari_preview -env: - # Set SAFARIDRIVER_DIAGNOSE to true to enable safaridriver diagnostics. The - # logs won't appear in `./wpt run` output but will be uploaded as an - # artifact. - SAFARIDRIVER_DIAGNOSE: false - jobs: check-workflow-run: name: "Check for appropriate epochs" @@ -35,84 +29,8 @@ jobs: needs: check-workflow-run if: | github.event_name != 'workflow_run' || fromJSON(needs.check-workflow-run.outputs.updated-refs)[0] != null - runs-on: - - self-hosted - - webkit-ews - timeout-minutes: 180 - strategy: - matrix: - current-chunk: [1, 2, 3, 4, 5, 6, 7, 8] - total-chunks: [8] - steps: - - name: checkout - uses: actions/checkout@v4.1.0 - with: - fetch-depth: 1 - - name: Enable safaridriver diagnostics - if: env.SAFARIDRIVER_DIAGNOSE == true - run: |- - rm -rf ~/Library/Logs/com.apple.WebDriver/ - defaults write com.apple.WebDriver DiagnosticsEnabled 1 - - name: Enable safaridriver - run: |- - set -eux -o pipefail - export SYSTEM_VERSION_COMPAT=0 - ./wpt install --channel preview --download-only -d . --rename STP safari browser - sudo installer -pkg STP.pkg -target LocalSystem - sudo /Applications/Safari\ Technology\ Preview.app/Contents/MacOS/safaridriver --enable - - name: Update hosts - run: |- - set -eux -o pipefail - ./wpt make-hosts-file | sudo tee -a /etc/hosts - - name: Update manifest - run: ./wpt manifest - - name: Run tests - run: |- - set -eux -o pipefail - export SYSTEM_VERSION_COMPAT=0 - ./wpt run \ - --no-manifest-update \ - --no-restart-on-unexpected \ - --no-fail-on-unexpected \ - --this-chunk=${{ matrix.current-chunk }} \ - --total-chunks=${{ matrix.total-chunks }} \ - --chunk-type hash \ - --log-wptreport ${{ runner.temp }}/wpt_report_${{ matrix.current-chunk }}.json \ - --log-wptscreenshot ${{ runner.temp }}/wpt_screenshot_${{ matrix.current-chunk }}.txt \ - --log-mach - \ - --log-mach-level info \ - --channel experimental \ - --kill-safari \ - --max-restarts 100 \ - safari - - name: Publish results - uses: actions/upload-artifact@v4.1.0 - with: - name: safari-technology-preview-results-${{ matrix.current-chunk }} - path: | - ${{ runner.temp }}/wpt_report_*.json - ${{ runner.temp }}/wpt_screenshot_*.txt - if-no-files-found: "error" - - name: Publish safaridriver logs - if: env.SAFARIDRIVER_DIAGNOSE == true - uses: actions/upload-artifact@v4.1.0 - with: - name: safaridriver-logs-${{ matrix.current-chunk }} - path: ~/Library/Logs/com.apple.WebDriver/ - if-no-files-found: warn - - name: Disable safaridriver diagnostics - if: env.SAFARIDRIVER_DIAGNOSE == true - run: |- - defaults write com.apple.WebDriver DiagnosticsEnabled 0 - rm -rf ~/Library/Logs/com.apple.WebDriver/ - - name: Cleanup - if: always() - run: |- - set -ux - sudo sed -i '' '/^# Start web-platform-tests hosts$/,/^# End web-platform-tests hosts$/d' /etc/hosts - - safari-technology-preview-results-notify: - needs: safari-technology-preview-results - uses: ./.github/workflows/wpt_fyi_notify.yml + uses: ./.github/workflows/safari-wptrunner.yml with: - artifact-name: 'safari-technology-preview-results-*' + artifact-name: "safari-technology-preview-results" + safari-technology-preview: true + safaridriver-diagnose: false diff --git a/tests/wpt/tests/IndexedDB/cursor-overloads.any.js b/tests/wpt/tests/IndexedDB/cursor-overloads.any.js new file mode 100644 index 00000000000..dd80d2f4038 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/cursor-overloads.any.js @@ -0,0 +1,87 @@ +// META: title=IndexedDB +// META: global=window,worker +// META: script=resources/support.js + +'use strict'; + +async_test(t => { + let db; + let trans; + let store; + let index; + let request = createdb(t); + + request.onupgradeneeded = function(e) { + db = e.target.result; + store = db.createObjectStore('store'); + index = store.createIndex('index', 'value'); + store.put({value: 0}, 0); + trans = request.transaction; + trans.oncomplete = verifyOverloads; + }; + + function verifyOverloads() { + trans = db.transaction('store', 'readonly', {durability: 'relaxed'}); + store = trans.objectStore('store'); + index = store.index('index'); + + checkCursorDirection(store.openCursor(), 'next'); + checkCursorDirection(store.openCursor(0), 'next'); + checkCursorDirection(store.openCursor(0, 'next'), 'next'); + checkCursorDirection(store.openCursor(0, 'nextunique'), 'nextunique'); + checkCursorDirection(store.openCursor(0, 'prev'), 'prev'); + checkCursorDirection(store.openCursor(0, 'prevunique'), 'prevunique'); + + checkCursorDirection(store.openCursor(IDBKeyRange.only(0)), 'next'); + checkCursorDirection(store.openCursor(IDBKeyRange.only(0), 'next'), 'next'); + checkCursorDirection( + store.openCursor(IDBKeyRange.only(0), 'nextunique'), 'nextunique'); + checkCursorDirection(store.openCursor(IDBKeyRange.only(0), 'prev'), 'prev'); + checkCursorDirection( + store.openCursor(IDBKeyRange.only(0), 'prevunique'), 'prevunique'); + + checkCursorDirection(index.openCursor(), 'next'); + checkCursorDirection(index.openCursor(0), 'next'); + checkCursorDirection(index.openCursor(0, 'next'), 'next'); + checkCursorDirection(index.openCursor(0, 'nextunique'), 'nextunique'); + checkCursorDirection(index.openCursor(0, 'prev'), 'prev'); + checkCursorDirection(index.openCursor(0, 'prevunique'), 'prevunique'); + + checkCursorDirection(index.openCursor(IDBKeyRange.only(0)), 'next'); + checkCursorDirection(index.openCursor(IDBKeyRange.only(0), 'next'), 'next'); + checkCursorDirection( + index.openCursor(IDBKeyRange.only(0), 'nextunique'), 'nextunique'); + checkCursorDirection(index.openCursor(IDBKeyRange.only(0), 'prev'), 'prev'); + checkCursorDirection( + index.openCursor(IDBKeyRange.only(0), 'prevunique'), 'prevunique'); + + checkCursorDirection(index.openKeyCursor(), 'next'); + checkCursorDirection(index.openKeyCursor(0), 'next'); + checkCursorDirection(index.openKeyCursor(0, 'next'), 'next'); + checkCursorDirection(index.openKeyCursor(0, 'nextunique'), 'nextunique'); + checkCursorDirection(index.openKeyCursor(0, 'prev'), 'prev'); + checkCursorDirection(index.openKeyCursor(0, 'prevunique'), 'prevunique'); + + checkCursorDirection(index.openKeyCursor(IDBKeyRange.only(0)), 'next'); + checkCursorDirection( + index.openKeyCursor(IDBKeyRange.only(0), 'next'), 'next'); + checkCursorDirection( + index.openKeyCursor(IDBKeyRange.only(0), 'nextunique'), 'nextunique'); + checkCursorDirection( + index.openKeyCursor(IDBKeyRange.only(0), 'prev'), 'prev'); + checkCursorDirection( + index.openKeyCursor(IDBKeyRange.only(0), 'prevunique'), 'prevunique'); + + t.done(); + } + + function checkCursorDirection(request, direction) { + request.onsuccess = function(event) { + assert_not_equals( + event.target.result, null, 'Check the result is not null') + assert_equals( + event.target.result.direction, direction, + 'Check the result direction'); + }; + } +}, 'Validate the overloads of IDBObjectStore.openCursor(), IDBIndex.openCursor() and IDBIndex.openKeyCursor()'); diff --git a/tests/wpt/tests/IndexedDB/cursor-overloads.htm b/tests/wpt/tests/IndexedDB/cursor-overloads.htm deleted file mode 100644 index 7beeaa2bb39..00000000000 --- a/tests/wpt/tests/IndexedDB/cursor-overloads.htm +++ /dev/null @@ -1,88 +0,0 @@ -<!-- -Test converted from WebKit: -http://trac.webkit.org/browser/trunk/LayoutTests/storage/indexeddb/cursor-overloads.html ---> - -<!DOCTYPE html> -<!-- Submitted from TestTWF Paris --> -<meta charset=utf-8> -<title>Validate the overloads of IDBObjectStore.openCursor(), IDBIndex.openCursor() and IDBIndex.openKeyCursor()</title> -<link rel=author href="mailto:romain.huet@gmail.com" title="Romain Huet"> - -<script src=/resources/testharness.js></script> -<script src=/resources/testharnessreport.js></script> -<script src=resources/support.js></script> - -<script> - - var db, trans, store, index; - var t = async_test(); - - var request = createdb(t); - request.onupgradeneeded = function(e) { - db = request.result; - store = db.createObjectStore('store'); - index = store.createIndex('index', 'value'); - store.put({value: 0}, 0); - trans = request.transaction; - trans.oncomplete = verifyOverloads; - }; - - function verifyOverloads() { - trans = db.transaction('store', 'readonly', {durability: 'relaxed'}); - store = trans.objectStore('store'); - index = store.index('index'); - - checkCursorDirection("store.openCursor()", "next"); - checkCursorDirection("store.openCursor(0)", "next"); - checkCursorDirection("store.openCursor(0, 'next')", "next"); - checkCursorDirection("store.openCursor(0, 'nextunique')", "nextunique"); - checkCursorDirection("store.openCursor(0, 'prev')", "prev"); - checkCursorDirection("store.openCursor(0, 'prevunique')", "prevunique"); - - checkCursorDirection("store.openCursor(IDBKeyRange.only(0))", "next"); - checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'next')", "next"); - checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique"); - checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'prev')", "prev"); - checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique"); - - checkCursorDirection("index.openCursor()", "next"); - checkCursorDirection("index.openCursor(0)", "next"); - checkCursorDirection("index.openCursor(0, 'next')", "next"); - checkCursorDirection("index.openCursor(0, 'nextunique')", "nextunique"); - checkCursorDirection("index.openCursor(0, 'prev')", "prev"); - checkCursorDirection("index.openCursor(0, 'prevunique')", "prevunique"); - - checkCursorDirection("index.openCursor(IDBKeyRange.only(0))", "next"); - checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'next')", "next"); - checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique"); - checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'prev')", "prev"); - checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique"); - - checkCursorDirection("index.openKeyCursor()", "next"); - checkCursorDirection("index.openKeyCursor(0)", "next"); - checkCursorDirection("index.openKeyCursor(0, 'next')", "next"); - checkCursorDirection("index.openKeyCursor(0, 'nextunique')", "nextunique"); - checkCursorDirection("index.openKeyCursor(0, 'prev')", "prev"); - checkCursorDirection("index.openKeyCursor(0, 'prevunique')", "prevunique"); - - checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0))", "next"); - checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'next')", "next"); - checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique"); - checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'prev')", "prev"); - checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique"); - - t.done(); - } - - function checkCursorDirection(statement, direction) { - request = eval(statement); - request.onsuccess = function(event) { - assert_not_equals(event.target.result, null, "Check the result is not null") - assert_equals(event.target.result.direction, direction, "Check the result direction"); - }; - } - -</script> - -<div id=log></div> diff --git a/tests/wpt/tests/IndexedDB/delete-request-queue.any.js b/tests/wpt/tests/IndexedDB/delete-request-queue.any.js new file mode 100644 index 00000000000..6b2034c7f6b --- /dev/null +++ b/tests/wpt/tests/IndexedDB/delete-request-queue.any.js @@ -0,0 +1,23 @@ +// META: title=IndexedDB +// META: global=window,worker +// META: script=resources/support.js + +'use strict'; + +let saw; +indexeddb_test( + (t, db) => { + this.saw = expect(t, ['delete1', 'delete2']); + let r = indexedDB.deleteDatabase(db.name); + r.onerror = t.unreached_func('delete should succeed'); + r.onsuccess = t.step_func(e => saw('delete1')); + }, + (t, db) => { + let r = indexedDB.deleteDatabase(db.name); + r.onerror = t.unreached_func('delete should succeed'); + r.onsuccess = t.step_func(e => saw('delete2')); + + db.close(); + t.done(); + }, + 'Deletes are processed as a FIFO queue'); diff --git a/tests/wpt/tests/IndexedDB/delete-request-queue.html b/tests/wpt/tests/IndexedDB/delete-request-queue.html deleted file mode 100644 index d8dfbf9a606..00000000000 --- a/tests/wpt/tests/IndexedDB/delete-request-queue.html +++ /dev/null @@ -1,27 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>IndexedDB: delete requests are processed as a FIFO queue</title> -<link rel="help" href="https://w3c.github.io/IndexedDB/#request-connection-queue"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/support.js"></script> -<script> - -let saw; -indexeddb_test( - (t, db) => { - saw = expect(t, ['delete1', 'delete2']); - let r = indexedDB.deleteDatabase(db.name); - r.onerror = t.unreached_func('delete should succeed'); - r.onsuccess = t.step_func(e => saw('delete1')); - }, - (t, db) => { - let r = indexedDB.deleteDatabase(db.name); - r.onerror = t.unreached_func('delete should succeed'); - r.onsuccess = t.step_func(e => saw('delete2')); - - db.close(); - }, - 'Deletes are processed in order'); - -</script> diff --git a/tests/wpt/tests/IndexedDB/error-attributes.any.js b/tests/wpt/tests/IndexedDB/error-attributes.any.js new file mode 100644 index 00000000000..9b5003040b2 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/error-attributes.any.js @@ -0,0 +1,32 @@ +// META: title=IndexedDB +// META: global=window,worker +// META: script=resources/support.js + +'use strict'; + +indexeddb_test( + function(t, db) { + db.createObjectStore('store'); + }, + function(t, db) { + let tx = db.transaction('store', 'readwrite', {durability: 'relaxed'}); + let store = tx.objectStore('store'); + let r1 = store.add('value', 'key'); + r1.onerror = t.unreached_func('first add should succeed'); + + let r2 = store.add('value', 'key'); + r2.onsuccess = t.unreached_func('second add should fail'); + + r2.onerror = t.step_func(function() { + assert_true(r2.error instanceof DOMException); + assert_equals(r2.error.name, 'ConstraintError'); + }); + + tx.oncomplete = t.unreached_func('transaction should not complete'); + tx.onabort = t.step_func(function() { + assert_true(tx.error instanceof DOMException); + assert_equals(tx.error.name, 'ConstraintError'); + t.done(); + }); + }, + 'IDBRequest and IDBTransaction error properties should be DOMExceptions'); diff --git a/tests/wpt/tests/IndexedDB/error-attributes.html b/tests/wpt/tests/IndexedDB/error-attributes.html deleted file mode 100644 index d65bf21790a..00000000000 --- a/tests/wpt/tests/IndexedDB/error-attributes.html +++ /dev/null @@ -1,38 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>IndexedDB: Error attributes are DOMExceptions</title> -<link rel="help" href="https://w3c.github.io/IndexedDB/#idbrequest"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/support.js"></script> -<script> - -indexeddb_test( - function(t, db) { - db.createObjectStore('store'); - }, - function(t, db) { - var tx = db.transaction('store', 'readwrite', {durability: 'relaxed'}); - var store = tx.objectStore('store'); - var r1 = store.add('value', 'key'); - r1.onerror = t.unreached_func('first add should succeed'); - - var r2 = store.add('value', 'key'); - r2.onsuccess = t.unreached_func('second add should fail'); - - r2.onerror = t.step_func(function() { - assert_true(r2.error instanceof DOMException); - assert_equals(r2.error.name, 'ConstraintError'); - }); - - tx.oncomplete = t.unreached_func('transaction should not complete'); - tx.onabort = t.step_func(function() { - assert_true(tx.error instanceof DOMException); - assert_equals(tx.error.name, 'ConstraintError'); - t.done(); - }); - }, - 'IDBRequest and IDBTransaction error properties should be DOMExceptions' -); - -</script> diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-deactivation-timing.any.js b/tests/wpt/tests/IndexedDB/upgrade-transaction-deactivation-timing.any.js new file mode 100644 index 00000000000..d11f821201c --- /dev/null +++ b/tests/wpt/tests/IndexedDB/upgrade-transaction-deactivation-timing.any.js @@ -0,0 +1,46 @@ +// META: title=Upgrade transaction deactivation timing +// META: global=window,worker +// META: script=resources/support.js +// META: script=resources/support-promises.js + +// Spec: "https://w3c.github.io/IndexedDB/#upgrade-transaction-steps" + +'use strict'; + +indexeddb_test( + (t, db, tx) => { + db.createObjectStore('store'); + assert_true(is_transaction_active(tx, 'store'), + 'Transaction should be active in upgradeneeded callback'); + }, + (t, db) => { t.done(); }, + 'Upgrade transactions are active in upgradeneeded callback'); + +indexeddb_test( + (t, db, tx) => { + db.createObjectStore('store'); + assert_true(is_transaction_active(tx, 'store'), + 'Transaction should be active in upgradeneeded callback'); + + Promise.resolve().then(t.step_func(() => { + assert_true(is_transaction_active(tx, 'store'), + 'Transaction should be active in microtask checkpoint'); + })); + }, + (t, db) => { t.done(); }, + 'Upgrade transactions are active in upgradeneeded callback and microtasks'); + + +indexeddb_test( + (t, db, tx) => { + db.createObjectStore('store'); + const release_tx = keep_alive(tx, 'store'); + + setTimeout(t.step_func(() => { + assert_false(is_transaction_active(tx, 'store'), + 'Transaction should be inactive in next task'); + release_tx(); + }), 0); + }, + (t, db) => { t.done(); }, + 'Upgrade transactions are deactivated before next task');
\ No newline at end of file diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-deactivation-timing.html b/tests/wpt/tests/IndexedDB/upgrade-transaction-deactivation-timing.html deleted file mode 100644 index 8119c9ab261..00000000000 --- a/tests/wpt/tests/IndexedDB/upgrade-transaction-deactivation-timing.html +++ /dev/null @@ -1,48 +0,0 @@ -<!DOCTYPE html> -<meta charset=utf-8> -<title>Upgrade transaction deactivation timing</title> -<link rel="help" href="http://localhost:4201/#upgrade-transaction-steps"> -<script src=/resources/testharness.js></script> -<script src=/resources/testharnessreport.js></script> -<script src=resources/support.js></script> -<script> - -indexeddb_test( - (t, db, tx) => { - db.createObjectStore('store'); - assert_true(is_transaction_active(tx, 'store'), - 'Transaction should be active in upgradeneeded callback'); - }, - (t, db) => { t.done(); }, - 'Upgrade transactions are active in upgradeneeded callback'); - -indexeddb_test( - (t, db, tx) => { - db.createObjectStore('store'); - assert_true(is_transaction_active(tx, 'store'), - 'Transaction should be active in upgradeneeded callback'); - - Promise.resolve().then(t.step_func(() => { - assert_true(is_transaction_active(tx, 'store'), - 'Transaction should be active in microtask checkpoint'); - })); - }, - (t, db) => { t.done(); }, - 'Upgrade transactions are active in upgradeneeded callback and microtasks'); - - -indexeddb_test( - (t, db, tx) => { - db.createObjectStore('store'); - const release_tx = keep_alive(tx, 'store'); - - setTimeout(t.step_func(() => { - assert_false(is_transaction_active(tx, 'store'), - 'Transaction should be inactive in next task'); - release_tx(); - }), 0); - }, - (t, db) => { t.done(); }, - 'Upgrade transactions are deactivated before next task'); - -</script> diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.js b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.js new file mode 100644 index 00000000000..841a83c6e0d --- /dev/null +++ b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.any.js @@ -0,0 +1,76 @@ +// META: title=IndexedDB: backend-aborted versionchange transaction lifecycle +// META: global=window,worker +// META: script=resources/support.js +// META: script=resources/support-promises.js + +// Spec: "https://w3c.github.io/IndexedDB/#upgrade-transaction-steps" +// "https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore" +// "https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore" +'use strict'; + +promise_test(t => { + return createDatabase(t, database => { + createBooksStore(t, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { + return new Promise((resolve, reject) => { + transaction.addEventListener('abort', () => { + resolve(new Promise((resolve, reject) => { + assert_equals( + request.transaction, transaction, + "The open request's transaction should be reset after onabort"); + assert_throws_dom( + 'InvalidStateError', + () => { database.createObjectStore('books2'); }, + 'createObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + assert_throws_dom( + 'InvalidStateError', + () => { database.deleteObjectStore('books'); }, + 'deleteObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + resolve(); + })); + }, false); + transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); + transaction._willBeAborted(); + }); + })); +}, 'in the abort event handler for a transaction aborted due to an unhandled ' + +'request error'); + +promise_test(t => { + return createDatabase(t, database => { + createBooksStore(t, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { + return new Promise((resolve, reject) => { + transaction.addEventListener('abort', () => { + setTimeout(() => { + resolve(new Promise((resolve, reject) => { + assert_equals( + request.transaction, null, + "The open request's transaction should be reset after " + + 'onabort microtasks'); + assert_throws_dom( + 'InvalidStateError', + () => { database.createObjectStore('books2'); }, + 'createObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + assert_throws_dom( + 'InvalidStateError', + () => { database.deleteObjectStore('books'); }, + 'deleteObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + resolve(); + })); + }, 0); + }, false); + transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); + transaction._willBeAborted(); + }); + })); +}, 'in a setTimeout(0) callback after the abort event is fired for a ' + +'transaction aborted due to an unhandled request failure');
\ No newline at end of file diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.html b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.html deleted file mode 100644 index 862e85144d6..00000000000 --- a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.html +++ /dev/null @@ -1,84 +0,0 @@ -<!doctype html> -<meta charset="utf8"> -<title>IndexedDB: backend-aborted versionchange transaction lifecycle</title> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#upgrade-transaction-steps"> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore"> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore"> -<link rel="author" href="pwnall@chromium.org" title="Victor Costan"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/support-promises.js"></script> -<script> -'use strict'; - -promise_test(t => { - return createDatabase(t, database => { - createBooksStore(t, database); - }).then(database => { - database.close(); - }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { - return new Promise((resolve, reject) => { - transaction.addEventListener('abort', () => { - resolve(new Promise((resolve, reject) => { - assert_equals( - request.transaction, transaction, - "The open request's transaction should be reset after onabort"); - assert_throws_dom( - 'InvalidStateError', - () => { database.createObjectStore('books2'); }, - 'createObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - assert_throws_dom( - 'InvalidStateError', - () => { database.deleteObjectStore('books'); }, - 'deleteObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - resolve(); - })); - }, false); - transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); - transaction._willBeAborted(); - }); - })); -}, 'in the abort event handler for a transaction aborted due to an unhandled ' + - 'request error'); - -promise_test(t => { - return createDatabase(t, database => { - createBooksStore(t, database); - }).then(database => { - database.close(); - }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { - return new Promise((resolve, reject) => { - transaction.addEventListener('abort', () => { - setTimeout(() => { - resolve(new Promise((resolve, reject) => { - assert_equals( - request.transaction, null, - "The open request's transaction should be reset after " + - 'onabort microtasks'); - assert_throws_dom( - 'InvalidStateError', - () => { database.createObjectStore('books2'); }, - 'createObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - assert_throws_dom( - 'InvalidStateError', - () => { database.deleteObjectStore('books'); }, - 'deleteObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - resolve(); - })); - }, 0); - }, false); - transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); - transaction._willBeAborted(); - }); - })); -}, 'in a setTimeout(0) callback after the abort event is fired for a ' + - 'transaction aborted due to an unhandled request failure'); - -</script> diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-committed.any.js b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-committed.any.js new file mode 100644 index 00000000000..85b447ea951 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-committed.any.js @@ -0,0 +1,73 @@ +// META: title=IndexedDB: committed versionchange transaction lifecycle +// META: global=window,worker +// META: script=resources/support.js +// META: script=resources/support-promises.js + +// Spec: "https://w3c.github.io/IndexedDB/#upgrade-transaction-steps" +// "https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore" +// "https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore" + +'use strict'; + +promise_test(t => { + return createDatabase(t, database => { + createBooksStore(t, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { + return new Promise((resolve, reject) => { + transaction.addEventListener('complete', () => { + resolve(new Promise((resolve, reject) => { + assert_equals( + request.transaction, transaction, + "The open request's transaction should be reset after " + + 'oncomplete'); + assert_throws_dom( + 'InvalidStateError', + () => { database.createObjectStore('books2'); }, + 'createObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + assert_throws_dom( + 'InvalidStateError', + () => { database.deleteObjectStore('books'); }, + 'deleteObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + resolve(); + })); + }, false); + }); + })).then(database => { database.close(); }); +}, 'in the complete event handler for a committed transaction'); + +promise_test(t => { + return createDatabase(t, database => { + createBooksStore(t, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { + return new Promise((resolve, reject) => { + transaction.addEventListener('complete', () => { + setTimeout(() => { + resolve(new Promise((resolve, reject) => { + assert_equals( + request.transaction, null, + "The open request's transaction should be reset after " + + 'oncomplete microtasks'); + assert_throws_dom( + 'InvalidStateError', + () => { database.createObjectStore('books2'); }, + 'createObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + assert_throws_dom( + 'InvalidStateError', + () => { database.deleteObjectStore('books'); }, + 'deleteObjectStore exception should reflect that the ' + + 'transaction is no longer running'); + resolve(); + })); + }, 0); + }, false); + }); + })).then(database => { database.close(); }); +}, 'in a setTimeout(0) callback after the complete event is fired for a ' + +'committed transaction');
\ No newline at end of file diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-committed.html b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-committed.html deleted file mode 100644 index 347d940aeef..00000000000 --- a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-committed.html +++ /dev/null @@ -1,80 +0,0 @@ -<!doctype html> -<meta charset="utf8"> -<title>IndexedDB: committed versionchange transaction lifecycle</title> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#upgrade-transaction-steps"> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore"> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore"> -<link rel="author" href="pwnall@chromium.org" title="Victor Costan"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/support-promises.js"></script> -<script> -'use strict'; - -promise_test(t => { - return createDatabase(t, database => { - createBooksStore(t, database); - }).then(database => { - database.close(); - }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { - return new Promise((resolve, reject) => { - transaction.addEventListener('complete', () => { - resolve(new Promise((resolve, reject) => { - assert_equals( - request.transaction, transaction, - "The open request's transaction should be reset after " + - 'oncomplete'); - assert_throws_dom( - 'InvalidStateError', - () => { database.createObjectStore('books2'); }, - 'createObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - assert_throws_dom( - 'InvalidStateError', - () => { database.deleteObjectStore('books'); }, - 'deleteObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - resolve(); - })); - }, false); - }); - })).then(database => { database.close(); }); -}, 'in the complete event handler for a committed transaction'); - -promise_test(t => { - return createDatabase(t, database => { - createBooksStore(t, database); - }).then(database => { - database.close(); - }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { - return new Promise((resolve, reject) => { - transaction.addEventListener('complete', () => { - setTimeout(() => { - resolve(new Promise((resolve, reject) => { - assert_equals( - request.transaction, null, - "The open request's transaction should be reset after " + - 'oncomplete microtasks'); - assert_throws_dom( - 'InvalidStateError', - () => { database.createObjectStore('books2'); }, - 'createObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - assert_throws_dom( - 'InvalidStateError', - () => { database.deleteObjectStore('books'); }, - 'deleteObjectStore exception should reflect that the ' + - 'transaction is no longer running'); - resolve(); - })); - }, 0); - }, false); - }); - })).then(database => { database.close(); }); -}, 'in a setTimeout(0) callback after the complete event is fired for a ' + - 'committed transaction'); - -</script> diff --git a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-user-aborted.html b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-user-aborted.any.js index 4094ce34f34..4346e1a675d 100644 --- a/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-user-aborted.html +++ b/tests/wpt/tests/IndexedDB/upgrade-transaction-lifecycle-user-aborted.any.js @@ -1,17 +1,12 @@ -<!doctype html> -<meta charset="utf8"> -<title>IndexedDB: user-abort()ed versionchange transaction lifecycle</title> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#upgrade-transaction-steps"> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore"> -<link rel="help" - href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore"> -<link rel="author" href="pwnall@chromium.org" title="Victor Costan"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/support-promises.js"></script> -<script> +// META: title=IndexedDB: user-abort()ed versionchange transaction lifecycle +// META: global=window,worker +// META: script=resources/support.js +// META: script=resources/support-promises.js + +// Spec: "https://w3c.github.io/IndexedDB/#upgrade-transaction-steps" +// "https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore" +// "https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore" + 'use strict'; promise_test(t => { @@ -138,6 +133,4 @@ promise_test(t => { }); })); }, 'in a setTimeout(0) callback after the abort event is fired for a ' + - 'transaction aborted due to an abort() call'); - -</script> + 'transaction aborted due to an abort() call');
\ No newline at end of file diff --git a/tests/wpt/tests/WebCryptoAPI/import_export/okp_importKey.js b/tests/wpt/tests/WebCryptoAPI/import_export/okp_importKey.js index 5699341d9e4..0e6a016fe20 100644 --- a/tests/wpt/tests/WebCryptoAPI/import_export/okp_importKey.js +++ b/tests/wpt/tests/WebCryptoAPI/import_export/okp_importKey.js @@ -40,51 +40,55 @@ function runTests(algorithmName) { // Test importKey with a given key format and other parameters. If // extrable is true, export the key and verify that it matches the input. function testFormat(format, algorithm, keyData, keySize, usages, extractable) { - promise_test(function(test) { - return subtle.importKey(format, keyData[format], algorithm, extractable, usages). - then(function(key) { - assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); - assert_goodCryptoKey(key, algorithm, extractable, usages, (format === 'pkcs8' || (format === 'jwk' && keyData[format].d)) ? 'private' : 'public'); - if (!extractable) { - return; - } + [algorithm, algorithm.name].forEach((alg) => { + promise_test(function(test) { + return subtle.importKey(format, keyData[format], alg, extractable, usages). + then(function(key) { + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); + assert_goodCryptoKey(key, algorithm, extractable, usages, (format === 'pkcs8' || (format === 'jwk' && keyData[format].d)) ? 'private' : 'public'); + if (!extractable) { + return; + } - return subtle.exportKey(format, key). - then(function(result) { - if (format !== "jwk") { - assert_true(equalBuffers(keyData[format], result), "Round trip works"); - } else { - assert_true(equalJwk(keyData[format], result), "Round trip works"); - } - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData[format], algorithm, extractable, usages)); + return subtle.exportKey(format, key). + then(function(result) { + if (format !== "jwk") { + assert_true(equalBuffers(keyData[format], result), "Round trip works"); + } else { + assert_true(equalJwk(keyData[format], result), "Round trip works"); + } + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData[format], alg, extractable, usages)); + }); } // Test importKey/exportKey "alg" behaviours, alg is ignored upon import and alg is missing for Ed25519 and Ed448 JWK export // https://github.com/WICG/webcrypto-secure-curves/pull/24 function testJwkAlgBehaviours(algorithm, keyData, crv, usages) { - promise_test(function(test) { - return subtle.importKey('jwk', { ...keyData, alg: 'this is ignored' }, algorithm, true, usages). - then(function(key) { - assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); - - return subtle.exportKey('jwk', key). - then(function(result) { - assert_equals(Object.keys(result).length, keyData.d ? 6 : 5, "Correct number of JWK members"); - assert_equals(result.alg, undefined, 'No JWK "alg" member is present'); - assert_true(equalJwk(keyData, result), "Round trip works"); - }, function(err) { + [algorithm, algorithm.name].forEach((alg) => { + promise_test(function(test) { + return subtle.importKey('jwk', { ...keyData, alg: 'this is ignored' }, alg, true, usages). + then(function(key) { + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); + + return subtle.exportKey('jwk', key). + then(function(result) { + assert_equals(Object.keys(result).length, keyData.d ? 6 : 5, "Correct number of JWK members"); + assert_equals(result.alg, undefined, 'No JWK "alg" member is present'); + assert_true(equalJwk(keyData, result), "Round trip works"); + }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, "Good parameters with ignored JWK alg: " + crv.toString() + " " + parameterString('jwk', keyData, algorithm, true, usages)); + }); + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, "Good parameters with ignored JWK alg: " + crv.toString() + " " + parameterString('jwk', keyData, alg, true, usages)); + }); } diff --git a/tests/wpt/tests/attribution-reporting/aggregatable-report-no-contributions.sub.https.html b/tests/wpt/tests/attribution-reporting/aggregatable-report-no-contributions.sub.https.html index b42a61b7bd5..b84f1905626 100644 --- a/tests/wpt/tests/attribution-reporting/aggregatable-report-no-contributions.sub.https.html +++ b/tests/wpt/tests/attribution-reporting/aggregatable-report-no-contributions.sub.https.html @@ -14,7 +14,6 @@ attribution_reporting_promise_test(async t => { registerAttributionSrcByImg(createRedirectChain([ { - cookie: attributionDebugCookie, source: { aggregation_keys: { campaignCounts: '0x159', diff --git a/tests/wpt/tests/attribution-reporting/resources/helpers.js b/tests/wpt/tests/attribution-reporting/resources/helpers.js index 0f20a71237c..56e2a2812b6 100644 --- a/tests/wpt/tests/attribution-reporting/resources/helpers.js +++ b/tests/wpt/tests/attribution-reporting/resources/helpers.js @@ -35,8 +35,6 @@ const verboseDebugReportsUrl = const aggregatableDebugReportsUrl = '/.well-known/attribution-reporting/debug/report-aggregate-debug'; -const attributionDebugCookie = 'ar_debug=1;Secure;HttpOnly;SameSite=None;Path=/'; - const pipeHeaderPattern = /[,)]/g; // , and ) in pipe values must be escaped with \ @@ -86,7 +84,7 @@ const redirectReportsTo = origin => { ]); }; -const getFetchParams = (origin, cookie) => { +const getFetchParams = (origin) => { let credentials; const headers = []; @@ -95,25 +93,10 @@ const getFetchParams = (origin, cookie) => { } // https://fetch.spec.whatwg.org/#http-cors-protocol - - const allowOriginHeader = 'Access-Control-Allow-Origin'; - - if (cookie) { - credentials = 'include'; - headers.push({ - name: 'Access-Control-Allow-Credentials', - value: 'true', - }); - headers.push({ - name: allowOriginHeader, - value: `${location.origin}`, - }); - } else { - headers.push({ - name: allowOriginHeader, - value: '*', - }); - } + headers.push({ + name: 'Access-Control-Allow-Origin', + value: '*', + }); return {credentials, headers}; }; @@ -127,7 +110,7 @@ const createRedirectChain = (redirects) => { let redirectTo; for (let i = redirects.length - 1; i >= 0; i--) { - const {source, trigger, cookie, reportingOrigin} = redirects[i]; + const {source, trigger, reportingOrigin} = redirects[i]; const headers = []; if (source) { @@ -144,10 +127,6 @@ const createRedirectChain = (redirects) => { }); } - if (cookie) { - headers.push({name: 'Set-Cookie', value: cookie}); - } - let status; if (redirectTo) { headers.push({name: 'Location', value: redirectTo.toString()}); @@ -169,7 +148,6 @@ const registerAttributionSrcByImg = (attributionSrc) => { const registerAttributionSrc = ({ source, trigger, - cookie, method = 'img', extraQueryParams = {}, reportingOrigin, @@ -200,14 +178,9 @@ const registerAttributionSrc = ({ }); } - if (cookie) { - const name = 'Set-Cookie'; - headers.push({name, value: cookie}); - } - let credentials; if (method === 'fetch') { - const params = getFetchParams(reportingOrigin, cookie); + const params = getFetchParams(reportingOrigin); credentials = params.credentials; headers = headers.concat(params.headers); } diff --git a/tests/wpt/tests/attribution-reporting/simple-verbose-debug-report.sub.https.html b/tests/wpt/tests/attribution-reporting/simple-verbose-debug-report.sub.https.html index 8a477f732f4..cc2e37cae8e 100644 --- a/tests/wpt/tests/attribution-reporting/simple-verbose-debug-report.sub.https.html +++ b/tests/wpt/tests/attribution-reporting/simple-verbose-debug-report.sub.https.html @@ -11,7 +11,6 @@ attribution_reporting_promise_test(async t => { registerAttributionSrcByImg(createRedirectChain([ { - cookie: attributionDebugCookie, trigger: { debug_reporting: true, debug_key: expectedTriggerDebugKey, diff --git a/tests/wpt/tests/clipboard-apis/async-navigator-clipboard-basics.https.html b/tests/wpt/tests/clipboard-apis/async-navigator-clipboard-basics.https.html index 5d6f701bdb7..f7aed80b17e 100644 --- a/tests/wpt/tests/clipboard-apis/async-navigator-clipboard-basics.https.html +++ b/tests/wpt/tests/clipboard-apis/async-navigator-clipboard-basics.https.html @@ -28,13 +28,51 @@ promise_test(async t => { await getPermissions(); const text_plain = "This text was copied using `Clipboard.prototype.write`."; const html_text = "<p style='color: red; font-style: oblique;'>Test</p>"; - await promise_rejects_dom(t, "NotAllowedError", navigator.clipboard.write([ + await navigator.clipboard.write([ new ClipboardItem({ "text/plain": text_plain, "text/html" : html_text }), - ])); - }, 'navigator.clipboard.write(Promise<DOMString>) fails'); + ]); + }, 'navigator.clipboard.write(DOMString) succeeds'); + +promise_test(async () => { + await getPermissions(); + const promise_text_string = Promise.resolve('hello'); + const promise_html_string = Promise.resolve("<p style='color: red; font-style: oblique;'>hello</p>"); + const item = new ClipboardItem({ + 'text/plain': promise_text_string, + 'text/html': promise_html_string + }); + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write(Promise<DOMString>) succeeds'); + +promise_test(async t => { + await getPermissions(); + const text_plain = 'hello'; + const html_text = "<p style='color: red; font-style: oblique;'>hello</p>"; + const image = await fetch("/clipboard-apis/resources/greenbox.png"); + const item = new ClipboardItem({ + 'text/plain': text_plain, + 'text/html': new Blob([html_text], {type: 'text/html'}), + 'image/png': image.blob(), // Promise<Blob> + 'web text/csv': 'hello,world' + }); + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write(web_custom_format) succeeds'); + +promise_test(async () => { + await getPermissions(); + const html_text = "<p style='color: red; font-style: oblique;'>Test</p>"; + const item = new ClipboardItem({ + 'text/plain': 'hello', + 'text/html': new Blob([html_text], {type: 'text/html'}) + }); + const text = await item.getType('text/plain'); + const blob = await item.getType('text/html'); + assert_true(text instanceof Blob, "item.getType('text/plain') didn't return a Blob"); + assert_true(blob instanceof Blob, "item.getType('text/html') didn't return a Blob"); +}, 'validate GetType(type) on a contructed ClipboardItem returns Blob'); promise_test(async () => { await getPermissions(); diff --git a/tests/wpt/tests/close-watcher/user-activation/y-dialog-disconnected.html b/tests/wpt/tests/close-watcher/user-activation/y-dialog-disconnected.html new file mode 100644 index 00000000000..0bd41b5bb24 --- /dev/null +++ b/tests/wpt/tests/close-watcher/user-activation/y-dialog-disconnected.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=author href="mailto:wpt@keithcirkel.co.uk"> +<link rel=help href="https://github.com/whatwg/html/pull/9462"> +<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/testdriver-actions.js"></script> +<script src="../resources/helpers.js"></script> + +<button id=b0>b0</button> + +<dialog id=d1> + <button id=b1>b1</button> + + <dialog id=d2>d2</dialog> +</dialog> + +<script> +promise_test(async () => { + const d1 = document.getElementById('d1'); + const d2 = document.getElementById('d2'); + await test_driver.click(b0); + d1.showModal(); + await test_driver.click(b1); + d2.showModal(); + + assert_true(d1.matches(':modal'), 'd1 should be open.'); + assert_true(d2.matches(':modal'), 'd2 should be open.'); + + d2.remove() + + assert_false(d2.matches(':modal'), 'd2 should now be closed.'); + await sendCloseRequest(); + assert_false(d2.matches(':modal'), 'd2 still now be closed.'); + assert_false(d1.matches(':modal'), 'd1 should now be closed.'); + + await sendCloseRequest(); + assert_false(d2.matches(':modal'), 'd2 still now be closed.'); + assert_false(d1.matches(':modal'), 'd1 still now be closed.'); +}, 'Disconnect dialog with close request'); +</script> diff --git a/tests/wpt/tests/close-watcher/user-activation/y-popover-disconnected.html b/tests/wpt/tests/close-watcher/user-activation/y-popover-disconnected.html new file mode 100644 index 00000000000..22fbdbfe73b --- /dev/null +++ b/tests/wpt/tests/close-watcher/user-activation/y-popover-disconnected.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=author href="mailto:wpt@keithcirkel.co.uk"> +<link rel=help href="https://github.com/whatwg/html/pull/9462"> +<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/testdriver-actions.js"></script> +<script src="../resources/helpers.js"></script> + +<button id=b0>b0</button> + +<div id=p1 popover=auto> + <button id=b1>b1</button> + + <div id=p2 popover=auto>p2</div> +</div> + +<script> +promise_test(async () => { + const p1 = document.getElementById('p1'); + const p2 = document.getElementById('p2'); + await test_driver.click(b0); + p1.showPopover(); + await test_driver.click(b1); + p2.showPopover(); + + assert_true(p1.matches(':popover-open'), 'p1 should be open.'); + assert_true(p2.matches(':popover-open'), 'p2 should be open.'); + + p2.remove() + + assert_false(p2.matches(':popover-open'), 'p2 should now be closed.'); + await sendCloseRequest(); + assert_false(p2.matches(':popover-open'), 'p2 still now be closed.'); + assert_false(p1.matches(':popover-open'), 'p1 should now be closed.'); + + await sendCloseRequest(); + assert_false(p2.matches(':popover-open'), 'p2 still now be closed.'); + assert_false(p1.matches(':popover-open'), 'p1 still now be closed.'); +}, 'Disconnect popover with close request'); +</script> diff --git a/tests/wpt/tests/css/CSS2/ui/overflow-applies-to-009.xht b/tests/wpt/tests/css/CSS2/ui/overflow-applies-to-009.xht index 5867a68b7a5..1a82a080654 100644 --- a/tests/wpt/tests/css/CSS2/ui/overflow-applies-to-009.xht +++ b/tests/wpt/tests/css/CSS2/ui/overflow-applies-to-009.xht @@ -12,7 +12,7 @@ <meta name="assert" content="The 'overflow' property applies to elements with 'display' set to 'block'." /> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style type="text/css"> - span + #blockoverflow { border: 5px solid transparent; color: white; @@ -30,7 +30,7 @@ <body> <p>Test passes if there is <strong>no red</strong>.</p> <div> - <span><b>XXXXX</b><b id="test">XXXXX</b></span> + <span id="blockoverflow"><span>XXXXX</span><span id="test">XXXXX</span></span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/css-align/blocks/justify-self-block-in-inline.html b/tests/wpt/tests/css/css-align/blocks/justify-self-block-in-inline.html index 3a326016bc1..0a3facf3ef7 100644 --- a/tests/wpt/tests/css/css-align/blocks/justify-self-block-in-inline.html +++ b/tests/wpt/tests/css/css-align/blocks/justify-self-block-in-inline.html @@ -1,5 +1,6 @@ <!DOCTYPE html> -<link rel="help" href="https://drafts.csswg.org/css-align-3/#justify-abspos"> +<link rel="help" href="https://drafts.csswg.org/css-align/#justify-self-property"> +<link rel="help" href="https://crbug.com/374034249"> <meta name="assert" content="block-in-inline width is stretched to its parent width, not sized as 'fit-content'" /> @@ -24,4 +25,13 @@ <span class="inline-block" style="width: 100px;">inline-block</span> </div> +<div style="width: 100px; justify-self: left;"> + <span> + <div class="block-in-inline" + style="height: 100px; background: green;" + data-expected-width="100"> + </div> + </span> +</div> + <script>checkLayout('.block-in-inline')</script> 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 147aef8c764..47cb3b8d86a 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 @@ -37,9 +37,7 @@ </style> <script> function inflate(t, template_element) { - if (!template_element.hasAttribute('debug')) { - t.add_cleanup(() => main.replaceChildren()); - } + t.add_cleanup(() => main.replaceChildren()); main.append(template_element.content.cloneNode(true)); } </script> @@ -47,6 +45,32 @@ <main id=main> </main> +<template id=test_inclusive_subtree> + <div class="scope-a anchor-a"> <!--A--> + <div class=anchored-a></div> + </div> +</template> +<script> + test((t) => { + inflate(t, test_inclusive_subtree); + assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '10px'); + }, 'Can anchor to a name both defined and scoped by the same element'); +</script> + +<template id=test_skips_named_anchor_with_scope> + <div class="anchor-a"></div> + <div class="anchor-a"></div> + <div class="anchor-a"></div> <!--A--> + <div class="scope-a anchor-a"></div> + <div class=anchored-a></div> +</template> +<script> + test((t) => { + inflate(t, test_skips_named_anchor_with_scope); + assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '30px'); + }, 'Sibling can not anchor into anchor-scope, even when anchor-name present'); +</script> + <template id=test_scope_all_common_ancestor> <div class=scope-all> <div class=anchor-a></div> diff --git a/tests/wpt/tests/css/css-anchor-position/try-tactic-wm.html b/tests/wpt/tests/css/css-anchor-position/try-tactic-wm.html index 8dcf98f8939..69d9c2dff88 100644 --- a/tests/wpt/tests/css/css-anchor-position/try-tactic-wm.html +++ b/tests/wpt/tests/css/css-anchor-position/try-tactic-wm.html @@ -46,6 +46,10 @@ // Effectively flips top:20px to bottom:20px: test_try_tactic_wm('flip-inline', 'vertical-lr', 'ltr', {left:10, top:340, width:30, height:40}); + test_try_tactic_wm('flip-inline', 'sideways-lr', 'ltr', {left:10, top:340, width:30, height:40}); + + // Effectively flips left:10px to right:10px: + test_try_tactic_wm('flip-block', 'sideways-rl', 'ltr', {left:360, top:20, width:30, height:40}); // Mirror across the [left,top]=>[bottom,right] diagonal: test_try_tactic_wm('flip-start', 'horizontal-tb', 'ltr', {left:20, top:10, width:40, height:30}); diff --git a/tests/wpt/tests/css/css-break/text-indent-and-wide-float.html b/tests/wpt/tests/css/css-break/text-indent-and-wide-float.html new file mode 100644 index 00000000000..59885e7c2c0 --- /dev/null +++ b/tests/wpt/tests/css/css-break/text-indent-and-wide-float.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="http://crbug.com/365814218"> +<meta name="assert" content="Floats are not part of lines, so if a float is too wide to fit any inline content beside it, the first formatted line goes below it, or even into the next fragmentainer if there's insufficient room below."> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width:100px; height:100px; background:red;"> + <div style="columns:2; column-fill:auto; gap:0; height:110px; font:25px/25px Ahem; text-indent:25px;"> + <span style="color:green;"> + <div style="float:left; width:100%; height:100px; background:green;"> + <!-- Bleed into the next column, to cover the text indentation there. --> + <div style="width:150%; height:25px; background:green;"></div> + </div> + x xx xx xx + </span> + </div> +</div> diff --git a/tests/wpt/tests/css/css-break/transform-025.html b/tests/wpt/tests/css/css-break/transform-025.html new file mode 100644 index 00000000000..58020065dc1 --- /dev/null +++ b/tests/wpt/tests/css/css-break/transform-025.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#transforms"> +<link rel="help" href="https://crbug.com/40501131"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="display:flow-root; writing-mode:sideways-rl; width:100px; height:100px; background:red;"> + <div style="columns:3; column-fill:auto; gap:0; inline-size:150px; block-size:100px; margin-block-start:100px; margin-inline-start:-50px;"> + <div style="transform:rotate(180deg); transform-origin:middle left; block-size:77px;"> + <div style="position:absolute; inset-block-start:100px; inline-size:100%; block-size:200px; background:green;"></div> + </div> + </div> +</div> diff --git a/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html b/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html index 8407e527017..23ee07d177a 100644 --- a/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html +++ b/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html @@ -120,12 +120,12 @@ // Testing with 'none'. Missing components are resolved to zero during color space conversion. // https://drafts.csswg.org/css-color-4/#missing - fuzzy_test_computed_color(`rgb(from rebeccapurple none none none)`, `color(srgb 0 0 0)`); - fuzzy_test_computed_color(`rgb(from rebeccapurple none none none / none)`, `color(srgb 0 0 0 / none)`); - fuzzy_test_computed_color(`rgb(from rebeccapurple r g none)`, `color(srgb 0.4 0.2 0)`); - fuzzy_test_computed_color(`rgb(from rebeccapurple r g none / alpha)`, `color(srgb 0.4 0.2 0)`); + fuzzy_test_computed_color(`rgb(from rebeccapurple none none none)`, `color(srgb none none none)`); + fuzzy_test_computed_color(`rgb(from rebeccapurple none none none / none)`, `color(srgb none none none / none)`); + fuzzy_test_computed_color(`rgb(from rebeccapurple r g none)`, `color(srgb 0.4 0.2 none)`); + fuzzy_test_computed_color(`rgb(from rebeccapurple r g none / alpha)`, `color(srgb 0.4 0.2 none)`); fuzzy_test_computed_color(`rgb(from rebeccapurple r g b / none)`, `color(srgb 0.4 0.2 0.6 / none)`); - fuzzy_test_computed_color(`rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)`, `color(srgb 0.2 0.4 0 / 0.8)`); + fuzzy_test_computed_color(`rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)`, `color(srgb 0.2 0.4 none / 0.8)`); fuzzy_test_computed_color(`rgb(from rgb(20% 40% 60% / 80%) r g b / none)`, `color(srgb 0.2 0.4 0.6 / none)`); fuzzy_test_computed_color(`rgb(from rgb(none none none) r g b)`, `color(srgb 0 0 0)`); fuzzy_test_computed_color(`rgb(from rgb(none none none / none) r g b / alpha)`, `color(srgb 0 0 0 / 0)`); @@ -145,6 +145,10 @@ // Nesting combined with 'currentColor' fuzzy_test_computed_color_using_currentcolor(`rgb(from rgb(from currentColor r g b) r g b)`, `color(srgb 0.4 0.2 0.6)`, `rebeccapurple`); + // Nesting inside light-dark() + fuzzy_test_computed_color(`light-dark(rgb(from rebeccapurple r g b), rgb(from rebeccapurple r g b))`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_computed_color(`light-dark(color-mix(in srgb, rgb(from rebeccapurple none g b), rebeccapurple), color-mix(in srgb, rgb(from rebeccapurple none g b), rebeccapurple))`, `color(srgb 0.4 0.2 0.6)`); + // hsl(from ...) // Testing no modifications. diff --git a/tests/wpt/tests/css/css-color/parsing/color-valid-relative-color.html b/tests/wpt/tests/css/css-color/parsing/color-valid-relative-color.html index 2c4dc0f8e60..142f96bcf9b 100644 --- a/tests/wpt/tests/css/css-color/parsing/color-valid-relative-color.html +++ b/tests/wpt/tests/css/css-color/parsing/color-valid-relative-color.html @@ -560,6 +560,7 @@ fuzzy_test_valid_color(`oklch(from oklch(0.7 0.2 300) calc(l - 0.2) c h)`, `oklch(from oklch(0.7 0.2 300) calc(-0.2 + l) c h)`); fuzzy_test_valid_color(`oklch(from oklch(0.7 0.2 300) l calc(c / 2) h)`, `oklch(from oklch(0.7 0.2 300) l calc(0.5 * c) h)`); fuzzy_test_valid_color(`oklch(from oklch(0.7 0.2 300) l c calc(h * 2.5))`, `oklch(from oklch(0.7 0.2 300) l c calc(2.5 * h))`); + fuzzy_test_valid_color(`oklch(from red calc(1 / l) c h)`); // Testing with 'none'. fuzzy_test_valid_color(`oklch(from oklch(0.7 0.45 30) none none none)`); diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-style-serialization.html b/tests/wpt/tests/css/css-conditional/container-queries/at-container-style-serialization.html index a30acef9ac2..bd9d23a4b70 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-style-serialization.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/at-container-style-serialization.html @@ -26,7 +26,7 @@ ["style(--foo: )", "Empty declaration value - spaces"], ["style(--foo: )", "Empty declaration value"], ["style(--foo)", "No declaration value"], - ["style((--FOO: BAR) or ( prop: val ))", "Unknown CSS property after 'or'"], + ["style((--FOO: BAR) or ( prop: val ))", "Unknown CSS property after 'or'"], ["style (--foo: bar)", "Not a style function with space before '('"], ["style(--foo: bar baz)", "Spaces preserved in custom property value"], ["style(--foo: 2.100)", "Original string number in custom property value"] diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-overflowing-parsing.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-overflowing-parsing.html index 5c15a825853..5c15a825853 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-overflowing-parsing.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-overflowing-parsing.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-overflowing-serialization.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-overflowing-serialization.html index f55cfeb6343..f55cfeb6343 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-overflowing-serialization.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-overflowing-serialization.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-snapped-parsing.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-snapped-parsing.html index 0a8fe50bc38..0a8fe50bc38 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-snapped-parsing.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-snapped-parsing.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-snapped-serialization.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-snapped-serialization.html index 59cc3d37f4f..59cc3d37f4f 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-snapped-serialization.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-snapped-serialization.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-stuck-parsing.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-stuck-parsing.html index a3a1f01458d..a3a1f01458d 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-stuck-parsing.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-stuck-parsing.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/at-container-stuck-serialization.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-stuck-serialization.html index d5abede45c2..d5abede45c2 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/at-container-stuck-serialization.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/at-container-stuck-serialization.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/container-type-scroll-state-computed.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-computed.html index 4e80712beab..4e80712beab 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/container-type-scroll-state-computed.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-computed.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/container-type-scroll-state-containment.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-containment.html index cc1af5a08eb..cc1af5a08eb 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/container-type-scroll-state-containment.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-containment.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/container-type-scroll-state-parsing.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-parsing.html index 7f3779bc39d..7f3779bc39d 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/container-type-scroll-state-parsing.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/container-type-scroll-state-parsing.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-initially-snapped.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-initially-snapped.html index 64a171c361e..64a171c361e 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-initially-snapped.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-initially-snapped.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-initially-stuck.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-initially-stuck.html index c0d59b61e76..c0d59b61e76 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-initially-stuck.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-initially-stuck.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-change.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-change.html index 6e9843b8b75..6e9843b8b75 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-change.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-change.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-container-type-change.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-container-type-change.html index 556e4c2445b..4eb5de2679e 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-container-type-change.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-container-type-change.html @@ -1,6 +1,6 @@ <!DOCTYPE html> <title>@container: scroll-state(snapped) property changes</title> -<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#container-rule"> +<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#snapped"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/css/css-conditional/container-queries/support/cq-testcommon.js"></script> diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-none.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-none.html index 8c7aae56beb..8c7aae56beb 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-none.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-none.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-snap-changing.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-snap-changing.html index 161c2e1368d..161c2e1368d 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-snap-changing.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-snap-changing.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-wm.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-wm.html index b6703e81142..b6703e81142 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-snapped-wm.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-snapped-wm.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html new file mode 100644 index 00000000000..9c6df648322 --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-container-type-change.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<title>@container: scroll-state(stuck) matching changes with container-type changes</title> +<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#stuck"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/css-conditional/container-queries/support/cq-testcommon.js"></script> +<script src="/css/css-transitions/support/helper.js"></script> +<style> + #filler { + height: 10000px; + } + #stuck { + container-name: initially-stuck; + container-type: scroll-state; + position: sticky; + bottom: 0; + } + + span { + --stuck: no; + @container initially-stuck scroll-state(stuck: bottom) { + --stuck: yes; + } + } +</style> +<div id="filler"></div> +<div id="stuck"> + <span id="target">My container is stuck</span> +</div> +<script> + setup(() => assert_implements_container_queries()); + + promise_test(async t => { + await waitForAnimationFrames(2); + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "yes", + "Initially stuck"); + + stuck.style.containerType = "initial"; + await waitForAnimationFrames(2); + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "no", + "container-type removed"); + + stuck.style.containerType = ""; + await waitForAnimationFrames(2); + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "yes", + "container-type back to scroll-state"); + }, "Check that scroll-state(stuck: bottom) evaluation changes with container-type changes"); +</script> diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html new file mode 100644 index 00000000000..eb0c1c4a84e --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-stuck-writing-direction.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<title>@container: scroll-state(stuck) matching writing-direction of query container</title> +<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#stuck"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/css-conditional/container-queries/support/cq-testcommon.js"></script> +<script src="/css/css-transitions/support/helper.js"></script> +<style> + #filler { + height: 10000px; + } + #stuck { + container-type: scroll-state; + position: sticky; + bottom: 0; + width: 100px; + height: 100px; + background: lime; + } + #target { + writing-mode: horizontal-tb; + direction: ltr; + width: 100px; + height: 100px; + background: orange; + } + @container scroll-state(stuck: inline-start) { + #target { --stuck: inline-start } + } + @container scroll-state(stuck: inline-end) { + #target { --stuck: inline-end } + } + @container scroll-state(stuck: block-start) { + #target { --stuck: block-start } + } + @container scroll-state(stuck: block-end) { + #target { --stuck: block-end } + } +</style> +<div id="filler"></div> +<div id="stuck"> + <div id="target"></div> +</div> +<script> + setup(() => assert_implements_container_queries()); + + promise_test(async t => { + await waitForAnimationFrames(2); + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "block-end"); + }, "bottom edge matching block-end for horizontal-tb/ltr"); + + promise_test(async t => { + stuck.style.writingMode = "vertical-lr"; + stuck.style.direction = "ltr"; + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "inline-end"); + }, "bottom edge matching inline-end for vertical-lr/ltr"); + + promise_test(async t => { + stuck.style.writingMode = "vertical-rl"; + stuck.style.direction = "ltr"; + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "inline-end"); + }, "bottom edge matching inline-end for vertical-rl/ltr"); + + promise_test(async t => { + stuck.style.writingMode = "vertical-lr"; + stuck.style.direction = "rtl"; + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "inline-start"); + }, "bottom edge matching inline-start for vertical-lr/rtl"); + + promise_test(async t => { + stuck.style.writingMode = "vertical-rl"; + stuck.style.direction = "rtl"; + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "inline-start"); + }, "bottom edge matching inline-start for vertical-rl/rtl"); + + promise_test(async t => { + stuck.style.writingMode = "horizontal-tb"; + stuck.style.direction = "rtl"; + assert_equals(getComputedStyle(target).getPropertyValue("--stuck"), "block-end"); + }, "bottom edge matching block-end for horizontal-tb/rtl"); + +</script> diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-target-query-change.html b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-target-query-change.html index 33459f470b9..33459f470b9 100644 --- a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state-target-query-change.html +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/scroll-state-target-query-change.html diff --git a/tests/wpt/tests/css/css-conditional/container-queries/size-container-writing-mode-change.html b/tests/wpt/tests/css/css-conditional/container-queries/size-container-writing-mode-change.html new file mode 100644 index 00000000000..dd709388b7d --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/size-container-writing-mode-change.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title>CSS Container Queries Test: size container writing-mode change</title> +<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#size-container"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/cq-testcommon.js"></script> +<style> + #container { + container-type: size; + width: 500px; + height: 300px; + } + #target { + @container (inline-size = 300px) { + color: green; + } + @container (inline-size = 500px) { + color: red; + } + } +</style> +<div id="container"> + <div id="target">Should be green</div> +</div> +<script> + setup(() => assert_implements_container_queries()); + + test(() => { + assert_equals(getComputedStyle(target).color, "rgb(255, 0, 0)"); + }, "Initial horizontal writing-mode"); + + test(() => { + container.style.writingMode = "vertical-lr"; + assert_equals(getComputedStyle(target).color, "rgb(0, 128, 0)"); + }, "Vertical writing-mode changes logical query evaluation"); +</script> diff --git a/tests/wpt/tests/css/css-multicol/crashtests/text-box-trim-end-and-widows.html b/tests/wpt/tests/css/css-multicol/crashtests/text-box-trim-end-and-widows.html new file mode 100644 index 00000000000..8ff033342c1 --- /dev/null +++ b/tests/wpt/tests/css/css-multicol/crashtests/text-box-trim-end-and-widows.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="http://crbug.com/41494433"> +<div style="columns:2; column-fill:auto; height:100px; text-box-trim:trim-end; line-height:50px; orphans:1; widows:2;"> + <br> + <br> + <br> + <br> +</div> diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/webkit-line-clamp-050-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/webkit-line-clamp-050-ref.html new file mode 100644 index 00000000000..1fa0720aeaf --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/webkit-line-clamp-050-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> + .clamp { + display: block; + padding: 10px; + border: solid 3px; + width: 100px; + } + .clamp div { + border: medium solid green; + padding: 15px; + } +</style> +<div class="clamp"> + Line1 + <div>Line2…</div> +</div> diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-050.html b/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-050.html new file mode 100644 index 00000000000..973871b72d8 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-050.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#propdef--webkit-line-clamp"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10816"> +<link rel="match" href="reference/webkit-line-clamp-050-ref.html"> +<style> + .clamp { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + padding: 10px; + border: solid 3px; + width: 100px; + } + .clamp div { + border: medium solid green; + padding: 15px; + } + span { + /* TODO: Remove once we don't paint clamped lines */ + color: transparent; + } +</style> +<div class="clamp"> + Line1 + <div>Line2<br><span>Line3</span></div> + <span>Line4</span> + <div>Line5<br>Line6</div> + Line7 +</div> diff --git a/tests/wpt/tests/css/css-pseudo/first-line-below-float.html b/tests/wpt/tests/css/css-pseudo/first-line-below-float.html new file mode 100644 index 00000000000..2e32513e9c7 --- /dev/null +++ b/tests/wpt/tests/css/css-pseudo/first-line-below-float.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#first-text-line"> +<meta name="assert" content="Floats are not part of lines, so if a float is too wide to fit any inline content beside it, the first formatted line goes below it"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> + .container { + width: 100px; + height: 100px; + font: 50px/50px Ahem; + color: red; + background: red; + } + .container::first-line { + color: green; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container"> + <div style="float:left; width:100px; height:50px; background:green;"></div> + xx +</div> diff --git a/tests/wpt/tests/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html b/tests/wpt/tests/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html new file mode 100644 index 00000000000..70f35091bc9 --- /dev/null +++ b/tests/wpt/tests/css/css-pseudo/parsing/the-check-pseudo-element.tentative.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS ::check Pseudo-Element Test</title> +<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10986"> +<meta name="assert" content="This test checks the validity of the ::check pseudo element selector." /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +<script> +test_valid_selector("::check"); +test_valid_selector("*::check", "::check"); +test_valid_selector("foo.bar[baz]::check"); +test_invalid_selector("::check *"); + +// Combinations +test_invalid_selector("::check::check"); + +test_invalid_selector("::before::check"); +test_invalid_selector("::after::check"); +test_invalid_selector("::marker::check"); +test_invalid_selector("::placeholder::check"); + +test_invalid_selector("::check::before"); +test_invalid_selector("::check::after"); +test_valid_selector("::check::marker"); +test_invalid_selector("::check::placeholder"); + +test_invalid_selector("::slotted(*)::check::slotted(*)"); +test_valid_selector("::slotted(*)::check"); + +test_valid_selector("::part(foo)::check"); +</script> diff --git a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-001.tentative.html b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-001.tentative.html index 209a47298e3..858a8e5abb7 100644 --- a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-001.tentative.html +++ b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-001.tentative.html @@ -56,7 +56,7 @@ test.innerHTML = ''; styles = getComputedStyle(target); assert_equals(styles.getPropertyValue('color'), green); - }, name); + }); </script> </body> diff --git a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-002.tentative.html b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-002.tentative.html index 36fafcb1dcc..76b726a0a4f 100644 --- a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-002.tentative.html +++ b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-002.tentative.html @@ -58,7 +58,7 @@ test.replaceChildren(); styles = getComputedStyle(target); assert_equals(styles.getPropertyValue('color'), green); - }, name); + }); </script> </body> diff --git a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-003.tentative.html b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-003.tentative.html index 9914e452088..0b1d710d770 100644 --- a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-003.tentative.html +++ b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-003.tentative.html @@ -57,7 +57,7 @@ test.textContent = ''; styles = getComputedStyle(target); assert_equals(styles.getPropertyValue('color'), green); - }, name); + }); </script> </body> diff --git a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-004.tentative.html b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-004.tentative.html index 669162050aa..f4fd54f3d48 100644 --- a/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-004.tentative.html +++ b/tests/wpt/tests/css/css-scoping/has-slotted-functional-changing-004.tentative.html @@ -64,7 +64,7 @@ span.remove(); styles = getComputedStyle(target); assert_equals(styles.getPropertyValue('color'), green); - }, name); + }); </script> </body> diff --git a/tests/wpt/tests/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html b/tests/wpt/tests/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html index 043844d0564..09b1655f86c 100644 --- a/tests/wpt/tests/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html +++ b/tests/wpt/tests/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html @@ -17,6 +17,8 @@ html.rtl { direction: rtl; } html.horz { writing-mode: horizontal-tb; } html.vlr { writing-mode: vertical-lr; } html.vrl { writing-mode: vertical-rl; } +html.slr { writing-mode: sideways-lr; } +html.srl { writing-mode: sideways-rl; } .horz.ltr .cx2, .vlr .cx2 { left: 100vw; } .horz.rtl .cx2, .vrl .cx2 { right: 100vw; } @@ -138,4 +140,28 @@ test(() => { }); }, "Vertical-RL RTL."); +test(() => { + CORNERS.forEach((corner) => { + runCase("slr ltr", 1, -1, true, -30, 0, corner); + }); +}, "Sideways-LR LTR."); + +test(() => { + CORNERS.forEach((corner) => { + runCase("slr rtl", 1, 1, true, -30, 0, corner); + }); +}, "Sideways-LR RTL."); + +test(() => { + CORNERS.forEach((corner) => { + runCase("srl ltr", -1, 1, true, 30, 0, corner); + }); +}, "Sideways-RL LTR."); + +test(() => { + CORNERS.forEach((corner) => { + runCase("srl rtl", -1, -1, true, 30, 0, corner); + }); +}, "Sideways-RL RTL."); + </script> diff --git a/tests/wpt/tests/css/css-sizing/animation/height-interpolation.html b/tests/wpt/tests/css/css-sizing/animation/height-interpolation.html index 75e0977fa11..7539dcb0161 100644 --- a/tests/wpt/tests/css/css-sizing/animation/height-interpolation.html +++ b/tests/wpt/tests/css/css-sizing/animation/height-interpolation.html @@ -121,4 +121,19 @@ test_no_interpolation({ to: 'fit-content', }); +let new_style_text = ` + .target { + height: auto; + } +`; +let new_style = document.createElement("style"); +new_style.append(new_style_text); +document.head.append(new_style); +test_no_interpolation({ + property: 'height', + from: neutralKeyframe, + to: '100px', +}); +new_style.remove(); + </script> diff --git a/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html index a66e118c203..d91d8e6ed9c 100644 --- a/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html +++ b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>Keyword sizes on floated element</title> +<title>Keyword sizes on inline-block</title> <link rel="author" title="Oriol Brufau" href="obrufau@igalia.com"> <link rel="help" href="https://drafts.csswg.org/css-sizing-3/#sizing-values"> <link rel="help" href="https://drafts.csswg.org/css-sizing-4/#sizing-values"> diff --git a/tests/wpt/tests/css/css-sizing/stretch/abspos-1.html b/tests/wpt/tests/css/css-sizing/stretch/abspos-1.html new file mode 100644 index 00000000000..a64f0d05fdf --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/abspos-1.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4028"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<style> + #reference-overlapped-red { + position: absolute; + background-color: red; + width: 100px; + height: 100px; + z-index: -1; + } +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="reference-overlapped-red"></div> + +<div style="width: 100px; height: 100px; position: relative;"> + <div style="position: absolute; width: stretch; height: 100px; background: green;"> + </div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/abspos-2.html b/tests/wpt/tests/css/css-sizing/stretch/abspos-2.html new file mode 100644 index 00000000000..80d815113d1 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/abspos-2.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4028"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<style> + #reference-overlapped-red { + position: absolute; + background-color: red; + width: 100px; + height: 100px; + z-index: -1; + } +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="reference-overlapped-red"></div> + +<div style="width: 100px; height: 200px; position: relative;"> + <div + style="width: 100%; height: stretch; position: absolute; bottom: 100px; background: green;"> + </div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/bfc-next-to-float-1.html b/tests/wpt/tests/css/css-sizing/stretch/bfc-next-to-float-1.html new file mode 100644 index 00000000000..9c2a60e6c01 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/bfc-next-to-float-1.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4028"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<style> + #reference-overlapped-red { + position: absolute; + background-color: red; + width: 100px; + height: 100px; + z-index: -1; + } +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="reference-overlapped-red"></div> + +<div style="width:200px; margin-left: -100px;"> + <div style="float: left; width: 100px; height: 100px;"></div> + <div + style="display: flow-root; width: stretch; height: 100px; background: green;"> + </div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/block-height-1.html b/tests/wpt/tests/css/css-sizing/stretch/block-height-1.html new file mode 100644 index 00000000000..94960f15b96 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/block-height-1.html @@ -0,0 +1,128 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#propdef-width"> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src="/resources/check-layout-th.js"></script> +<meta name="assert" content="Checks the behaviour of stretch in various configurations."> +<style> +.content { + width: 20px; + height: 20px; + background: lime; +} +.tall-content { + width: 20px; + height: 120px; + background: lime; +} +</style> +<body onload="checkLayout('[data-expected-height]')"> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: block; height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: flex; height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: grid; height: stretch;"> + <div class=content></div> + </div> +</div> + +<!-- As the height of the container is indefinite, stretch is treated as auto. --> +<div style="height: 100%;"> + <div data-expected-height=20 style="display: block; height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=20 style="display: flex; height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=20 style="display: grid; height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: block; min-height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: flex; min-height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: grid; min-height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=20 style="display: block; min-height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=20 style="display: flex; min-height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=20 style="display: grid; min-height: stretch;"> + <div class=content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: block; max-height: stretch;"> + <div class=tall-content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: flex; max-height: stretch;"> + <div class=tall-content></div> + </div> +</div> + +<div style="height: 100px;"> + <div data-expected-height=100 style="display: grid; max-height: stretch;"> + <div class=tall-content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=120 style="display: block; max-height: stretch;"> + <div class=tall-content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=120 style="display: flex; max-height: stretch;"> + <div class=tall-content></div> + </div> +</div> + +<div style="height: 100%;"> + <div data-expected-height=120 style="display: grid; max-height: stretch;"> + <div class=tall-content></div> + </div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/block-height-2.html b/tests/wpt/tests/css/css-sizing/stretch/block-height-2.html new file mode 100644 index 00000000000..7028adf9054 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/block-height-2.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing"> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src="/resources/check-layout-th.js"></script> +<meta name="assert" content="Checks the behaviour of stretch in various configurations."> + +<body onload="checkLayout('[data-expected-height]')"> + +<div style="height: 200px; border: solid;"> + <div style="height: stretch; margin: 10px;" data-expected-height="180"></div> +</div> + +<!-- + +Chrome fails the following test, which is a variation of example 9 in the spec. Safari passes. + +From https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing, height:stretch for blocks behaves as +""" +100% but applying the resulting size to its margin box instead of the box indicated by box-sizing. For this purpose, auto margins are treated as zero, and furthermore, for block-level boxes in particular, if its block-start/block-end margin would be adjoining to its parent’s block-start/block-end margin if its parent’s sizing properties all had their initial values, then ***its block-start/block-end margin is treated as zero.*** +""" + +So the spec demands that the child has 0px margins and as a corollary, has 300px inner and outer height. + +But Blink gives it an inner height of 200px and margins as specified (25px/75px). +--> +<div style="height: 300px; outline: 1px solid; margin: 10px 0px 10px 0px;"> + <div + style="height: stretch; margin: 25px 0px 75px 0px; outline: 2px dashed blue;" + data-expected-height="300"></div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/min-width-1.html b/tests/wpt/tests/css/css-sizing/stretch/min-width-1.html new file mode 100644 index 00000000000..a1a39073e88 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/min-width-1.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#propdef-width"> +<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div style="width: 100px;"> + <div style="width: 50px; min-width: stretch; height: 100px; background: green;"></div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/parsing.html b/tests/wpt/tests/css/css-sizing/stretch/parsing.html new file mode 100644 index 00000000000..1f5bd39059e --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/parsing.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Intrinsic & Extrinsic Sizing Test: parsing stretch value</title> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#sizing-values"> +<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("width", "stretch"); +test_valid_value("height", "stretch"); +test_valid_value("max-width", "stretch"); +test_valid_value("min-width", "stretch"); +test_valid_value("max-height", "stretch"); +test_valid_value("min-height", "stretch"); +test_valid_value("inline-size", "stretch"); +test_valid_value("block-size", "stretch"); +test_valid_value("max-inline-size", "stretch"); +test_valid_value("min-inline-size", "stretch"); +test_valid_value("max-block-size", "stretch"); +test_valid_value("min-block-size", "stretch"); +test_valid_value("flex-basis", "stretch"); +</script> +</body> +</html> diff --git a/tests/wpt/tests/css/css-sizing/stretch/positioned-non-replaced-1.html b/tests/wpt/tests/css/css-sizing/stretch/positioned-non-replaced-1.html new file mode 100644 index 00000000000..b66916b8ab4 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/positioned-non-replaced-1.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html"> +<link rel="help" href="https://github.com/webcompat/web-bugs/issues/103641#issuecomment-1122414992"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1324259"> +<p>Test passes if there is a filled green square.</p> +<style> +#target { + position: absolute; + background: green; + min-width: 50px; + min-height: 25px; + width: stretch; + height: stretch; +} +</style> +<div style="display: flow-root; position: relative; width: 150px; height: 150px; margin-top: -50px; margin-left: -50px;"> + <div style="margin-left: 50px; margin-top: 50px;"> + <div id="target"></div> + </div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/stretch/positioned-replaced-1.html b/tests/wpt/tests/css/css-sizing/stretch/positioned-replaced-1.html new file mode 100644 index 00000000000..60b817933d3 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/positioned-replaced-1.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html"> +<link rel="help" href="https://github.com/webcompat/web-bugs/issues/103641#issuecomment-1122414992"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1324259"> +<p>Test passes if there is a filled green square.</p> +<style> +canvas { + position: absolute; + background: green; + width: stretch; + height: stretch; +} +</style> +<div style="display: flow-root; position: relative; width: 150px; height: 150px; margin-top: -50px; margin-left: -50px;"> + <div style="margin-left: 50px; margin-top: 50px;"> + <canvas width="50" height="25"></canvas> + </div> +</div> diff --git a/tests/wpt/tests/css/css-text/text-indent/below-float.html b/tests/wpt/tests/css/css-text/text-indent/below-float.html new file mode 100644 index 00000000000..a386232fd0e --- /dev/null +++ b/tests/wpt/tests/css/css-text/text-indent/below-float.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-text-4/#text-indent-property"> +<meta name="assert" content="Floats are not part of lines, so if a float is too wide to fit any inline content beside it, the first formatted line goes below it"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="position:relative; width:100px; height:100px; font:50px/50px Ahem; text-indent:50px; color:green; background:red;"> + <div style="position:absolute; top:50px; width:50px; height:50px; background:green;"></div> + <span> + <div style="float:left; width:100px; height:50px; background:green;"></div> + x + </span> +</div> diff --git a/tests/wpt/tests/css/css-ui/crashtests/text-overflow-ellipsis-multiline-crash.html b/tests/wpt/tests/css/css-ui/crashtests/text-overflow-ellipsis-multiline-crash.html new file mode 100644 index 00000000000..a281df3a280 --- /dev/null +++ b/tests/wpt/tests/css/css-ui/crashtests/text-overflow-ellipsis-multiline-crash.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> +div { + width: 5ch; + overflow: hidden; + text-overflow: ellipsis; +} +div::first-line { + text-decoration: underline; +} +</style> +<div> + <br> + 1234567 +</div> diff --git a/tests/wpt/tests/css/css-ui/reference/text-overflow-ellipsis-multiline-001-ref.html b/tests/wpt/tests/css/css-ui/reference/text-overflow-ellipsis-multiline-001-ref.html new file mode 100644 index 00000000000..a26b8260eae --- /dev/null +++ b/tests/wpt/tests/css/css-ui/reference/text-overflow-ellipsis-multiline-001-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<style> +div { + width: 6ch; + overflow: hidden; + text-overflow: ellipsis; +} +div.first-line { + color: orange; +} +</style> +<div class="first-line">1234567</div> +<div>1234567</div> diff --git a/tests/wpt/tests/css/css-ui/text-overflow-ellipsis-multiline-001.html b/tests/wpt/tests/css/css-ui/text-overflow-ellipsis-multiline-001.html new file mode 100644 index 00000000000..5987817a5c9 --- /dev/null +++ b/tests/wpt/tests/css/css-ui/text-overflow-ellipsis-multiline-001.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>Test multiline ellipsis with `::first-line`</title> +<link rel="match" href="reference/text-overflow-ellipsis-multiline-001-ref.html"> +<link rel="help" href="https://drafts.csswg.org/css-ui-3/#ellipsing-details"> +<style> +div { + width: 6ch; + overflow: hidden; + text-overflow: ellipsis; +} +div::first-line { + color: orange; +} +</style> +<div> + 1234567<br> + 1234567 +</div> diff --git a/tests/wpt/tests/css/css-values/calc-serialization-002.html b/tests/wpt/tests/css/css-values/calc-serialization-002.html index 28a7de5cdab..a3b99cf87bb 100644 --- a/tests/wpt/tests/css/css-values/calc-serialization-002.html +++ b/tests/wpt/tests/css/css-values/calc-serialization-002.html @@ -139,7 +139,7 @@ ); verifySerialization( "calc((min(10px, 20%) + max(1rem, 2%)) * 2)", - "calc((min(10px, 20%) + max(1rem, 2%)) * 2)", + "calc(2 * (min(10px, 20%) + max(1rem, 2%)))", "testing calc((min(10px, 20%) + max(1rem, 2%)) * 2)" ); diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/calc-size-height-interpolation.html b/tests/wpt/tests/css/css-values/calc-size/animation/calc-size-height-interpolation.html index 2126bd8faed..20b7b8ba317 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/calc-size-height-interpolation.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/calc-size-height-interpolation.html @@ -131,7 +131,7 @@ html.no-parent-height .parent { { at: 0, expect: `${expected}px` }, { at: 0.75, expect: `${expected * 0.25 + 50 * 0.75}px` }, { at: 1, expect: `50px` }, - { at: 1.25, expect: `${50 * 1.25 - expected * 0.25}px` }, + { at: 1.1, expect: `${50 * 1.1 - expected * 0.1}px` }, ]); test_interpolation({ @@ -139,7 +139,7 @@ html.no-parent-height .parent { from: 'calc-size(any, 50px)', to: `calc-size(${keyword}, size * 2)`, }, [ - { at: -0.1, expect: `${50 * 1.1 - expected * 0.2}px` }, + { at: -0.05, expect: `${50 * 1.05 - expected * 0.1}px` }, { at: 0, expect: "50px" }, { at: 0.75, expect: `${50 * 0.25 + expected * 1.5}px` }, { at: 1, expect: `${expected * 2}px` }, diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-height-composition.html b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-height-composition.html index 22f62b8edac..9a3caa747bb 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-height-composition.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-height-composition.html @@ -43,15 +43,20 @@ test_composition({ test_composition({ property: 'height', - underlying: 'fit-content', /* ignored because the keywords aren't compatible */ - addFrom: 'min-content', /* 50px */ - addTo: '200px', + underlying: 'fit-content', + addFrom: 'min-content', /* min-content is 50px, fit-content is ignored + because min-content and fit-content are not + compatible */ + addTo: '200px', /* combines with fit-content (50px) to be 250px */ + /* the composited from value is a min-content size and the composited + to value is a fit-content size, so they cannot be interpolated, + and the animation is discrete */ }, [ - {at: -0.3, expect: '5px'}, + {at: -0.3, expect: '50px'}, {at: 0, expect: '50px'}, - {at: 0.5, expect: '125px'}, - {at: 1, expect: '200px'}, - {at: 1.5, expect: '275px'}, + {at: 0.5, expect: '250px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '250px'}, ]); </script> </body> diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html index e356fb60746..958022d4cd0 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-height-composition.html @@ -40,24 +40,24 @@ test_composition({ addFrom: '100px', addTo: '200px', }, [ - {at: -0.3, expect: 'calc-size(fit-content, 70px + size * 1)'}, - {at: 0, expect: 'calc-size(fit-content, 100px + size * 1)'}, - {at: 0.5, expect: 'calc-size(fit-content, 150px + size * 1)'}, - {at: 1, expect: 'calc-size(fit-content, 200px + size * 1)'}, - {at: 1.5, expect: 'calc-size(fit-content, 250px + size * 1)'}, + {at: -0.3, expect: 'calc-size(fit-content, (100px + size) * 1.3 + (200px + size) * -0.3)'}, + {at: 0, expect: 'calc-size(fit-content, (100px + size) * 1 + (200px + size) * 0)'}, + {at: 0.5, expect: 'calc-size(fit-content, (100px + size) * 0.5 + (200px + size) * 0.5)'}, + {at: 1, expect: 'calc-size(fit-content, (100px + size) * 0 + (200px + size) * 1)'}, + {at: 1.5, expect: 'calc-size(fit-content, (100px + size) * -0.5 + (200px + size) * 1.5)'}, ]); test_composition({ property: 'max-height', - underlying: 'fit-content', /* ignored because the keywords aren't compatible */ - addFrom: 'min-content', /* 50px */ - addTo: '200px', + underlying: 'fit-content', /* 50px */ + addFrom: 'min-content', /* 50px (fit-content is ignored) */ + addTo: '200px', /* adds to 250px, can't interpolate with from */ }, [ - {at: -0.3, expect: 'calc-size(min-content, -60px + size * 1.3)'}, - {at: 0, expect: 'calc-size(min-content, 0px + size * 1)'}, - {at: 0.5, expect: 'calc-size(min-content, 100px + size * 0.5)'}, - {at: 1, expect: 'calc-size(min-content, 200px + size * 0)'}, - {at: 1.5, expect: 'calc-size(min-content, 300px + size * -0.5)'}, + {at: -0.3, expect: 'min-content'}, + {at: 0, expect: 'min-content'}, + {at: 0.5, expect: 'calc-size(fit-content, 200px + size)'}, + {at: 1, expect: 'calc-size(fit-content, 200px + size)'}, + {at: 1.5, expect: 'calc-size(fit-content, 200px + size)'}, ]); </script> </body> diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html index 1e540eaee64..852e1eed793 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-max-width-composition.html @@ -40,11 +40,11 @@ test_composition({ addFrom: '100px', addTo: 'fit-content', }, [ - {at: -0.3, expect: 'calc-size(fit-content, 230px + size * -0.3)'}, - {at: 0, expect: 'calc-size(fit-content, 200px + size * 0)'}, - {at: 0.5, expect: 'calc-size(fit-content, 150px + size * 0.5)'}, - {at: 1, expect: 'calc-size(fit-content, 100px + size * 1)'}, - {at: 1.5, expect: 'calc-size(fit-content, 50px + size * 1.5)'}, + {at: -0.3, expect: 'calc-size(fit-content, 260px + (100px + size) * -0.3)'}, + {at: 0, expect: 'calc-size(fit-content, 200px + (100px + size) * 0)'}, + {at: 0.5, expect: 'calc-size(fit-content, 100px + (100px + size) * 0.5)'}, + {at: 1, expect: 'calc-size(fit-content, 0px + (100px + size) * 1)'}, + {at: 1.5, expect: 'calc-size(fit-content, -100px + (100px + size) * 1.5)'}, ]); test_composition({ @@ -62,15 +62,15 @@ test_composition({ test_composition({ property: 'max-width', - underlying: 'max-content', /* ignored, not compatible */ + underlying: 'max-content', addFrom: '100px', addTo: 'min-content', }, [ - {at: -0.3, expect: 'calc-size(min-content, 130px + size * -0.3)'}, - {at: 0, expect: 'calc-size(min-content, 100px + size * 0)'}, - {at: 0.5, expect: 'calc-size(min-content, 50px + size * 0.5)'}, - {at: 1, expect: 'calc-size(min-content, 0px + size * 1)'}, - {at: 1.5, expect: 'calc-size(min-content, -50px + size * 1.5)'}, + {at: -0.3, expect: 'calc-size(max-content, 100px + size)'}, + {at: 0, expect: 'calc-size(max-content, 100px + size)'}, + {at: 0.5, expect: 'min-content'}, + {at: 1, expect: 'min-content'}, + {at: 1.5, expect: 'min-content'}, ]); </script> </body> diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html index 520ec75aaf8..0c3b4d2c7e3 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-height-composition.html @@ -40,24 +40,24 @@ test_composition({ addFrom: '100px', addTo: '200px', }, [ - {at: -0.3, expect: 'calc-size(fit-content, 70px + size * 1)'}, - {at: 0, expect: 'calc-size(fit-content, 100px + size * 1)'}, - {at: 0.5, expect: 'calc-size(fit-content, 150px + size * 1)'}, - {at: 1, expect: 'calc-size(fit-content, 200px + size * 1)'}, - {at: 1.5, expect: 'calc-size(fit-content, 250px + size * 1)'}, + {at: -0.3, expect: 'calc-size(fit-content, (100px + size) * 1.3 + (200px + size) * -0.3)'}, + {at: 0, expect: 'calc-size(fit-content, (100px + size) * 1 + (200px + size) * 0)'}, + {at: 0.5, expect: 'calc-size(fit-content, (100px + size) * 0.5 + (200px + size) * 0.5)'}, + {at: 1, expect: 'calc-size(fit-content, (100px + size) * 0 + (200px + size) * 1)'}, + {at: 1.5, expect: 'calc-size(fit-content, (100px + size) * -0.5 + (200px + size) * 1.5)'}, ]); test_composition({ property: 'min-height', - underlying: 'fit-content', /* ignored because the keywords aren't compatible */ + underlying: 'fit-content', addFrom: '200px', addTo: 'min-content', /* 50px */ }, [ - {at: -0.3, expect: 'calc-size(min-content, 260px + size * -0.3)'}, - {at: 0, expect: 'calc-size(min-content, 200px + size * 0)'}, - {at: 0.5, expect: 'calc-size(min-content, 100px + size * 0.5)'}, - {at: 1, expect: 'calc-size(min-content, 0px + size * 1)'}, - {at: 1.5, expect: 'calc-size(min-content, -100px + size * 1.5)'}, + {at: -0.3, expect: 'calc-size(fit-content, 200px + size)'}, + {at: 0, expect: 'calc-size(fit-content, 200px + size)'}, + {at: 0.5, expect: 'min-content'}, + {at: 1, expect: 'min-content'}, + {at: 1.5, expect: 'min-content'}, ]); </script> </body> diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html index 4f9e91394a5..2472f805526 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-min-width-composition.html @@ -40,11 +40,11 @@ test_composition({ addFrom: 'max-content', addTo: '100px', }, [ - {at: -0.3, expect: 'calc-size(max-content, 70px + size * 1.3)'}, - {at: 0, expect: 'calc-size(max-content, 100px + size * 1)'}, - {at: 0.5, expect: 'calc-size(max-content, 150px + size * 0.5)'}, - {at: 1, expect: 'calc-size(max-content, 200px + size * 0)'}, - {at: 1.5, expect: 'calc-size(max-content, 250px + size * -0.5)'}, + {at: -0.3, expect: 'calc-size(max-content, (100px + size) * 1.3 + -60px)'}, + {at: 0, expect: 'calc-size(max-content, (100px + size) * 1 + 0px)'}, + {at: 0.5, expect: 'calc-size(max-content, (100px + size) * 0.5 + 100px)'}, + {at: 1, expect: 'calc-size(max-content, (100px + size) * 0 + 200px)'}, + {at: 1.5, expect: 'calc-size(max-content, (100px + size) * -0.5 + 300px)'}, ]); test_composition({ @@ -62,15 +62,16 @@ test_composition({ test_composition({ property: 'min-width', - underlying: 'max-content', /* ignored, not compatible */ - addFrom: '100px', - addTo: 'min-content', + underlying: 'max-content', + addFrom: '100px', /* composites to calc-size(max-content, 100px + size) */ + addTo: 'min-content', /* underlying value ignored when compositing since not compatible */ + /* min-content and max-content values cannot interpolate, so they animate discretely */ }, [ - {at: -0.3, expect: 'calc-size(min-content, 130px + size * -0.3)'}, - {at: 0, expect: 'calc-size(min-content, 100px + size * 0)'}, - {at: 0.5, expect: 'calc-size(min-content, 50px + size * 0.5)'}, - {at: 1, expect: 'calc-size(min-content, 0px + size * 1)'}, - {at: 1.5, expect: 'calc-size(min-content, -50px + size * 1.5)'}, + {at: -0.3, expect: 'calc-size(max-content, 100px + size)'}, + {at: 0, expect: 'calc-size(max-content, 100px + size)'}, + {at: 0.5, expect: 'min-content'}, + {at: 1, expect: 'min-content'}, + {at: 1.5, expect: 'min-content'}, ]); </script> </body> diff --git a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-width-composition.html b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-width-composition.html index a84e0bec3d5..529eac2f7ff 100644 --- a/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-width-composition.html +++ b/tests/wpt/tests/css/css-values/calc-size/animation/interpolate-size-width-composition.html @@ -56,15 +56,15 @@ test_composition({ test_composition({ property: 'width', - underlying: 'max-content', /* ignored, not compatible */ - addFrom: '100px', - addTo: 'auto', /* 200px */ + underlying: 'max-content', /* 100px */ + addFrom: '200px', + addTo: 'auto', /* 200px, max-content underlying is ignored */ }, [ - {at: -0.3, expect: '70px'}, - {at: 0, expect: '100px'}, - {at: 0.5, expect: '150px'}, + {at: -0.3, expect: '300px'}, + {at: 0, expect: '300px'}, + {at: 0.5, expect: '200px'}, {at: 1, expect: '200px'}, - {at: 1.5, expect: '250px'}, + {at: 1.5, expect: '200px'}, ]); </script> </body> diff --git a/tests/wpt/tests/css/css-values/minmax-length-percent-serialize.html b/tests/wpt/tests/css/css-values/minmax-length-percent-serialize.html index 0a109d7c18e..5d11b850467 100644 --- a/tests/wpt/tests/css/css-values/minmax-length-percent-serialize.html +++ b/tests/wpt/tests/css/css-values/minmax-length-percent-serialize.html @@ -126,8 +126,8 @@ test_serialization( test_serialization( 'max((min(10%, 30px) + 10px) * 2 + 10px, 5em + 5%)', - 'max(10px + ((10px + min(10%, 30px)) * 2), 5% + 5em)', - 'max(10px + ((10px + min(10%, 30px)) * 2), 5% + 80px)', + 'max(10px + (2 * (10px + min(10%, 30px))), 5% + 5em)', + 'max(10px + (2 * (10px + min(10%, 30px))), 5% + 80px)', '85px', prop='width'); </script> diff --git a/tests/wpt/tests/css/css-values/round-function.html b/tests/wpt/tests/css/css-values/round-function.html index 338ecaed904..fd35567a575 100644 --- a/tests/wpt/tests/css/css-values/round-function.html +++ b/tests/wpt/tests/css/css-values/round-function.html @@ -246,4 +246,9 @@ test_minus_infinity("round(down, -1, infinity)"); test_minus_zero("round(down, -1 * 0, infinity)"); test_plus_zero("round(down, 0, infinity)"); test_plus_zero("round(down, 1, infinity)"); -</script>
\ No newline at end of file + +// In this test if the multiplication is factored into the sum first, the +// result of the round will be incorrect, because of floating point inprecision. +// round(down, 2.3333333 - 0.33333334, 1) = round(down, 1.99999996, 1) = 1 +test_math_used('round(down, (7 - 1) / 3, 1)', '2', {type:'number'}); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/inline-child-with-overflow-shadow-ref.html b/tests/wpt/tests/css/css-view-transitions/inline-child-with-overflow-shadow-ref.html new file mode 100644 index 00000000000..69ed62da57d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/inline-child-with-overflow-shadow-ref.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<title>View transitions: inline child with overflowing shadow</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<style> +body { + background: rebeccapurple; + margin: 0; +} + +.target { + width: 100px; + height: 200px; + position: absolute; + top: 100px; + left: 100px; + view-transition-name: target; +} + +.child { + background: green; + font-size: 100px; + box-shadow: -20px -20px yellow; +} +</style> + +<div class=target> + <span class=child> </span> +</div> + diff --git a/tests/wpt/tests/css/css-view-transitions/inline-child-with-overflow-shadow.html b/tests/wpt/tests/css/css-view-transitions/inline-child-with-overflow-shadow.html new file mode 100644 index 00000000000..2c2d50af60c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/inline-child-with-overflow-shadow.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>View transitions: inline child with overflowing shadow</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<link rel="match" href="inline-child-with-overflow-shadow-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +:root { view-transition-name: none; } +::view-transition { background: rebeccapurple; } +body { + margin: 0; +} + +.target { + width: 100px; + height: 200px; + position: absolute; + top: 100px; + left: 100px; + view-transition-name: target; +} + +.child { + background: green; + font-size: 100px; + box-shadow: -20px -20px yellow; +} + +html::view-transition-group(target) { + animation-play-state: paused; + } +html::view-transition-old(target), +html::view-transition-new(target) { + animation: unset; + opacity: 1; +} + +html::view-transition-old(target) { + opacity: 0; +} + +/* None of these should apply, so make everything red if it does */ +html::view-transition-group(root) { animation: unset; opacity: 1; background: red; } +html::view-transition-image-pair(root) { visibility: hidden } +</style> + +<div class=target> + <span class=child> </span> +</div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +async function runTest() { + document.startViewTransition(() => + requestAnimationFrame(() => 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 026ecb240a3..6bbb8b49392 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-1400"> +<meta name="fuzzy" content="maxDifference=0-255; totalPixels=0-1500"> <script src="/common/reftest-wait.js"></script> <script src="/common/rendering-utils.js"></script> diff --git a/tests/wpt/tests/css/css-view-transitions/layered-capture/capture-mode-flat.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/capture-mode-flat.tentative.html new file mode 100644 index 00000000000..beed17c8973 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/capture-mode-flat.tentative.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>Capture mode: flat</title> +<meta name=fuzzy content="maxDifference=0-255; totalPixels=0-515"> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="nested-opacity-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="../nested/resources/compute-test.js"></script> +<style> + body { + margin: 0; + } + div { + position: absolute; + width: 100px; + height: 100px; + background: green; + } + + .parent { + opacity: 0.4; + view-transition-name: parent; + view-transition-capture-mode: flat; + will-change: opacity; + } + + .child { + top: 50px; + left: 50px; + } + + ::view-transition-group(parent) { + animation-name: none; + opacity: 1; + } + ::view-transition-old(*), + ::view-transition-new(*) { + animation-play-state: paused; + } +</style> +<body> + <div class="parent"> + <div class="child"></div> + </div> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-view-transitions/layered-capture/capture-mode-layered.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/capture-mode-layered.tentative.html new file mode 100644 index 00000000000..d1f190343b0 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/capture-mode-layered.tentative.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>Captured mode: layered</title> +<meta name=fuzzy content="maxDifference=0-255; totalPixels=0-515"> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="nested-opacity-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="../nested/resources/compute-test.js"></script> +<style> + body { + margin: 0; + } + div { + position: absolute; + width: 100px; + height: 100px; + background: green; + } + + .parent { + opacity: 0.7; + view-transition-name: parent; + will-change: opacity; + view-transition-capture-mode: layered; + } + + .child { + top: 50px; + left: 50px; + } + + ::view-transition-group(parent) { + opacity: 0.4; + animation-name: none; + } + ::view-transition-old(*), + ::view-transition-new(*) { + animation-play-state: paused; + } +</style> +<body> + <div class="parent"> + <div class="child"></div> + </div> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-view-transitions/nested/opacity-backdrop-blend-animated.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/nested-opacity-backdrop-blend-animated.tentative.html index 835f068c492..73100015cdd 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/opacity-backdrop-blend-animated.tentative.html +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/nested-opacity-backdrop-blend-animated.tentative.html @@ -5,7 +5,7 @@ <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="match" href="nested-opacity-ref.html"> <script src="/common/reftest-wait.js"></script> -<script src="resources/compute-test.js"></script> +<script src="../nested/resources/compute-test.js"></script> <style> body { margin: 0; diff --git a/tests/wpt/tests/css/css-view-transitions/nested/opacity-backdrop-blend.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/nested-opacity-backdrop-blend.tentative.html index ea8acfc86b0..0042d9676f2 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/opacity-backdrop-blend.tentative.html +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/nested-opacity-backdrop-blend.tentative.html @@ -5,7 +5,7 @@ <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <link rel="match" href="nested-opacity-ref.html"> <script src="/common/reftest-wait.js"></script> -<script src="resources/compute-test.js"></script> +<script src="../nested/resources/compute-test.js"></script> <style> body { margin: 0; diff --git a/tests/wpt/tests/css/css-view-transitions/nested/opacity-computed-style.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/opacity-computed-style.tentative.html index f370b7b03d2..f370b7b03d2 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/opacity-computed-style.tentative.html +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/opacity-computed-style.tentative.html diff --git a/tests/wpt/tests/css/css-view-transitions/nested/opacity-resets-after-done.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/opacity-resets-after-done.tentative.html index 7616638dc5e..7616638dc5e 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/opacity-resets-after-done.tentative.html +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/opacity-resets-after-done.tentative.html diff --git a/tests/wpt/tests/css/css-view-transitions/nested/opacity-resets-after-skip.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/opacity-resets-after-skip.tentative.html index e7a11ebe331..e7a11ebe331 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/opacity-resets-after-skip.tentative.html +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/opacity-resets-after-skip.tentative.html diff --git a/tests/wpt/tests/css/css-view-transitions/layered-capture/parsing/view-transition-capture-mode-invalid.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/parsing/view-transition-capture-mode-invalid.tentative.html new file mode 100644 index 00000000000..6bcd77cdae0 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/parsing/view-transition-capture-mode-invalid.tentative.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS View Transitions Test: view-transition-capture-mode with invalid values</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> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("view-transition-capture-mode", "none"); +test_invalid_value("view-transition-capture-mode", "auto"); +test_invalid_value("view-transition-capture-mode", "stuff"); +</script> +</body> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/layered-capture/parsing/view-transition-capture-mode-valid.tentative.html b/tests/wpt/tests/css/css-view-transitions/layered-capture/parsing/view-transition-capture-mode-valid.tentative.html new file mode 100644 index 00000000000..2b739fcfe28 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/layered-capture/parsing/view-transition-capture-mode-valid.tentative.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS View Transitions Test: view-transition-capture-mode with valid values</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> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("view-transition-capture-mode", "flat"); +test_valid_value("view-transition-capture-mode", "layered"); + +</script> +</body> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/nested-elements-in-overflow-ref.html b/tests/wpt/tests/css/css-view-transitions/nested-elements-in-overflow-ref.html new file mode 100644 index 00000000000..a05172fa40e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/nested-elements-in-overflow-ref.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<title>View transitions: nested named element in overflow</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<style> +body { + background: rebeccapurple; + margin: 0; +} +.outer { + width: 50px; + height: 100px; + position: absolute; + top: 50px; + left: 50px; + border: 2px solid black; +} +.inner { + background: lightblue; + width: 50px; + height: 50px; + view-transition-name: outer; + position: absolute; + top: 25px; +} +.grey { + background: lightgrey; + position: relative; + width: 50px; + height: 50px; +} +</style> +<div class="outer"> + <div class="inner"></div> +</div> +<div class="grey"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/nested-elements-in-overflow.html b/tests/wpt/tests/css/css-view-transitions/nested-elements-in-overflow.html new file mode 100644 index 00000000000..cce8fe8d8ff --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/nested-elements-in-overflow.html @@ -0,0 +1,71 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<meta name="timeout" content="long"> +<title>View transitions: nested named element in overflow</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="nested-elements-in-overflow-ref.html"> +<meta name="fuzzy" content="maxDifference=0-60; totalPixels=0-500"> +<script src="/common/reftest-wait.js"></script> +<style> +:root { + view-transition-name: none; +} + +.outer { + background: lightblue; + width: 100px; + height: 100px; + view-transition-name: outer; + position: absolute; + top: 50px; + left: 50px; +} +.inner { + background: lightgrey; + position: relative; + top: -50px; + left: -50px; + width: 50px; + height: 50px; + view-transition-name: inner; +} + +::view-transition { background: rebeccapurple; } +::view-transition-group(*) { + animation-duration: 300s; +} +::view-transition-group(outer) { + width: 50px; + height: 100px; + border: 2px solid black; + animation: none; +} +::view-transition-new(*), +::view-transition-old(*) { + position: absolute; + inset-block-start: unset; + inline-size: 100%; + block-size: 100%; + object-fit: contain; +} +::view-transition-old(*) { + opacity: 0; + animation: none; +} +::view-transition-new(*) { + opacity: 1; + animation: none; +} +</style> +<div class="outer"> + <div class="inner"></div> +</div> +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +async function runTest() { + document.startViewTransition().ready.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/new-and-old-sizes-match.html b/tests/wpt/tests/css/css-view-transitions/new-and-old-sizes-match.html index f23f63d28ff..7245e4b42f2 100644 --- a/tests/wpt/tests/css/css-view-transitions/new-and-old-sizes-match.html +++ b/tests/wpt/tests/css/css-view-transitions/new-and-old-sizes-match.html @@ -4,7 +4,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-and-old-sizes-match-ref.html"> -<meta name="fuzzy" content="maxDifference=0-15; totalPixels=0-500"> +<meta name="fuzzy" content="maxDifference=0-25; totalPixels=0-1500"> <script src="/common/reftest-wait.js"></script> <style> .box { diff --git a/tests/wpt/tests/css/css-view-transitions/outer-padding-inner-background-ref.html b/tests/wpt/tests/css/css-view-transitions/outer-padding-inner-background-ref.html new file mode 100644 index 00000000000..7c7ee533f5c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/outer-padding-inner-background-ref.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<style> +:root { background: rebeccapurple; } +.target { + width: 200px; + height: 200px; + contain: paint; + view-transition-name: target; + padding: 20px; +} + +.child { + width: 100px; + height: 200px; + position: relative; + background: green; +} +</style> + +<div class=target> + <div class=child> + </div> +</div> + diff --git a/tests/wpt/tests/css/css-view-transitions/outer-padding-inner-background.html b/tests/wpt/tests/css/css-view-transitions/outer-padding-inner-background.html new file mode 100644 index 00000000000..6bbcf514ab4 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/outer-padding-inner-background.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>View transitions: named element has padding, inner element has background</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<link rel="match" href="outer-padding-inner-background-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +:root { view-transition-name: none; } +::view-transition { background: rebeccapurple; } +.target { + width: 200px; + height: 200px; + view-transition-name: target; + padding: 20px; +} + +.child { + width: 100px; + height: 100px; + position: relative; + background: green; +} + +html::view-transition-group(target) { + animation-play-state: paused; + } +html::view-transition-old(target), +html::view-transition-new(target) { + animation: unset; + opacity: 1; +} + +html::view-transition-new(target) { + position: relative; + top: 100px; +} + +/* None of these should apply, so make everything red if it does */ +html::view-transition-group(root) { animation: unset; opacity: 1; background: red; } +html::view-transition-image-pair(root) { visibility: hidden } +</style> + +<div class=target> + <div class=child> + </div> +</div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +async function runTest() { + document.startViewTransition(() => + requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + diff --git a/tests/wpt/tests/css/filter-effects/backdrop-filter-plus-filter.html b/tests/wpt/tests/css/filter-effects/backdrop-filter-plus-filter.html index 546786d8e60..5c83faae868 100644 --- a/tests/wpt/tests/css/filter-effects/backdrop-filter-plus-filter.html +++ b/tests/wpt/tests/css/filter-effects/backdrop-filter-plus-filter.html @@ -4,6 +4,7 @@ <link rel="author" href="mailto:masonf@chromium.org"> <link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty"> <link rel="match" href="backdrop-filter-plus-filter-ref.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-210"> <p>Expected: A green box with an overlapping purple box.<br> The overlapping portion of the boxes should be bright magenta.<br> diff --git a/tests/wpt/tests/custom-elements/CustomElementRegistry.html b/tests/wpt/tests/custom-elements/CustomElementRegistry.html index 5b75fc651fc..87da806bcab 100644 --- a/tests/wpt/tests/custom-elements/CustomElementRegistry.html +++ b/tests/wpt/tests/custom-elements/CustomElementRegistry.html @@ -11,6 +11,8 @@ <div id="log"></div> <script> +const moveBefore_supported = ("moveBefore" in Node.prototype); + test(function () { assert_true('define' in CustomElementRegistry.prototype, '"define" exists on CustomElementRegistry.prototype'); assert_true('define' in customElements, '"define" exists on window.customElements'); @@ -273,7 +275,9 @@ test(function () { } }); customElements.define('element-with-proxy-prototype', constructor); - assert_array_equals(calls, ['connectedCallback', 'disconnectedCallback', 'adoptedCallback', 'attributeChangedCallback']); + assert_array_equals(calls, + moveBefore_supported ? ['connectedCallback', 'disconnectedCallback', 'connectedMoveCallback', 'adoptedCallback', 'attributeChangedCallback'] : + ['connectedCallback', 'disconnectedCallback', 'adoptedCallback', 'attributeChangedCallback']); }, 'customElements.define must get callbacks of the constructor prototype'); test(function () { @@ -305,7 +309,10 @@ test(function () { } }); assert_throws_js(TypeError, function () { customElements.define('element-with-throwing-callback', constructor); }); - assert_array_equals(calls, ['connectedCallback', 'disconnectedCallback', 'adoptedCallback'], + assert_array_equals(calls, + moveBefore_supported ? + ['connectedCallback', 'disconnectedCallback', 'connectedMoveCallback', 'adoptedCallback'] : + ['connectedCallback', 'disconnectedCallback', 'adoptedCallback'], 'customElements.define must not get callbacks after one of the conversion throws'); }, 'customElements.define must rethrow an exception thrown while converting a callback value to Function callback type'); @@ -332,11 +339,14 @@ test(function () { } }); customElements.define('element-with-attribute-changed-callback', proxy); - assert_array_equals(prototypeCalls, [1, 'connectedCallback', 2, 'disconnectedCallback', 3, 'adoptedCallback', 4, 'attributeChangedCallback']); + assert_array_equals(prototypeCalls, + moveBefore_supported ? + [1, 'connectedCallback', 2, 'disconnectedCallback', 3, 'connectedMoveCallback', 4, 'adoptedCallback', 5, 'attributeChangedCallback'] : + [1, 'connectedCallback', 2, 'disconnectedCallback', 3, 'adoptedCallback', 4, 'attributeChangedCallback']); assert_array_equals(constructorCalls, [0, 'prototype', - 5, 'observedAttributes', - 6, 'disabledFeatures', - 7, 'formAssociated']); + 6, 'observedAttributes', + 7, 'disabledFeatures', + 8, 'formAssociated']); }, 'customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present'); test(function () { @@ -492,6 +502,10 @@ test(function () { '"formAssociated" on the constructor'); assert_array_equals( prototypeCalls, + moveBefore_supported ? ['connectedCallback', 'disconnectedCallback', 'connectedMoveCallback', 'adoptedCallback', + 'attributeChangedCallback', 'formAssociatedCallback', + 'formResetCallback', 'formDisabledCallback', + 'formStateRestoreCallback'] : ['connectedCallback', 'disconnectedCallback', 'adoptedCallback', 'attributeChangedCallback', 'formAssociatedCallback', 'formResetCallback', 'formDisabledCallback', @@ -521,7 +535,10 @@ test(function () { }); assert_throws_exactly(err, () => customElements.define('element-with-throwing-callback-2', proxy)); - assert_array_equals(calls, ['connectedCallback', 'disconnectedCallback', + assert_array_equals(calls, moveBefore_supported ? ['connectedCallback', 'disconnectedCallback', 'connectedMoveCallback', + 'adoptedCallback', 'attributeChangedCallback', + 'formAssociatedCallback', 'formResetCallback', + 'formDisabledCallback'] : ['connectedCallback', 'disconnectedCallback', 'adoptedCallback', 'attributeChangedCallback', 'formAssociatedCallback', 'formResetCallback', 'formDisabledCallback'], @@ -538,7 +555,9 @@ test(function () { }); assert_throws_js(TypeError, () => customElements.define('element-with-throwing-callback-3', proxy)); - assert_array_equals(calls2, ['connectedCallback', 'disconnectedCallback', + assert_array_equals(calls2, moveBefore_supported ? ['connectedCallback', 'disconnectedCallback', 'connectedMoveCallback', + 'adoptedCallback', 'attributeChangedCallback', + 'formAssociatedCallback', 'formResetCallback'] : ['connectedCallback', 'disconnectedCallback', 'adoptedCallback', 'attributeChangedCallback', 'formAssociatedCallback', 'formResetCallback'], 'customElements.define must not get callbacks after one of the get throws'); diff --git a/tests/wpt/tests/digital-credentials/allow-attribute.https.html b/tests/wpt/tests/digital-credentials/allow-attribute.https.html index 41223626808..d988e94cd23 100644 --- a/tests/wpt/tests/digital-credentials/allow-attribute.https.html +++ b/tests/wpt/tests/digital-credentials/allow-attribute.https.html @@ -8,6 +8,8 @@ <script src="/common/get-host-info.sub.js"></script> <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> const hostInfo = get_host_info(); const iframeDetails = [ diff --git a/tests/wpt/tests/digital-credentials/support/iframe.html b/tests/wpt/tests/digital-credentials/support/iframe.html index 6f3c072f29f..3ec761e08a6 100644 --- a/tests/wpt/tests/digital-credentials/support/iframe.html +++ b/tests/wpt/tests/digital-credentials/support/iframe.html @@ -69,5 +69,6 @@ } } + test_driver.set_test_context(parent); window.addEventListener("message", messageListener); </script> diff --git a/tests/wpt/tests/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html b/tests/wpt/tests/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html new file mode 100644 index 00000000000..ce0302cd734 --- /dev/null +++ b/tests/wpt/tests/dom/nodes/moveBefore/tentative/custom-element-move-reactions.html @@ -0,0 +1,98 @@ +<!DOCTYPE html> +<title>Node.moveBefore custom element reactions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +; +</script> + +<body> + <section id="section"></section> + <script> + promise_test(async t => { + const ce = document.getElementById("ce"); + let reactions = []; + const element_name = `ce-${performance.now()}`; + customElements.define(element_name, + class MockCustomElement extends HTMLElement { + connectedCallback() { reactions.push("connected"); } + disconnectedCallback() { reactions.push("disconnected"); } + }); + const element = document.createElement(element_name); + t.add_cleanup(() => element.remove()); + document.body.append(element); + await Promise.resolve(); + reactions = []; + document.getElementById("section").moveBefore(element, null); + await Promise.resolve(); + assert_array_equals(reactions, ["disconnected", "connected"]); + }, "the disconnected/connected callbacks should be called when no other callback is defined"); + + promise_test(async t => { + const ce = document.getElementById("ce"); + let reactions = []; + const element_name = `ce-${performance.now()}`; + customElements.define(element_name, + class MockCustomElement extends HTMLElement { + connectedCallback() { reactions.push(this.isConnected); } + disconnectedCallback() { reactions.push(this.isConnected); } + }); + const element = document.createElement(element_name); + t.add_cleanup(() => element.remove()); + document.body.append(element); + await Promise.resolve(); + reactions = []; + document.getElementById("section").moveBefore(element, null); + await Promise.resolve(); + assert_array_equals(reactions, [true, true]); + }, "the element should stay connected during the callbacks"); + + promise_test(async t => { + const ce = document.getElementById("ce"); + let reactions = []; + const element_name = `ce-${performance.now()}`; + customElements.define(element_name, + class MockCustomElement extends HTMLElement { + connectedMoveCallback() { reactions.push("connectedMove"); } + connectedCallback() { reactions.push("connected"); } + disconnectedCallback() { reactions.push("disconnected"); } + }); + const element = document.createElement(element_name); + t.add_cleanup(() => element.remove()); + document.body.append(element); + await Promise.resolve(); + reactions = []; + document.getElementById("section").moveBefore(element, null); + await Promise.resolve(); + assert_array_equals(reactions, ["connectedMove"]); + }, "When connectedMoveCallback is defined, it is called instead of disconnectedCallback/connectedCallback"); + + promise_test(async t => { + const ce = document.getElementById("ce"); + let reactions = []; + const outer_element_name = `ce-${performance.now()}-outer`; + const inner_element_name = `ce-${performance.now()}-inner`; + customElements.define(outer_element_name, + class MockCustomElement extends HTMLElement { + connectedCallback() { reactions.push("outer connected"); } + disconnectedCallback() { reactions.push("outer disconnected"); } + }); + customElements.define(inner_element_name, + class MockCustomElement extends HTMLElement { + connectedCallback() { reactions.push("inner connected"); } + disconnectedCallback() { reactions.push("inner disconnected"); } + }); + const outer = document.createElement(outer_element_name); + const inner = document.createElement(inner_element_name); + t.add_cleanup(() => outer.remove()); + outer.append(inner); + document.body.append(outer); + await Promise.resolve(); + reactions = []; + document.getElementById("section").moveBefore(outer, null); + await Promise.resolve(); + assert_array_equals(reactions, ["outer disconnected", "outer connected", "inner disconnected", "inner connected"]); + }, "Reactions to atomic move are called in order of element, not in order of operation"); + +</script> +</body> diff --git a/tests/wpt/tests/editing/data/inserthtml.js b/tests/wpt/tests/editing/data/inserthtml.js index bdfc1d34020..412fa63ef31 100644 --- a/tests/wpt/tests/editing/data/inserthtml.js +++ b/tests/wpt/tests/editing/data/inserthtml.js @@ -487,7 +487,7 @@ var browserTests = [ {"inserthtml":[false,false,"",false,false,""]}], ["<p>{}<br></p>", [["inserthtml","<!--abc-->"]], - "<p><!--abc-->{}</p>", + "<p><!--abc-->{}<br></p>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["<p><!--foo-->{}<span><br></span><!--bar--></p>", @@ -521,13 +521,13 @@ var browserTests = [ {"inserthtml":[false,false,"",false,false,""]}], ["<p><br>{}</p>", [["inserthtml","<!--abc-->"]], - "<p><!--abc--></p>", + "<p><!--abc--><br></p>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["<p><!--foo--><span><br></span>{}<!--bar--></p>", [["inserthtml","abc"]], ["<p><!--foo--><span>abc</span><!--bar--></p>", - "<p><!--foo-->abc<span></span><!--bar--></p>"], + "<p><!--foo-->abc<!--bar--></p>"], [true], {"inserthtml":[false,false,"",false,false,""]}], ["<p><!--foo--><span><br></span>{}<!--bar--></p>", @@ -535,7 +535,7 @@ var browserTests = [ "<p><!--foo--><span><!--abc-->{}<br></span><!--bar--></p>", [true], {"inserthtml":[false,false,"",false,false,""]}], -// TODO: Fix the insertion not occurring at carot position. +// TODO: Fix the insertion not occurring at caret position. // Updating the expected value of below two tests as to how other // browsers behave these tests will still fail and since the insertion // position is incorrect br tag gets removed, after fixing this it shouldn't. @@ -552,40 +552,34 @@ var browserTests = [ ["<pre>12[]34</pre>", [["inserthtml","<pre>abc</pre>"]], - ["<pre>12abc34</pre>", - "<pre>12abc34<br></pre>"], + "<pre>12abc34</pre>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["<pre>1[23]4</pre>", [["inserthtml","<pre>abc</pre>"]], - ["<pre>1abc4</pre>", - "<pre>1abc4<br></pre>"], + "<pre>1abc4</pre>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["<pre>[1234]</pre>", [["inserthtml","<pre>abc</pre>"]], - ["<pre>abc</pre>", - "<pre>abc<br></pre>"], + "<pre>abc</pre>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["<pre contenteditable=\"false\"><span contenteditable>[1234]</span></pre>", [["inserthtml","<pre>abc</pre>"]], - ["<pre contenteditable=\"false\"><span contenteditable=\"\">abc</span></pre>", - "<pre contenteditable=\"false\"><span contenteditable=\"\">abc<br></span></pre>"], + "<pre contenteditable=\"false\"><span contenteditable=\"\">abc</span></pre>", [true], {"inserthtml":[false,false,"",false,false,""]}], // Empty inline elements shouldn't be deleted if they are inserted intentionally ["<div>a[]b</div>", [["inserthtml","<span></span>"]], - ["<div>a<span></span>b</div>", - "<div>a<span></span>b<br></div>"], + "<div>a<span></span>b</div>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["<div>a[]c</div>", [["inserthtml","<span class=\"s1\"></span>b<span class=\"s2\"></span>"]], - ["<div>a<span class=\"s1\"></span>b<span class=\"s2\"></span>c</div>", - "<div>a<span class=\"s1\"></span>b<span class=\"s2\"></span>c<br></div>"], + "<div>a<span class=\"s1\"></span>b<span class=\"s2\"></span>c</div>", [true], {"inserthtml":[false,false,"",false,false,""]}], ["{}", diff --git a/tests/wpt/tests/editing/data/insertimage.js b/tests/wpt/tests/editing/data/insertimage.js index b62331e1520..f92a5709191 100644 --- a/tests/wpt/tests/editing/data/insertimage.js +++ b/tests/wpt/tests/editing/data/insertimage.js @@ -357,8 +357,7 @@ var browserTests = [ {"insertimage":[false,false,"",false,false,""]}], ["<div>{}<br></div>", [["insertimage","/img/lion.svg"]], - ["<div><img src=\"/img/lion.svg\"></div>", - "<div><img src=\"/img/lion.svg\"><br></div>"], + "<div><img src=\"/img/lion.svg\"></div>", [true], {}], ["<div><b>{}<br></b></div>", diff --git a/tests/wpt/tests/editing/data/inserttext.js b/tests/wpt/tests/editing/data/inserttext.js index 8fa8127f2df..568b467f153 100644 --- a/tests/wpt/tests/editing/data/inserttext.js +++ b/tests/wpt/tests/editing/data/inserttext.js @@ -1248,36 +1248,32 @@ var browserTests = [ {"inserttext":[false,false,"",false,false,""]}], ["<br>{}", [["inserttext","a"]], - ["a", "a<br>"], + "a", [true], {"inserttext":[false,false,"",false,false,""]}], ["abc<br>{}", [["inserttext","d"]], - ["abcd", "abcd<br>"], + "abcd", [true], {"inserttext":[false,false,"",false,false,""]}], ["abc<br>{}<br>", [["inserttext","d"]], - ["abc<br>d", - "abc<br>d<br>"], + "abc<br>d", [true], {"inserttext":[false,false,"",false,false,""]}], ["<span contenteditable=false>abc</span><br>{}", [["inserttext","d"]], - ["<span contenteditable=\"false\">abc</span>d", - "<span contenteditable=\"false\">abc</span>d<br>"], + "<span contenteditable=\"false\">abc</span>d", [true], {"inserttext":[false,false,"",false,false,""]}], ["<div contenteditable=false><span contenteditable><br>{}</span></div>", [["inserttext","a"]], - ["<div contenteditable=\"false\"><span contenteditable=\"\">a</span></div>", - "<div contenteditable=\"false\"><span contenteditable=\"\">a<br></span></div>"], + "<div contenteditable=\"false\"><span contenteditable=\"\">a</span></div>", [true], {"inserttext":[false,false,"",false,false,""]}], ["<div contenteditable=false><span contenteditable>abc<br>{}</span></div>", [["inserttext","d"]], - ["<div contenteditable=\"false\"><span contenteditable=\"\">abcd</span></div>", - "<div contenteditable=\"false\"><span contenteditable=\"\">abcd<br></span></div>"], + "<div contenteditable=\"false\"><span contenteditable=\"\">abcd</span></div>", [true], {"inserttext":[false,false,"",false,false,""]}], ["<div style=white-space:pre>foo[]bar</div>", @@ -1349,15 +1345,20 @@ var browserTests = [ // element. ["<p>a<br>{}<span></span></p>", [["inserttext","b"]], - "<p>ab<br><span></span></p>", + "<p>ab<span></span></p>", [true], {"inserttext":[false,false,"",false,false,""]}], -// In this case, the <span> element after <br> element is visible and is put in -// the second line, but for backward compatibility, typing text should be -// inserted before the <br> element. +// In these cases, the <span> element after <br> element is visible and is put in +// the second line and caret is in the second line. Therefore, new text should +// be inserted into the second line. ["<p style=\"white-space:pre-wrap\">a<br>{}<span style=\"padding:1px\"></span></p>", [["inserttext","b"]], - "<p style=\"white-space:pre-wrap\">ab<br><span style=\"padding:1px\"></span></p>", + "<p style=\"white-space:pre-wrap\">a<br>b<span style=\"padding:1px\"></span></p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=\"white-space:pre-wrap\">a<br>{}<span style=\"padding:1px\"></span><p>c</p></div>", + [["inserttext","b"]], + "<div style=\"white-space:pre-wrap\">a<br>b<span style=\"padding:1px\"></span><p>c</p></div>", [true], {"inserttext":[false,false,"",false,false,""]}], // Similar case if <br> follows last visible thing and is followed by invisible @@ -1368,13 +1369,6 @@ var browserTests = [ "<div>a<br><span></span><p>bc</p></div>", [true], {"inserttext":[false,false,"",false,false,""]}], -// And even if the <br> element is followed by visible but empty inline element, -// should be same as previous test. -["<div style=\"white-space:pre-wrap\">a<br>{}<span style=\"padding:1px\"></span><p>c</p></div>", - [["inserttext","b"]], - "<div style=\"white-space:pre-wrap\">a<br><span style=\"padding:1px\"></span><p>bc</p></div>", - [true], - {"inserttext":[false,false,"",false,false,""]}], // https://bugzilla.mozilla.org/show_bug.cgi?id=1785801 ["<div>abc{</div><div>}efg</div>", [["inserttext", "d"]], @@ -1474,75 +1468,63 @@ var browserTests = [ // selection start container. ["<div>{abc</div><div>def</div>}", [["inserttext","g"],["inserttext","h"]], - ["<div>gh</div>", - "<div>gh<br></div>"], + "<div>gh</div>", [true,true], {}], ["<div>abc</div><div>{def</div>}", [["inserttext","g"],["inserttext","h"]], - ["<div>abc</div><div>gh</div>", - "<div>abc</div><div>gh<br></div>"], + "<div>abc</div><div>gh</div>", [true,true], {}], ["<div style=display:flex><span>{abc</span><span>def</span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:flex\"><span>gh</span></div>", - "<div style=\"display:flex\"><span>gh<br></span></div>"], + "<div style=\"display:flex\"><span>gh</span></div>", [true,true], {}], ["<div style=display:flex><span>abc</span><span>{def</span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:flex\"><span>abc</span><span>gh</span></div>", - "<div style=\"display:flex\"><span>abc</span><span>gh<br></span></div>"], + "<div style=\"display:flex\"><span>abc</span><span>gh</span></div>", [true,true], {}], ["<div style=display:grid><span>{abc</span><span>def</span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:grid\"><span>gh</span></div>", - "<div style=\"display:grid\"><span>gh<br></span></div>"], + "<div style=\"display:grid\"><span>gh</span></div>", [true,true], {}], ["<div style=display:grid><span>abc</span><span>{def</span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:grid\"><span>abc</span><span>gh</span></div>", - "<div style=\"display:grid\"><span>abc</span><span>gh<br></span></div>"], + "<div style=\"display:grid\"><span>abc</span><span>gh</span></div>", [true,true], {}], // The inline style at selection start should be preserved for typed text. ["<div><b>{abc</b></div><div>def</div>}", [["inserttext","g"],["inserttext","h"]], - ["<div><b>gh</b></div>", - "<div><b>gh<br></b></div>"], + "<div><b>gh</b></div>", [true,true], {}], ["<div>abc</div><div><b>{def</b></div>}", [["inserttext","g"],["inserttext","h"]], - ["<div>abc</div><div><b>gh</b></div>", - "<div>abc</div><div><b>gh<br></b></div>"], + "<div>abc</div><div><b>gh</b></div>", [true,true], {}], ["<div style=display:flex><span><b>{abc</b></span><span>def</span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:flex\"><span><b>gh</b></span></div>", - "<div style=\"display:flex\"><span><b>gh<br></b></span></div>"], + "<div style=\"display:flex\"><span><b>gh</b></span></div>", [true,true], {}], ["<div style=display:flex><span>abc</span><span><b>{def</b></span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:flex\"><span>abc</span><span><b>gh</b></span></div>", - "<div style=\"display:flex\"><span>abc</span><span><b>gh<br></b></span></div>"], + "<div style=\"display:flex\"><span>abc</span><span><b>gh</b></span></div>", [true,true], {}], ["<div style=display:grid><span><b>{abc</b></span><span>def</span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:grid\"><span><b>gh</b></span></div>", - "<div style=\"display:grid\"><span><b>gh<br></b></span></div>"], + "<div style=\"display:grid\"><span><b>gh</b></span></div>", [true,true], {}], ["<div style=display:grid><span>abc</span><span><b>{def</b></span>}</div>", [["inserttext","g"],["inserttext","h"]], - ["<div style=\"display:grid\"><span>abc</span><span><b>gh</b></span></div>", - "<div style=\"display:grid\"><span>abc</span><span><b>gh<br></b></span></div>"], + "<div style=\"display:grid\"><span>abc</span><span><b>gh</b></span></div>", [true,true], {}], ] diff --git a/tests/wpt/tests/editing/other/delete-before-invisible-line-break.html b/tests/wpt/tests/editing/other/delete-before-invisible-line-break.html new file mode 100644 index 00000000000..ec88079d31e --- /dev/null +++ b/tests/wpt/tests/editing/other/delete-before-invisible-line-break.html @@ -0,0 +1,154 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?white-space=normal"> +<meta name="variant" content="?white-space=pre"> +<meta name="variant" content="?white-space=pre-line"> +<meta name="variant" content="?white-space=pre-wrap"> +<title>Deleting content immediately before invisible line break should clean up if it's unnecessary anymore</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 src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const whiteSpace = searchParams.get("white-space"); +const useBR = whiteSpace == "normal"; +const collapseWhiteSpaces = whiteSpace == "normal" || whiteSpace == "pre-line"; + +addEventListener("load", () => { + const editingHost = document.querySelector("div[contenteditable]"); + editingHost.style.whiteSpace = whiteSpace; + editingHost.getBoundingClientRect(); + editingHost.focus(); + const utils = new EditorTestUtils(editingHost); + + for (const data of [ + { + initialInnerHTML: "<p>a []<br></p>", + expected: "<p>a</p>", + }, + { + initialInnerHTML: "<p>a[ ]<br></p>", + expected: "<p>a</p>", + }, + { + initialInnerHTML: "<p>a b[]<br></p>", + expected: collapseWhiteSpaces + ? (useBR ? ["<p>a <br></p>", "<p>a </p>"] : ["<p>a <br></p>", "<p>a \n</p>", "<p>a </p>"]) + : "<p>a </p>", + }, + { + initialInnerHTML: "<p>a [b]<br></p>", + expected: collapseWhiteSpaces + ? (useBR ? ["<p>a <br></p>", "<p>a </p>"] : ["<p>a <br></p>", "<p>a \n</p>", "<p>a </p>"]) + : "<p>a </p>", + }, + { + initialInnerHTML: "<p>a []\n</p>", + expected: "<p>a</p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<p>a[ ]\n</p>", + expected: "<p>a</p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<p>a b[]\n</p>", + expected: collapseWhiteSpaces + ? ["<p>a \n</p>", "<p>a </p>"] + : "<p>a </p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<p>a [b]\n</p>", + expected: collapseWhiteSpaces + ? ["<p>a \n</p>", "<p>a </p>"] + : "<p>a </p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a []<br><div>b</div></div>", + expected: "<div>a<div>b</div></div>", + }, + { + initialInnerHTML: "<div>a[ ]<br><div>b</div></div>", + expected: "<div>a<div>b</div></div>", + }, + { + initialInnerHTML: "<div>a b[]<br><div>b</div></div>", + expected: collapseWhiteSpaces + ? (useBR + ? ["<div>a <br><div>b</div></div>", "<div>a <div>b</div></div>"] + : ["<div>a <br><div>b</div></div>", "<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"]) + : "<div>a <div>b</div></div>", + }, + { + initialInnerHTML: "<div>a [b]<br><div>b</div></div>", + expected: collapseWhiteSpaces + ? (useBR + ? ["<div>a <br><div>b</div></div>", "<div>a <div>b</div></div>"] + : ["<div>a <br><div>b</div></div>", "<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"]) + : "<div>a <div>b</div></div>", + }, + { + initialInnerHTML: "<div>a []\n<div>b</div></div>", + expected: "<div>a<div>b</div></div>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a[ ]\n<div>b</div></div>", + expected: "<div>a<div>b</div></div>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a b[]\n<div>b</div></div>", + expected: collapseWhiteSpaces + ? ["<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"] + : "<div>a <div>b</div></div>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a [b]\n<div>b</div></div>", + expected: collapseWhiteSpaces + ? ["<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"] + : "<div>a <div>b</div></div>", + skipIf: () => useBR, + }, + ]) { + if (data.skipIf !== undefined && data.skipIf()) { + continue; + } + promise_test(async () => { + utils.setupEditingHost(data.initialInnerHTML); + document.execCommand("delete"); + if (Array.isArray(data.expected)) { + assert_in_array(editingHost.innerHTML, data.expected); + } else { + assert_equals(editingHost.innerHTML, data.expected); + } + }, `document.execCommand("delete") when ${data.initialInnerHTML.replaceAll("\n", "\\n")}`); + promise_test(async () => { + utils.setupEditingHost(data.initialInnerHTML); + await utils.sendBackspaceKey(); + if (Array.isArray(data.expected)) { + assert_in_array(editingHost.innerHTML, data.expected); + } else { + assert_equals(editingHost.innerHTML, data.expected); + } + }, `Backspace when ${data.initialInnerHTML.replaceAll("\n", "\\n")}`); + } +}, {once: true}); +</script> +</head> +<body> + <div contenteditable></div> +</body> +</html> diff --git a/tests/wpt/tests/editing/other/double-click-range-selection-in-floating-list-item.html b/tests/wpt/tests/editing/other/double-click-range-selection-in-floating-list-item.html new file mode 100644 index 00000000000..898f42b9b04 --- /dev/null +++ b/tests/wpt/tests/editing/other/double-click-range-selection-in-floating-list-item.html @@ -0,0 +1,71 @@ +<!DOCTYPE html> +<meta charset="utf-8" /> +<title> + This test is for testing the range selection of floating list item on + double click. +</title> +<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> + .fl, + li { + float: left; + margin-right: 40px; + } +</style> +<div> + <ul> + <li id="first">First</li> + <li>Second</li> + </ul> +</div> +<div> + <strong id="sfirst" class="fl">first</strong + ><strong class="fl">second</strong> +</div> +<script> + function runTests() { + promise_test(async () => { + const first = document.getElementById("first"); + first.focus(); + let actions = new test_driver.Actions() + .pointerMove(0, 0, { origin: first }) + .pointerDown() + .pointerUp() + .pointerDown() + .pointerUp(); + await actions.send(); + const selection = window.getSelection(); + let selectedText = selection.toString(); + assert_equals( + selectedText, + "First", + "Selected Text Should be equal to first list item" + ); + }, "Double click on one floating list item should not select more than one list item"); + + promise_test(async () => { + const sfirst = document.getElementById("sfirst"); + sfirst.focus(); + let actions = new test_driver.Actions() + .pointerMove(0, 0, { origin: sfirst }) + .pointerDown() + .pointerUp() + .pointerDown() + .pointerUp(); + await actions.send(); + const selection = window.getSelection(); + let selectedText = selection.toString(); + assert_equals( + selectedText, + "first", + "Selected Text Should be equal to first list item" + ); + }, "Double click on one floating strong text should not select more than one item"); + } + + window.addEventListener("load", runTests, { once: true }); +</script> diff --git a/tests/wpt/tests/editing/other/double-click-range-selection-in-list-item.html b/tests/wpt/tests/editing/other/double-click-range-selection-in-list-item.html new file mode 100644 index 00000000000..18dee19966a --- /dev/null +++ b/tests/wpt/tests/editing/other/double-click-range-selection-in-list-item.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<meta charset="utf-8" /> +<title> + This test is for testing the range selection of list item on double + click. +</title> +<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> + .inline-block { + display: inline-block; + width: 50px; + height: 20px; + background-color: lightblue; + } +</style> +<div> + <ul> + <li id="first">First</li> + <li>Second</li> + </ul> +</div> +<div> + This is some + <span id="atomicinline" class="inline-block">atomicinline</span> text. +</div> +<script> + function runTests() { + promise_test(async () => { + const first = document.getElementById("first"); + first.focus(); + let actions = new test_driver.Actions() + .pointerMove(0, 0, { origin: "viewport" }) + .pointerDown() + .pointerUp() + .pointerDown() + .pointerUp(); + await actions.send(); + const selection = window.getSelection(); + let selectedText = selection.toString(); + assert_equals( + selectedText, + "First", + "Selected Text Should be equal to first list item" + ); + }, "Double click on one list item should not select more than one list item"); + + promise_test(async () => { + const atomic_inline = document.getElementById("atomicinline"); + atomic_inline.focus(); + let actions = new test_driver.Actions() + .pointerMove(0, 0, { origin: atomic_inline }) + .pointerDown() + .pointerUp() + .pointerDown() + .pointerUp(); + await actions.send(); + const selection = window.getSelection(); + let selectedText = selection.toString(); + assert_equals( + selectedText, + "atomicinline", + "Selected Text Should be equal to atomicinline" + ); + }, "Double click on one text item should select only one text item"); + } + + window.addEventListener("load", runTests, { once: true }); +</script> diff --git a/tests/wpt/tests/editing/other/forwarddelete-before-invisible-line-break.html b/tests/wpt/tests/editing/other/forwarddelete-before-invisible-line-break.html new file mode 100644 index 00000000000..aebfdc2899e --- /dev/null +++ b/tests/wpt/tests/editing/other/forwarddelete-before-invisible-line-break.html @@ -0,0 +1,154 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?white-space=normal"> +<meta name="variant" content="?white-space=pre"> +<meta name="variant" content="?white-space=pre-line"> +<meta name="variant" content="?white-space=pre-wrap"> +<title>Deleting content immediately before invisible line break should clean up if it's unnecessary anymore</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 src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const whiteSpace = searchParams.get("white-space"); +const useBR = whiteSpace == "normal"; +const collapseWhiteSpaces = whiteSpace == "normal" || whiteSpace == "pre-line"; + +addEventListener("load", () => { + const editingHost = document.querySelector("div[contenteditable]"); + editingHost.style.whiteSpace = whiteSpace; + editingHost.getBoundingClientRect(); + editingHost.focus(); + const utils = new EditorTestUtils(editingHost); + + for (const data of [ + { + initialInnerHTML: "<p>a[] <br></p>", + expected: "<p>a</p>", + }, + { + initialInnerHTML: "<p>a[ ]<br></p>", + expected: "<p>a</p>", + }, + { + initialInnerHTML: "<p>a []b<br></p>", + expected: collapseWhiteSpaces + ? (useBR ? ["<p>a <br></p>", "<p>a </p>"] : ["<p>a <br></p>", "<p>a \n</p>", "<p>a </p>"]) + : "<p>a </p>", + }, + { + initialInnerHTML: "<p>a [b]<br></p>", + expected: collapseWhiteSpaces + ? (useBR ? ["<p>a <br></p>", "<p>a </p>"] : ["<p>a <br></p>", "<p>a \n</p>", "<p>a </p>"]) + : "<p>a </p>", + }, + { + initialInnerHTML: "<p>a[] \n</p>", + expected: "<p>a</p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<p>a[ ]\n</p>", + expected: "<p>a</p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<p>a []b\n</p>", + expected: collapseWhiteSpaces + ? ["<p>a \n</p>", "<p>a </p>"] + : "<p>a </p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<p>a [b]\n</p>", + expected: collapseWhiteSpaces + ? ["<p>a \n</p>", "<p>a </p>"] + : "<p>a </p>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a[] <br><div>b</div></div>", + expected: "<div>a<div>b</div></div>", + }, + { + initialInnerHTML: "<div>a[ ]<br><div>b</div></div>", + expected: "<div>a<div>b</div></div>", + }, + { + initialInnerHTML: "<div>a []b<br><div>b</div></div>", + expected: collapseWhiteSpaces + ? (useBR + ? ["<div>a <br><div>b</div></div>", "<div>a <div>b</div></div>"] + : ["<div>a <br><div>b</div></div>", "<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"]) + : "<div>a <div>b</div></div>", + }, + { + initialInnerHTML: "<div>a [b]<br><div>b</div></div>", + expected: collapseWhiteSpaces + ? (useBR + ? ["<div>a <br><div>b</div></div>", "<div>a <div>b</div></div>"] + : ["<div>a <br><div>b</div></div>", "<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"]) + : "<div>a <div>b</div></div>", + }, + { + initialInnerHTML: "<div>a[] \n<div>b</div></div>", + expected: "<div>a<div>b</div></div>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a[ ]\n<div>b</div></div>", + expected: "<div>a<div>b</div></div>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a []b\n<div>b</div></div>", + expected: collapseWhiteSpaces + ? ["<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"] + : "<div>a <div>b</div></div>", + skipIf: () => useBR, + }, + { + initialInnerHTML: "<div>a [b]\n<div>b</div></div>", + expected: collapseWhiteSpaces + ? ["<div>a \n<div>b</div></div>", "<div>a <div>b</div></div>"] + : "<div>a <div>b</div></div>", + skipIf: () => useBR, + }, + ]) { + if (data.skipIf !== undefined && data.skipIf()) { + continue; + } + promise_test(async () => { + utils.setupEditingHost(data.initialInnerHTML); + document.execCommand("forwardDelete"); + if (Array.isArray(data.expected)) { + assert_in_array(editingHost.innerHTML, data.expected); + } else { + assert_equals(editingHost.innerHTML, data.expected); + } + }, `document.execCommand("forwardDelete") when ${data.initialInnerHTML.replaceAll("\n", "\\n")}`); + promise_test(async () => { + utils.setupEditingHost(data.initialInnerHTML); + await utils.sendDeleteKey(); + if (Array.isArray(data.expected)) { + assert_in_array(editingHost.innerHTML, data.expected); + } else { + assert_equals(editingHost.innerHTML, data.expected); + } + }, `(Forward) Delete when ${data.initialInnerHTML.replaceAll("\n", "\\n")}`); + } +}, {once: true}); +</script> +</head> +<body> + <div contenteditable></div> +</body> +</html> diff --git a/tests/wpt/tests/editing/plaintext-only/insertText.html b/tests/wpt/tests/editing/plaintext-only/insertText.html index 9045e04d368..664b9befb8d 100644 --- a/tests/wpt/tests/editing/plaintext-only/insertText.html +++ b/tests/wpt/tests/editing/plaintext-only/insertText.html @@ -36,6 +36,24 @@ addEventListener("load", () => { for (const data of [ { + initialInnerHTML: "{}<br>", + insertText: " ", + expected: collapseWhiteSpaces + ? (useBR ? [" <br>", " "] : [" <br>", " \n", " "]) + : " ", + }, + { + initialInnerHTML: "{}<br>", + insertText: "a", + expected: "a", + }, + { + initialInnerHTML: "[]\n", + skipIf: () => useBR, + insertText: "a", + expected: "a", + }, + { initialInnerHTML: "A[]B", insertText: "a", expected: "AaB", @@ -98,9 +116,7 @@ addEventListener("load", () => { prepareDescription: "execCommand(\"insertParagraph\")", prepare: () => document.execCommand("insertParagraph"), insertText: "a", - expected: useBR - ? ["<p><b>A</b></p><p><b>aB</b></p>", "<p><b>A</b></p><p><b>aB<br></b></p>"] - : ["<p><b>A</b></p><p><b>aB</b></p>", "<p><b>A</b></p><p><b>aB<br></b></p>", "<p><b>A</b></p><p><b>aB\n</b></p>"], + expected: "<p><b>A</b></p><p><b>aB</b></p>", }, { initialInnerHTML: "<p><b>AB[]</b></p>", @@ -109,9 +125,7 @@ addEventListener("load", () => { insertText: "a", // To keep the style of next typing even after lost focus, the placeholder line break in // the empty paragraph after "insertParagraph" should be wrapped in the <b>. - expected: useBR - ? ["<p><b>AB</b></p><p><b>a</b></p>", "<p><b>AB</b></p><p><b>a<br></b></p>"] - : ["<p><b>AB</b></p><p><b>a</b></p>", "<p><b>AB</b></p><p><b>a<br></b></p>", "<p><b>AB</b></p><p><b>a\n</b></p>"], + expected: "<p><b>AB</b></p><p><b>a</b></p>", }, { initialInnerHTML: "<p><b>[AB]</b></p>", @@ -119,9 +133,8 @@ addEventListener("load", () => { prepare: () => document.execCommand("insertParagraph"), insertText: "a", expected: useBR - ? ["<p><b><br></b></p><p><b>a</b></p>", "<p><b><br></b></p><p><b>a<br></b></p>"] - : ["<p><b><br></b></p><p><b>a</b></p>", "<p><b>\n</b></p><p><b>a</b></p>", - "<p><b><br></b></p><p><b>a<br></b></p>", "<p><b>\n</b></p><p><b>a\n</b></p>"], + ? "<p><b><br></b></p><p><b>a</b></p>" + : ["<p><b><br></b></p><p><b>a</b></p>", "<p><b>\n</b></p><p><b>a</b></p>"], }, { initialInnerHTML: "<p><b>[]AB</b></p>", @@ -149,9 +162,8 @@ addEventListener("load", () => { // To keep the style of next typing even after once the paragraph becomes empty, // the placeholder line break (if there is) should be in <b>. expected: useBR - ? ["<p><b>AB<br>a</b></p>", "<p><b>AB<br>a<br></b></p>"] - : ["<p><b>AB<br>a</b></p>", "<p><b>AB<br>a<br></b></p>", "<p><b>AB\na</b></p>", - "<p><b>AB\na\n</b></p>", "<p><b>AB\na<br></b></p>", "<p><b>AB<br>a\n</b></p>"], + ? "<p><b>AB<br>a</b></p>" + : ["<p><b>AB<br>a</b></p>", "<p><b>AB\na</b></p>"], }, { initialInnerHTML: "<p><b>[AB]</b></p>", @@ -161,9 +173,8 @@ addEventListener("load", () => { // To keep the style of next typing even after once the paragraph becomes empty, // the placeholder line break (if there is) should be in <b>. expected: useBR - ? ["<p><b><br>a</b></p>", "<p><b><br>a<br></b></p>"] - : ["<p><b><br>a</b></p>", "<p><b><br>a<br></b></p>", "<p><b>\na</b></p>", "<p><b>\na\n</b></p>", - "<p><b><br>a\n</b></p>", "<p><b>\na<br></b></p>"], + ? "<p><b><br>a</b></p>" + : ["<p><b><br>a</b></p>", "<p><b>\na</b></p>"], }, { initialInnerHTML: "<p><b>[AB]</b></p>", @@ -172,9 +183,7 @@ addEventListener("load", () => { insertText: "a", // To keep the style of next typing even after blur, the placeholder line break // (if there is) should be in <b>. - expected: useBR - ? ["<p><b>a</b></p>", "<p><b>a<br></b></p>"] - : ["<p><b>a</b></p>", "<p><b>a<br></b></p>", "<p><b>a\n</b></p>"], + expected: "<p><b>a</b></p>", }, { initialInnerHTML: "<p><b>A[]</b></p><p>B</p>", @@ -186,9 +195,7 @@ addEventListener("load", () => { }, insertText: "a", // Moving caret shouldn't cause loosing the style. - expected: useBR - ? ["<p><b>a</b></p><p>B</p>", "<p><b>a<br></b></p><p>B</p>"] - : ["<p><b>a</b></p><p>B</p>", "<p><b>a<br></b></p><p>B</p>", "<p><b>a\n</b></p><p>B</p>"], + expected: "<p><b>a</b></p><p>B</p>", }, { initialInnerHTML: "<p><b>[]A</b></p><p>B</p>", @@ -200,9 +207,7 @@ addEventListener("load", () => { }, insertText: "a", // Moving caret shouldn't cause loosing the style. - expected: useBR - ? ["<p><b>a</b></p><p>B</p>", "<p><b>a<br></b></p><p>B</p>"] - : ["<p><b>a</b></p><p>B</p>", "<p><b>a<br></b></p><p>B</p>", "<p><b>a\n</b></p><p>B</p>"], + expected: "<p><b>a</b></p><p>B</p>", }, { initialInnerHTML: "<p><b>[A]</b></p><p>B</p>", @@ -214,9 +219,7 @@ addEventListener("load", () => { }, insertText: "a", // Moving caret shouldn't cause loosing the style. - expected: useBR - ? ["<p><b>a</b></p><p>B</p>", "<p><b>a<br></b></p><p>B</p>"] - : ["<p><b>a</b></p><p>B</p>", "<p><b>a<br></b></p><p>B</p>", "<p><b>a\n</b></p><p>B</p>"], + expected: "<p><b>a</b></p><p>B</p>", }, { initialInnerHTML: "<p><b>A[]</b></b>", @@ -228,11 +231,12 @@ addEventListener("load", () => { }, insertText: "a", // Moving caret shouldn't cause loosing the style. - expected: useBR - ? ["<p><b>A</b></p><p><b>a</b></p>", "<p><b>A</b></p><p><b>a<br></b></p>"] - : ["<p><b>A</b></p><p><b>a</b></p>", "<p><b>A</b></p><p><b>a<br></b></p>", "<p><b>A</b></p><p><b>a\n</b></p>"], + expected: "<p><b>A</b></p><p><b>a</b></p>", }, ]) { + if (data.skipIf !== undefined && data.skipIf()) { + continue; + } test(() => { utils.setupEditingHost(data.initialInnerHTML); if (data.prepare) { @@ -244,8 +248,10 @@ addEventListener("load", () => { } else { assert_equals(editingHost.innerHTML, data.expected); } - }, `execCommand("insertText", false, "${data.insertText}") when ${data.initialInnerHTML}${ - data.prepareDescription ? ` and ${data.prepareDescription}` : "" + }, `execCommand("insertText", false, "${data.insertText.replaceAll("\n", "\\n")}") when ${ + data.initialInnerHTML.replaceAll("\n", "\\n") + }${ + data.prepareDescription ? ` and ${data.prepareDescription.replaceAll("\n", "\\n")}` : "" }`); promise_test(async t => { utils.setupEditingHost(data.initialInnerHTML); @@ -260,8 +266,10 @@ addEventListener("load", () => { } else { assert_equals(editingHost.innerHTML, data.expected); } - }, `Typing "${data.insertText}" when ${data.initialInnerHTML}${ - data.prepareDescription ? ` and ${data.prepareDescription}` : "" + }, `Typing "${data.insertText.replaceAll("\n", "\\n")}" when ${ + data.initialInnerHTML.replaceAll("\n", "\\n") + }${ + data.prepareDescription ? ` and ${data.prepareDescription.replaceAll("\n", "\\n")}` : "" }`); } }, {once: true}); diff --git a/tests/wpt/tests/eyedropper/idlharness.https.window.js b/tests/wpt/tests/eyedropper/idlharness.https.window.js new file mode 100644 index 00000000000..891d334e9f6 --- /dev/null +++ b/tests/wpt/tests/eyedropper/idlharness.https.window.js @@ -0,0 +1,7 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +idl_test( + ['eyedropper-api'], + [], +); diff --git a/tests/wpt/tests/fenced-frame/http-localhost-url.https.html b/tests/wpt/tests/fenced-frame/http-localhost-url.https.html new file mode 100644 index 00000000000..a8b16d75c85 --- /dev/null +++ b/tests/wpt/tests/fenced-frame/http-localhost-url.https.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>Test navigate fenced frame to http://localhost URL</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="resources/utils.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/get-host-info.sub.js"></script> + +<body> +<script> +promise_test(async (t) => { + const key = token(); + const url = generateURL("http://localhost:" + get_host_info().HTTP_PORT + + "/fenced-frame/resources/embeddee.html", [key]); + attachFencedFrame(url); + + const result = await nextValueFromServer(key); + assert_equals(result, "PASS", + "The fenced frame should load a http://localhost URL."); +}, 'http://localhost URLs can load'); + +</script> +</body> +</html> diff --git a/tests/wpt/tests/fledge/tentative/get-interest-group-auction-data.https.window.js b/tests/wpt/tests/fledge/tentative/get-interest-group-auction-data.https.window.js index 3788045c8c2..453d0f8e642 100644 --- a/tests/wpt/tests/fledge/tentative/get-interest-group-auction-data.https.window.js +++ b/tests/wpt/tests/fledge/tentative/get-interest-group-auction-data.https.window.js @@ -374,15 +374,16 @@ subsetTest(promise_test, async test => { assert_equals(ig.browserSignals.joinCount, 2, 'joinCount'); assert_equals(ig.browserSignals.bidCount, 1, 'bidCount'); - // Recency is the # of seconds since the join. We can't exactly say what it - // is, but it shouldn't be too huge. - assert_true(typeof ig.browserSignals.recency === 'number'); + // RecencyMs is the # of milliseconds since the join. We can't exactly say + // what it is, but it shouldn't be too huge. + assert_true(typeof ig.browserSignals.recencyMs === 'number'); assert_between_inclusive( - ig.browserSignals.recency, 0, 60, 'Recency is between 0 and 60 seconds'); + ig.browserSignals.recencyMs, 0, 60000, + 'RecencyMs is between 0 and 60 seconds'); // It's also supposed to be an integer. assert_equals( - ig.browserSignals.recency, Math.round(ig.browserSignals.recency), - 'Recency is an integer'); + ig.browserSignals.recencyMs, Math.round(ig.browserSignals.recencyMs), + 'RecencyMs is an integer'); // One win. The format here depends highly on whether full ads are used or // not. @@ -433,15 +434,16 @@ subsetTest(promise_test, async test => { assert_equals(ig.browserSignals.joinCount, 2, 'joinCount'); assert_equals(ig.browserSignals.bidCount, 1, 'bidCount'); - // Recency is the # of seconds since the join. We can't exactly say what it - // is, but it shouldn't be too huge. - assert_true(typeof ig.browserSignals.recency === 'number'); + // RecencyMs is the # of milliseconds since the join. We can't exactly say + // what it is, but it shouldn't be too huge. + assert_true(typeof ig.browserSignals.recencyMs === 'number'); assert_between_inclusive( - ig.browserSignals.recency, 0, 60, 'Recency is between 0 and 60 seconds'); + ig.browserSignals.recencyMs, 0, 60000, + 'RecencyMs is between 0 and 60 seconds'); // It's also supposed to be an integer. assert_equals( - ig.browserSignals.recency, Math.round(ig.browserSignals.recency), - 'Recency is an integer'); + ig.browserSignals.recencyMs, Math.round(ig.browserSignals.recencyMs), + 'RecencyMs is an integer'); // One win. The format here depends highly on whether full ads are used or // not. diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html new file mode 100644 index 00000000000..eea78248a83 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html new file mode 100644 index 00000000000..8e6b95ae221 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html @@ -0,0 +1,845 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..2318c1ec94e --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html new file mode 100644 index 00000000000..08ed3566fd1 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html new file mode 100644 index 00000000000..5dca89e3c12 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html @@ -0,0 +1,767 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..2318c1ec94e --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html new file mode 100644 index 00000000000..22c84f42e89 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html new file mode 100644 index 00000000000..6b3c4c6a589 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html @@ -0,0 +1,871 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..2318c1ec94e --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html new file mode 100644 index 00000000000..2072348f904 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html new file mode 100644 index 00000000000..f6872b22127 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html @@ -0,0 +1,897 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..fde78773116 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html new file mode 100644 index 00000000000..1e119bcbde5 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html new file mode 100644 index 00000000000..1c68c0e4540 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html @@ -0,0 +1,819 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..fde78773116 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern-expected.html new file mode 100644 index 00000000000..f45fe82c302 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html new file mode 100644 index 00000000000..1e3f14fb9a3 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html @@ -0,0 +1,923 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..fde78773116 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html new file mode 100644 index 00000000000..923d8360a9d --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html new file mode 100644 index 00000000000..31e0fba7918 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html @@ -0,0 +1,845 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..ce392a1dccc --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html new file mode 100644 index 00000000000..c809e56cac3 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html new file mode 100644 index 00000000000..e14c336868e --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html @@ -0,0 +1,767 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..ce392a1dccc --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html new file mode 100644 index 00000000000..f052442a637 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html new file mode 100644 index 00000000000..6f8159466db --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html @@ -0,0 +1,871 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..ce392a1dccc --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html new file mode 100644 index 00000000000..ad07c35d310 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html new file mode 100644 index 00000000000..84527f5a283 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html @@ -0,0 +1,897 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..aca03a61b22 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html new file mode 100644 index 00000000000..e16a5fcf458 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html new file mode 100644 index 00000000000..46bc366c8ac --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html @@ -0,0 +1,819 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..aca03a61b22 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html new file mode 100644 index 00000000000..01e1d4d7b26 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html new file mode 100644 index 00000000000..e636330c59f --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html @@ -0,0 +1,923 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas4"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas5"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas6"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas7"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas8"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas9"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas10"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas11"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas12"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas13"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas14"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas15"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas16"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas17"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas18"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas19"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas20"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas21"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas22"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas23"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas24"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas25"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.png b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..aca03a61b22 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.basic.png b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.basic.png Binary files differindex 8021427a07d..70d7b046cb2 100644 --- a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.basic.png +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.basic.png diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png Binary files differindex 8021427a07d..70d7b046cb2 100644 --- a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png Binary files differindex 8021427a07d..70d7b046cb2 100644 --- a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png Binary files differindex d4f6dc1ee88..fb3b5b830d3 100644 --- a/tests/wpt/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html new file mode 100644 index 00000000000..cc6f366e072 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-position.tentative.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-position.tentative</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<style> +@font-face { + font-family: CanvasTest; + src: url("/fonts/CanvasTest.ttf"); +} +</style> +<body class="show_output"> + +<h1>2d.text.measure.text-clusters-position.tentative</h1> +<p class="desc">Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.</p> + + +<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span> +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="500" height="500"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +promise_test(async t => { + + var canvas = document.getElementById('c'); + var ctx = canvas.getContext('2d'); + + await document.fonts.ready; + ctx.font = '40px CanvasTest'; + const text = 'E'; + + // Origin for all the measurements is placed at the top left corner. + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + + // X position. + _assertSame(Math.abs(tm.getTextClusters({align: 'left'})[0].x), 0, "Math.abs(tm.getTextClusters({align: 'left'})[\""+(0)+"\"].x)", "0"); + _assertSame(tm.getTextClusters({align: 'center'})[0].x, 20, "tm.getTextClusters({align: 'center'})[\""+(0)+"\"].x", "20"); + _assertSame(tm.getTextClusters({align: 'right'})[0].x, 40, "tm.getTextClusters({align: 'right'})[\""+(0)+"\"].x", "40"); + + // Y position. + _assertSame(Math.abs(tm.getTextClusters({baseline: 'top'})[0].y), 0, "Math.abs(tm.getTextClusters({baseline: 'top'})[\""+(0)+"\"].y)", "0"); + _assertSame(tm.getTextClusters({baseline: 'middle'})[0].y, 20, "tm.getTextClusters({baseline: 'middle'})[\""+(0)+"\"].y", "20"); + _assertSame(tm.getTextClusters({baseline: 'bottom'})[0].y, 40, "tm.getTextClusters({baseline: 'bottom'})[\""+(0)+"\"].y", "40"); + _assertSame(tm.getTextClusters({baseline: 'alphabetic'})[0].y, 30, "tm.getTextClusters({baseline: 'alphabetic'})[\""+(0)+"\"].y", "30"); + +}, "Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options."); +</script> + diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html new file mode 100644 index 00000000000..effa53c4c95 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-range.tentative.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-range.tentative</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<style> +@font-face { + font-family: CanvasTest; + src: url("/fonts/CanvasTest.ttf"); +} +</style> +<body class="show_output"> + +<h1>2d.text.measure.text-clusters-range.tentative</h1> +<p class="desc">Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.</p> + + +<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span> +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="400" height="300"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +promise_test(async t => { + + var canvas = document.getElementById('c'); + var ctx = canvas.getContext('2d'); + + // Renders all the clusters in the list from position (x, y). + function renderClusters(clusters, x, y) { + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + } + + await document.fonts.ready; + + ctx.font = '50px CanvasTest'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + const text = 'EEEEE'; + let tm = ctx.measureText(text); + + // Background color. + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + ctx.fillStyle = '#0f0'; + + // Without the first character. + renderClusters(tm.getTextClusters(1, 5), 0, 0); + _assertPixelApprox(canvas, 5,5, 255,0,0,255, 2); + _assertPixelApprox(canvas, 55,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 105,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 205,5, 0,255,0,255, 2); + // Without the last character. + renderClusters(tm.getTextClusters(0, 4), 0, 100); + _assertPixelApprox(canvas, 5,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 55,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 105,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 205,105, 255,0,0,255, 2); + // Only the middle character. + renderClusters(tm.getTextClusters(2, 3), 0, 150); + _assertPixelApprox(canvas, 5,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 55,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 105,155, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 205,155, 255,0,0,255, 2); + +}, "Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text."); +</script> + diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html new file mode 100644 index 00000000000..967ae7e4636 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-align.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-align.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textAlign from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(3, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_align_left</div> + <canvas id="canvas0" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'left'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_align_center</div> + <canvas id="canvas1" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'center'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_align_right</div> + <canvas id="canvas2" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'right'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html new file mode 100644 index 00000000000..159efb4fee4 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-align.tentative.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-align.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-align.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-align.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textAlign from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(3, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_align_left</div> + <canvas id="canvas0" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'left'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +<span> + <div>ctx_align_center</div> + <canvas id="canvas1" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'center'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +<span> + <div>ctx_align_right</div> + <canvas id="canvas2" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'right'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html new file mode 100644 index 00000000000..2dffe90aadc --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-baseline.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-baseline.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textBaseline from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(4, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_baseline_top</div> + <canvas id="canvas0" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'top'; + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_baseline_middle</div> + <canvas id="canvas1" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'middle'; + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_baseline_bottom</div> + <canvas id="canvas2" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'bottom'; + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_baseline_alphabetic</div> + <canvas id="canvas3" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'alphabetic'; + ctx.fillText(text, x, y); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html new file mode 100644 index 00000000000..c20e076a351 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html @@ -0,0 +1,116 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-baseline.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-baseline.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textBaseline from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(4, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_baseline_top</div> + <canvas id="canvas0" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +<span> + <div>ctx_baseline_middle</div> + <canvas id="canvas1" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'middle'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +<span> + <div>ctx_baseline_bottom</div> + <canvas id="canvas2" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'bottom'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +<span> + <div>ctx_baseline_alphabetic</div> + <canvas id="canvas3" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'alphabetic'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html new file mode 100644 index 00000000000..9a9443962df --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-font-change.tentative</title> +<h1>2d.text.measure.text-clusters-rendering-font-change.tentative</h1> +<p class="desc">Test that fillTextCluster() renders in the font used originally when the text was measured, even if the font set on the context has changed since.</p> +<canvas id="canvas" width="500" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + const x = 100; + const y = 100; + ctx.fillText(text, x, y); +</script> diff --git a/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative.html b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative.html new file mode 100644 index 00000000000..a927cfcd330 --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/text/2d.text.measure.text-clusters-rendering-font-change.tentative.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-font-change.tentative</title> +<h1>2d.text.measure.text-clusters-rendering-font-change.tentative</h1> +<p class="desc">Test that fillTextCluster() renders in the font used originally when the text was measured, even if the font set on the context has changed since.</p> +<canvas id="canvas" width="500" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + ctx.font = '80px serif'; + + const x = 100; + const y = 100; + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } +</script> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html new file mode 100644 index 00000000000..eea78248a83 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html new file mode 100644 index 00000000000..72b23aeeafb --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html @@ -0,0 +1,949 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..2318c1ec94e --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html new file mode 100644 index 00000000000..89f4dba75b5 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html @@ -0,0 +1,1316 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.drawImage</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.js new file mode 100644 index 00000000000..45329fcd9c8 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.worker.js @@ -0,0 +1,685 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.filter.no_shadow.drawImage +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html new file mode 100644 index 00000000000..08ed3566fd1 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html new file mode 100644 index 00000000000..3f8fdc8164d --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html @@ -0,0 +1,871 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..2318c1ec94e --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html new file mode 100644 index 00000000000..37839bf8a8b --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html @@ -0,0 +1,1238 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.fillRect</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.js new file mode 100644 index 00000000000..dff55436a40 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.worker.js @@ -0,0 +1,607 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.filter.no_shadow.fillRect +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html new file mode 100644 index 00000000000..22c84f42e89 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html new file mode 100644 index 00000000000..0bb970ab3f8 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html @@ -0,0 +1,975 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..2318c1ec94e --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html new file mode 100644 index 00000000000..81d0a8e6a69 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html @@ -0,0 +1,1342 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.filter.no_shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.no_shadow.pattern</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.js new file mode 100644 index 00000000000..d3e79cd2d15 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.worker.js @@ -0,0 +1,711 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.filter.no_shadow.pattern +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html new file mode 100644 index 00000000000..2072348f904 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html new file mode 100644 index 00000000000..5c9e992c7ce --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html @@ -0,0 +1,1001 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..fde78773116 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html new file mode 100644 index 00000000000..08e66abd464 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html @@ -0,0 +1,1368 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.filter.shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.drawImage</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.js new file mode 100644 index 00000000000..9a9c2f93632 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.worker.js @@ -0,0 +1,737 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.filter.shadow.drawImage +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html new file mode 100644 index 00000000000..1e119bcbde5 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html new file mode 100644 index 00000000000..0f6b88fd5e9 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html @@ -0,0 +1,923 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..fde78773116 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html new file mode 100644 index 00000000000..f754f538b56 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html @@ -0,0 +1,1290 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.filter.shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.fillRect</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.js new file mode 100644 index 00000000000..f495009b301 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.worker.js @@ -0,0 +1,659 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.filter.shadow.fillRect +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern-expected.html new file mode 100644 index 00000000000..f45fe82c302 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html new file mode 100644 index 00000000000..e89aff9196d --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html @@ -0,0 +1,1027 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.filter.shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..fde78773116 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html new file mode 100644 index 00000000000..79f7aab01cd --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html @@ -0,0 +1,1394 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.filter.shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.filter.shadow.pattern</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.js new file mode 100644 index 00000000000..d960d0d5401 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.worker.js @@ -0,0 +1,763 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.filter.shadow.pattern +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html new file mode 100644 index 00000000000..923d8360a9d --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.no_shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html new file mode 100644 index 00000000000..54a53b46576 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html @@ -0,0 +1,949 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..ce392a1dccc --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html new file mode 100644 index 00000000000..4750ed210ff --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html @@ -0,0 +1,1316 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.drawImage</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.js new file mode 100644 index 00000000000..de1686a76e8 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.worker.js @@ -0,0 +1,685 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.no_filter.no_shadow.drawImage +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html new file mode 100644 index 00000000000..c809e56cac3 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.no_shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html new file mode 100644 index 00000000000..e69af8a79a9 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html @@ -0,0 +1,871 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..ce392a1dccc --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html new file mode 100644 index 00000000000..0cfc23ab86a --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html @@ -0,0 +1,1238 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.fillRect</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.js new file mode 100644 index 00000000000..cb60645b704 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.worker.js @@ -0,0 +1,607 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.no_filter.no_shadow.fillRect +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html new file mode 100644 index 00000000000..f052442a637 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.no_shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html new file mode 100644 index 00000000000..b6008b7c79f --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html @@ -0,0 +1,975 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..ce392a1dccc --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html new file mode 100644 index 00000000000..ef952ce12cd --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html @@ -0,0 +1,1342 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.no_filter.no_shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.no_shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.no_shadow.pattern</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.js new file mode 100644 index 00000000000..e1479261ce2 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.worker.js @@ -0,0 +1,711 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.no_filter.no_shadow.pattern +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + // No shadow. + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html new file mode 100644 index 00000000000..ad07c35d310 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.drawImage</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.shadow.drawImage.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html new file mode 100644 index 00000000000..d25f183aeb8 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html @@ -0,0 +1,1001 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.drawImage</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.png Binary files differnew file mode 100644 index 00000000000..aca03a61b22 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html new file mode 100644 index 00000000000..c66b467d627 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html @@ -0,0 +1,1368 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.drawImage-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.drawImage</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.drawImage</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.js new file mode 100644 index 00000000000..c7827238f69 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.worker.js @@ -0,0 +1,737 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.no_filter.shadow.drawImage +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.drawImage(img_canvas, 5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html new file mode 100644 index 00000000000..e16a5fcf458 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.fillRect</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.shadow.fillRect.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html new file mode 100644 index 00000000000..3fdbfa72caf --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html @@ -0,0 +1,923 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.fillRect</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.png Binary files differnew file mode 100644 index 00000000000..aca03a61b22 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html new file mode 100644 index 00000000000..519631612f0 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html @@ -0,0 +1,1290 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.fillRect-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.fillRect</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.fillRect</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.js new file mode 100644 index 00000000000..217fe38a8de --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.worker.js @@ -0,0 +1,659 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.no_filter.shadow.fillRect +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html new file mode 100644 index 00000000000..01e1d4d7b26 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern-expected.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.pattern</h1> +<p></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-in</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-out</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px 0px; + object-fit: none;"> +</span> + +<span> + <div>source-atop</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-over</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-in</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px 0px; + object-fit: none;"> +</span> + +<span> + <div>destination-out</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -60px; + object-fit: none;"> +</span> + +<span> + <div>destination-atop</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -60px; + object-fit: none;"> +</span> + +<span> + <div>lighter</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -60px; + object-fit: none;"> +</span> + +<span> + <div>copy</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -60px; + object-fit: none;"> +</span> + +<span> + <div>xor</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -60px; + object-fit: none;"> +</span> + +<span> + <div>multiply</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -60px; + object-fit: none;"> +</span> + +<span> + <div>screen</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -120px; + object-fit: none;"> +</span> + +<span> + <div>overlay</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -120px; + object-fit: none;"> +</span> + +<span> + <div>darken</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -120px; + object-fit: none;"> +</span> + +<span> + <div>lighten</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-dodge</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -120px; + object-fit: none;"> +</span> + +<span> + <div>color-burn</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -120px; + object-fit: none;"> +</span> + +<span> + <div>hard-light</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -180px; + object-fit: none;"> +</span> + +<span> + <div>soft-light</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -180px; + object-fit: none;"> +</span> + +<span> + <div>difference</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -160px -180px; + object-fit: none;"> +</span> + +<span> + <div>exclusion</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -240px -180px; + object-fit: none;"> +</span> + +<span> + <div>hue</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -320px -180px; + object-fit: none;"> +</span> + +<span> + <div>saturation</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -400px -180px; + object-fit: none;"> +</span> + +<span> + <div>color</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: 0px -240px; + object-fit: none;"> +</span> + +<span> + <div>luminosity</div> + <img src="2d.composite.grid.no_filter.shadow.pattern.png" + style="outline: 1px solid; + width: 80px; + height: 60px; + object-position: -80px -240px; + object-fit: none;"> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html new file mode 100644 index 00000000000..d9df6be84f1 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html @@ -0,0 +1,1027 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.pattern</h1> +<p class="desc"></p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas4"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas5"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas6"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas7"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas8"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas9"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas10"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas11"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas12"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas13"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas14"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas15"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas16"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas17"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas18"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas19"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas20"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas21"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas22"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas23"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas24"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const outputCanvas = document.getElementById("canvas25"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.png b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.png Binary files differnew file mode 100644 index 00000000000..aca03a61b22 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.png diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html new file mode 100644 index 00000000000..5c698e8c760 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html @@ -0,0 +1,1394 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.composite.grid.no_filter.shadow.pattern-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-10210"> +<title>Canvas test: 2d.composite.grid.no_filter.shadow.pattern</title> +<h1 style="font-size: 20px;">2d.composite.grid.no_filter.shadow.pattern</h1> +<p class="desc"></p> +<script>pending_tests = 26;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(6, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>source-over</div> + <canvas id="canvas0" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-in</div> + <canvas id="canvas1" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-out</div> + <canvas id="canvas2" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>source-atop</div> + <canvas id="canvas3" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-over</div> + <canvas id="canvas4" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker4" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker4').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas4'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-in</div> + <canvas id="canvas5" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker5" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker5').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas5'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-out</div> + <canvas id="canvas6" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker6" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker6').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas6'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>destination-atop</div> + <canvas id="canvas7" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker7" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker7').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas7'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighter</div> + <canvas id="canvas8" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker8" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker8').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas8'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>copy</div> + <canvas id="canvas9" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker9" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker9').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas9'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>xor</div> + <canvas id="canvas10" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker10" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker10').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas10'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>multiply</div> + <canvas id="canvas11" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker11" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker11').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas11'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>screen</div> + <canvas id="canvas12" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker12" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker12').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas12'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>overlay</div> + <canvas id="canvas13" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker13" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker13').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas13'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>darken</div> + <canvas id="canvas14" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker14" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker14').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas14'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>lighten</div> + <canvas id="canvas15" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker15" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker15').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas15'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-dodge</div> + <canvas id="canvas16" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker16" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker16').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas16'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color-burn</div> + <canvas id="canvas17" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker17" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker17').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas17'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hard-light</div> + <canvas id="canvas18" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker18" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker18').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas18'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>soft-light</div> + <canvas id="canvas19" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker19" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker19').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas19'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>difference</div> + <canvas id="canvas20" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker20" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker20').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas20'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>exclusion</div> + <canvas id="canvas21" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker21" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker21').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas21'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>hue</div> + <canvas id="canvas22" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker22" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker22').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas22'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>saturation</div> + <canvas id="canvas23" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker23" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker23').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas23'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>color</div> + <canvas id="canvas24" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker24" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker24').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas24'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>luminosity</div> + <canvas id="canvas25" width="80" height="60" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker25" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker25').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas25'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.js b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.js new file mode 100644 index 00000000000..f26657b5214 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.worker.js @@ -0,0 +1,763 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.composite.grid.no_filter.shadow.pattern +// Description: +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'source-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-over' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-in' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-out' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'destination-atop' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighter' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'copy' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'xor' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'multiply' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'screen' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'overlay' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'darken' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'lighten' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-dodge' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color-burn' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hard-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'soft-light' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'difference' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'exclusion' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'hue' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'saturation' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'color' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +test(t => { + const canvas = new OffscreenCanvas(80, 60); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + // No filter. + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + + ctx.globalCompositeOperation = 'luminosity' + + const img_canvas = new OffscreenCanvas(80, 60); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, 80, 60); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); +}, ""); + +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png Binary files differindex 8021427a07d..70d7b046cb2 100644 --- a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png Binary files differindex 8021427a07d..70d7b046cb2 100644 --- a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png Binary files differindex 8021427a07d..70d7b046cb2 100644 --- a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png Binary files differindex d4f6dc1ee88..fb3b5b830d3 100644 --- a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html new file mode 100644 index 00000000000..780a4f52623 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>OffscreenCanvas test: 2d.text.measure.text-clusters-position.tentative</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.text.measure.text-clusters-position.tentative</h1> +<p class="desc">Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.</p> + + +<script> +promise_test(async t => { + + var canvas = new OffscreenCanvas(500, 500); + var ctx = canvas.getContext('2d'); + + var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')"); + f.load(); + document.fonts.add(f); + await document.fonts.ready; + ctx.font = '40px CanvasTest'; + const text = 'E'; + + // Origin for all the measurements is placed at the top left corner. + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + + // X position. + _assertSame(Math.abs(tm.getTextClusters({align: 'left'})[0].x), 0, "Math.abs(tm.getTextClusters({align: 'left'})[\""+(0)+"\"].x)", "0"); + _assertSame(tm.getTextClusters({align: 'center'})[0].x, 20, "tm.getTextClusters({align: 'center'})[\""+(0)+"\"].x", "20"); + _assertSame(tm.getTextClusters({align: 'right'})[0].x, 40, "tm.getTextClusters({align: 'right'})[\""+(0)+"\"].x", "40"); + + // Y position. + _assertSame(Math.abs(tm.getTextClusters({baseline: 'top'})[0].y), 0, "Math.abs(tm.getTextClusters({baseline: 'top'})[\""+(0)+"\"].y)", "0"); + _assertSame(tm.getTextClusters({baseline: 'middle'})[0].y, 20, "tm.getTextClusters({baseline: 'middle'})[\""+(0)+"\"].y", "20"); + _assertSame(tm.getTextClusters({baseline: 'bottom'})[0].y, 40, "tm.getTextClusters({baseline: 'bottom'})[\""+(0)+"\"].y", "40"); + _assertSame(tm.getTextClusters({baseline: 'alphabetic'})[0].y, 30, "tm.getTextClusters({baseline: 'alphabetic'})[\""+(0)+"\"].y", "30"); + +}, "Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options."); +</script> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js new file mode 100644 index 00000000000..90ee50fa50f --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-position.tentative.worker.js @@ -0,0 +1,36 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.text.measure.text-clusters-position.tentative +// Description:Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +promise_test(async t => { + var canvas = new OffscreenCanvas(500, 500); + var ctx = canvas.getContext('2d'); + + var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')"); + f.load(); + self.fonts.add(f); + await self.fonts.ready; + ctx.font = '40px CanvasTest'; + const text = 'E'; + + // Origin for all the measurements is placed at the top left corner. + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + + // X position. + _assertSame(Math.abs(tm.getTextClusters({align: 'left'})[0].x), 0, "Math.abs(tm.getTextClusters({align: 'left'})[\""+(0)+"\"].x)", "0"); + _assertSame(tm.getTextClusters({align: 'center'})[0].x, 20, "tm.getTextClusters({align: 'center'})[\""+(0)+"\"].x", "20"); + _assertSame(tm.getTextClusters({align: 'right'})[0].x, 40, "tm.getTextClusters({align: 'right'})[\""+(0)+"\"].x", "40"); + + // Y position. + _assertSame(Math.abs(tm.getTextClusters({baseline: 'top'})[0].y), 0, "Math.abs(tm.getTextClusters({baseline: 'top'})[\""+(0)+"\"].y)", "0"); + _assertSame(tm.getTextClusters({baseline: 'middle'})[0].y, 20, "tm.getTextClusters({baseline: 'middle'})[\""+(0)+"\"].y", "20"); + _assertSame(tm.getTextClusters({baseline: 'bottom'})[0].y, 40, "tm.getTextClusters({baseline: 'bottom'})[\""+(0)+"\"].y", "40"); + _assertSame(tm.getTextClusters({baseline: 'alphabetic'})[0].y, 30, "tm.getTextClusters({baseline: 'alphabetic'})[\""+(0)+"\"].y", "30"); +}, "Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options."); +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html new file mode 100644 index 00000000000..9bd2a026618 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>OffscreenCanvas test: 2d.text.measure.text-clusters-range.tentative</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.text.measure.text-clusters-range.tentative</h1> +<p class="desc">Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text.</p> + + +<script> +promise_test(async t => { + + var canvas = new OffscreenCanvas(400, 300); + var ctx = canvas.getContext('2d'); + + // Renders all the clusters in the list from position (x, y). + function renderClusters(clusters, x, y) { + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + } + + var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')"); + f.load(); + document.fonts.add(f); + await document.fonts.ready; + + ctx.font = '50px CanvasTest'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + const text = 'EEEEE'; + let tm = ctx.measureText(text); + + // Background color. + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + ctx.fillStyle = '#0f0'; + + // Without the first character. + renderClusters(tm.getTextClusters(1, 5), 0, 0); + _assertPixelApprox(canvas, 5,5, 255,0,0,255, 2); + _assertPixelApprox(canvas, 55,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 105,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 205,5, 0,255,0,255, 2); + // Without the last character. + renderClusters(tm.getTextClusters(0, 4), 0, 100); + _assertPixelApprox(canvas, 5,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 55,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 105,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 205,105, 255,0,0,255, 2); + // Only the middle character. + renderClusters(tm.getTextClusters(2, 3), 0, 150); + _assertPixelApprox(canvas, 5,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 55,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 105,155, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 205,155, 255,0,0,255, 2); + +}, "Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text."); +</script> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js new file mode 100644 index 00000000000..db76d19edf3 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-range.tentative.worker.js @@ -0,0 +1,59 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.text.measure.text-clusters-range.tentative +// Description:Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +promise_test(async t => { + var canvas = new OffscreenCanvas(400, 300); + var ctx = canvas.getContext('2d'); + + // Renders all the clusters in the list from position (x, y). + function renderClusters(clusters, x, y) { + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + } + + var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')"); + f.load(); + self.fonts.add(f); + await self.fonts.ready; + + ctx.font = '50px CanvasTest'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + const text = 'EEEEE'; + let tm = ctx.measureText(text); + + // Background color. + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + ctx.fillStyle = '#0f0'; + + // Without the first character. + renderClusters(tm.getTextClusters(1, 5), 0, 0); + _assertPixelApprox(canvas, 5,5, 255,0,0,255, 2); + _assertPixelApprox(canvas, 55,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 105,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,5, 0,255,0,255, 2); + _assertPixelApprox(canvas, 205,5, 0,255,0,255, 2); + // Without the last character. + renderClusters(tm.getTextClusters(0, 4), 0, 100); + _assertPixelApprox(canvas, 5,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 55,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 105,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,105, 0,255,0,255, 2); + _assertPixelApprox(canvas, 205,105, 255,0,0,255, 2); + // Only the middle character. + renderClusters(tm.getTextClusters(2, 3), 0, 150); + _assertPixelApprox(canvas, 5,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 55,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 105,155, 0,255,0,255, 2); + _assertPixelApprox(canvas, 155,155, 255,0,0,255, 2); + _assertPixelApprox(canvas, 205,155, 255,0,0,255, 2); +}, "Test that getTextClusters() and fillTextCluster() correctly render different ranges of the input text."); +done(); diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html new file mode 100644 index 00000000000..967ae7e4636 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative-expected.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-align.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-align.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textAlign from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(3, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_align_left</div> + <canvas id="canvas0" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'left'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_align_center</div> + <canvas id="canvas1" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'center'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_align_right</div> + <canvas id="canvas2" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'right'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html new file mode 100644 index 00000000000..4fc41c79cc4 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.html @@ -0,0 +1,102 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-align.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-align.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-align.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textAlign from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(3, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_align_left</div> + <canvas id="canvas0" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(250, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'left'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>ctx_align_center</div> + <canvas id="canvas1" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(250, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'center'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>ctx_align_right</div> + <canvas id="canvas2" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(250, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'right'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html new file mode 100644 index 00000000000..35ddd54bfd7 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-align.tentative.w.html @@ -0,0 +1,147 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-align.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-align.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-align.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textAlign from the context at the time the text was measured.</p> +<script>pending_tests = 3;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(3, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_align_left</div> + <canvas id="canvas0" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(250, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'left'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>ctx_align_center</div> + <canvas id="canvas1" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(250, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'center'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>ctx_align_right</div> + <canvas id="canvas2" width="250" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(250, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = 'right'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html new file mode 100644 index 00000000000..2dffe90aadc --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-baseline.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-baseline.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textBaseline from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(4, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_baseline_top</div> + <canvas id="canvas0" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas0"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'top'; + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_baseline_middle</div> + <canvas id="canvas1" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas1"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'middle'; + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_baseline_bottom</div> + <canvas id="canvas2" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas2"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'bottom'; + ctx.fillText(text, x, y); + </script> +</span> + +<span> + <div>ctx_baseline_alphabetic</div> + <canvas id="canvas3" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = document.getElementById("canvas3"); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'alphabetic'; + ctx.fillText(text, x, y); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html new file mode 100644 index 00000000000..84def142a9b --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.html @@ -0,0 +1,132 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-baseline.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-baseline.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textBaseline from the context at the time the text was measured.</p> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(4, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_baseline_top</div> + <canvas id="canvas0" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas0"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>ctx_baseline_middle</div> + <canvas id="canvas1" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'middle'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas1"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>ctx_baseline_bottom</div> + <canvas id="canvas2" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'bottom'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas2"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +<span> + <div>ctx_baseline_alphabetic</div> + <canvas id="canvas3" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script type="module"> + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'alphabetic'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas3"); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(canvas, 0, 0); + </script> +</span> + +</div> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html new file mode 100644 index 00000000000..9227776d8c8 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-baseline.tentative.w.html @@ -0,0 +1,191 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-baseline.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-baseline.tentative</title> +<h1 style="font-size: 20px;">2d.text.measure.text-clusters-rendering-baseline.tentative</h1> +<p class="desc">Test that fillTextCluster() correctly positions the text, taking into account the textBaseline from the context at the time the text was measured.</p> +<script>pending_tests = 4;</script> + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat(4, max-content); + font-size: 13px; text-align: center;"> +<span> + <div>ctx_baseline_top</div> + <canvas id="canvas0" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker0" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker0').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas0'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>ctx_baseline_middle</div> + <canvas id="canvas1" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker1" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'middle'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker1').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas1'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>ctx_baseline_bottom</div> + <canvas id="canvas2" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker2" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'bottom'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker2').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas2'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +<span> + <div>ctx_baseline_alphabetic</div> + <canvas id="canvas3" width="180" height="43" style="outline: 1px solid"> + <p class="fallback">FAIL (fallback content)</p> + </canvas> + <script id="myWorker3" type="text/worker"> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(180, 43); + const ctx = canvas.getContext('2d'); + + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = 'alphabetic'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; + </script> + <script type="module"> + const blob = new Blob([document.getElementById('myWorker3').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCanvas = document.getElementById('canvas3'); + const outputCtx = outputCanvas.getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + if (--pending_tests == 0) { + document.documentElement.classList.remove('reftest-wait'); + } + }); + worker.postMessage(null); + </script> +</span> + +</div> +</html> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html new file mode 100644 index 00000000000..9a9443962df --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-font-change.tentative</title> +<h1>2d.text.measure.text-clusters-rendering-font-change.tentative</h1> +<p class="desc">Test that fillTextCluster() renders in the font used originally when the text was measured, even if the font set on the context has changed since.</p> +<canvas id="canvas" width="500" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + const x = 100; + const y = 100; + ctx.fillText(text, x, y); +</script> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.html new file mode 100644 index 00000000000..c8e3383a462 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-font-change.tentative</title> +<h1>2d.text.measure.text-clusters-rendering-font-change.tentative</h1> +<p class="desc">Test that fillTextCluster() renders in the font used originally when the text was measured, even if the font set on the context has changed since.</p> +<canvas id="canvas" width="500" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(500, 200); + const ctx = canvas.getContext('2d'); + + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + ctx.font = '80px serif'; + + const x = 100; + const y = 100; + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html new file mode 100644 index 00000000000..6bca8ebbc35 --- /dev/null +++ b/tests/wpt/tests/html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-font-change.tentative.w.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<meta charset="UTF-8"> +<html class="reftest-wait"> +<link rel="match" href="2d.text.measure.text-clusters-rendering-font-change.tentative-expected.html"> +<title>Canvas test: 2d.text.measure.text-clusters-rendering-font-change.tentative</title> +<h1>2d.text.measure.text-clusters-rendering-font-change.tentative</h1> +<p class="desc">Test that fillTextCluster() renders in the font used originally when the text was measured, even if the font set on the context has changed since.</p> +<canvas id="canvas" width="500" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(500, 200); + const ctx = canvas.getContext('2d'); + + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + ctx.font = '80px serif'; + + const x = 100; + const y = 100; + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/tests/wpt/tests/html/canvas/tools/gentestutilsunion.py b/tests/wpt/tests/html/canvas/tools/gentestutilsunion.py index 2ec2e20886b..629b596b513 100644 --- a/tests/wpt/tests/html/canvas/tools/gentestutilsunion.py +++ b/tests/wpt/tests/html/canvas/tools/gentestutilsunion.py @@ -39,6 +39,7 @@ import dataclasses import enum import importlib import itertools +import math import os import pathlib import sys @@ -257,6 +258,7 @@ class _CanvasType(str, enum.Enum): class _TemplateType(str, enum.Enum): REFERENCE = 'reference' HTML_REFERENCE = 'html_reference' + CAIRO_REFERENCE = 'cairo_reference' TESTHARNESS = 'testharness' @@ -338,12 +340,18 @@ def _write_cairo_images(pycairo_code: str, output_files: _OutputPaths, if _CanvasType.HTML_CANVAS in canvas_types: full_code = (f'{pycairo_code}\n' f'surface.write_to_png("{output_files.element}")\n') - eval(compile(full_code, '<string>', 'exec'), {'cairo': cairo}) + eval(compile(full_code, '<string>', 'exec'), { + 'cairo': cairo, + 'math': math, + }) if {_CanvasType.OFFSCREEN_CANVAS, _CanvasType.WORKER} & canvas_types: full_code = (f'{pycairo_code}\n' f'surface.write_to_png("{output_files.offscreen}")\n') - eval(compile(full_code, '<string>', 'exec'), {'cairo': cairo}) + eval(compile(full_code, '<string>', 'exec'), { + 'cairo': cairo, + 'math': math, + }) class _Variant(): @@ -452,15 +460,21 @@ class _Variant(): return frozenset(_CanvasType(t) for t in canvas_types) def _get_template_type(self) -> _TemplateType: - if 'reference' in self.params and 'html_reference' in self.params: + reference_types = (('reference' in self.params) + + ('html_reference' in self.params) + + ('cairo_reference' in self.params)) + if reference_types > 1: raise InvalidTestDefinitionError( - f'Test {self.params["name"]} is invalid, "reference" and ' - '"html_reference" can\'t both be specified at the same time.') + f'Test {self.params["name"]} is invalid, only one of ' + '"reference", "html_reference" or "cairo_reference" can be ' + 'specified at the same time.') if 'reference' in self.params: return _TemplateType.REFERENCE if 'html_reference' in self.params: return _TemplateType.HTML_REFERENCE + if 'cairo_reference' in self.params: + return _TemplateType.CAIRO_REFERENCE return _TemplateType.TESTHARNESS def finalize_params(self, jinja_env: jinja2.Environment, @@ -476,13 +490,10 @@ class _Variant(): if isinstance(self._params['size'], list): self._params['size'] = tuple(self._params['size']) - if 'reference' in self._params: - self._params['reference'] = _preprocess_code( - jinja_env, self._params['reference'], self._params) - - if 'html_reference' in self._params: - self._params['html_reference'] = _preprocess_code( - jinja_env, self._params['html_reference'], self._params) + for ref_type in {'reference', 'html_reference', 'cairo_reference'}: + if ref_type in self._params: + self._params[ref_type] = _preprocess_code( + jinja_env, self._params[ref_type], self._params) code_params = dict(self.params) if _CanvasType.HTML_CANVAS in self.params['canvas_types']: @@ -503,7 +514,7 @@ class _Variant(): _validate_test(self._params) def generate_expected_image(self, output_dirs: _OutputPaths) -> None: - """Creates a reference image using Cairo and save filename in params.""" + """Creates an expected image using Cairo and save filename in params.""" expected = self.params['expected'] if expected == 'green': @@ -660,7 +671,8 @@ class _VariantGrid: 'fonts': self._param_set('fonts'), } if self.template_type in (_TemplateType.REFERENCE, - _TemplateType.HTML_REFERENCE): + _TemplateType.HTML_REFERENCE, + _TemplateType.CAIRO_REFERENCE): grid_params['desc'] = self._unique_param('desc') return grid_params @@ -692,9 +704,12 @@ class _VariantGrid: f'{output_files.offscreen}.w.html') params['is_test_reference'] = True - is_html_ref = self.template_type == _TemplateType.HTML_REFERENCE - ref_template_name = (f'reftest{grid}.html' - if is_html_ref else f'reftest_element{grid}.html') + templates = { + _TemplateType.REFERENCE: f'reftest_element{grid}.html', + _TemplateType.HTML_REFERENCE: f'reftest{grid}.html', + _TemplateType.CAIRO_REFERENCE: f'reftest_img{grid}.html' + } + ref_template_name = templates[self.template_type] if _CanvasType.HTML_CANVAS in self.canvas_types: _render(jinja_env, ref_template_name, params, @@ -727,9 +742,72 @@ class _VariantGrid: _render(jinja_env, f'testharness_worker{grid}.js', self.params, f'{output_files.offscreen}.worker.js') + def _generate_cairo_reference_grid(self, + output_dirs: _OutputPaths) -> None: + """Generate this grid's expected image from Cairo code, if needed. + + In order to cut on the number of files generated, the expected image + of all the variants in this grid are packed into a single PNG. The + expected HTML then contains a grid of <img> tags, each showing a portion + of the PNG file.""" + if not any(v.params.get('cairo_reference') for v in self.variants): + return + + width, height = self._unique_param('size') + cairo_code = '' + + # First generate a function producing a Cairo surface with the expected + # image for each variant in the grid. The function is needed to provide + # a scope isolating the variant code from each other. + for idx, variant in enumerate(self._variants): + cairo_ref = variant.params.get('cairo_reference') + if not cairo_ref: + raise InvalidTestDefinitionError( + 'When used, "cairo_reference" must be specified for all ' + 'test variants.') + cairo_code += textwrap.dedent(f'''\ + def draw_ref{idx}(): + surface = cairo.ImageSurface( + cairo.FORMAT_ARGB32, {width}, {height}) + cr = cairo.Context(surface) + {{}} + return surface + ''').format(textwrap.indent(cairo_ref, ' ')) + + # Write all variant images into the final surface. + surface_width = width * self._grid_width + surface_height = (height * + math.ceil(len(self._variants) / self._grid_width)) + cairo_code += textwrap.dedent(f'''\ + surface = cairo.ImageSurface( + cairo.FORMAT_ARGB32, {surface_width}, {surface_height}) + cr = cairo.Context(surface) + ''') + for idx, variant in enumerate(self._variants): + x_pos = int(idx % self._grid_width) * width + y_pos = int(idx / self._grid_width) * height + cairo_code += textwrap.dedent(f'''\ + cr.set_source_surface(draw_ref{idx}(), {x_pos}, {y_pos}) + cr.paint() + ''') + + img_filename = f'{self.file_name}.png' + _write_cairo_images(cairo_code, output_dirs.sub_path(img_filename), + self.canvas_types) + self._params['img_reference'] = img_filename + def _generate_cairo_images(self, output_dirs: _OutputPaths) -> None: """Generates the pycairo images found in the YAML test definition.""" - if any(v.params.get('expected') for v in self._variants): + has_expected = any(v.params.get('expected') for v in self._variants) + has_cairo_reference = any( + v.params.get('cairo_reference') for v in self._variants) + + if has_expected and has_cairo_reference: + raise InvalidTestDefinitionError( + 'Parameters "expected" and "cairo_reference" can\'t be both ' + 'used at the same time.') + + if has_expected: if len(self.variants) != 1: raise InvalidTestDefinitionError( 'Parameter "expected" is not supported for variant grids.') @@ -738,6 +816,8 @@ class _VariantGrid: 'Parameter "expected" is not supported in reference ' 'tests.') self.variants[0].generate_expected_image(output_dirs) + elif has_cairo_reference: + self._generate_cairo_reference_grid(output_dirs) def generate_test(self, jinja_env: jinja2.Environment, output_dirs: _OutputPaths) -> None: @@ -747,7 +827,8 @@ class _VariantGrid: output_files = output_dirs.sub_path(self.file_name) if self.template_type in (_TemplateType.REFERENCE, - _TemplateType.HTML_REFERENCE): + _TemplateType.HTML_REFERENCE, + _TemplateType.CAIRO_REFERENCE): self._write_reference_test(jinja_env, output_files) else: self._write_testharness_test(jinja_env, output_files) @@ -803,6 +884,9 @@ def _get_variant_grids(test: Mapping[str, Any], jinja_env: jinja2.Environment) -> List[_VariantGrid]: base_variant = _Variant.create_with_defaults(test) grid_width = base_variant.params.get('grid_width', 1) + if not isinstance(grid_width, int): + raise InvalidTestDefinitionError('"grid_width" must be an integer.') + grids = [_VariantGrid([base_variant], grid_width=grid_width)] for dimension in _get_variant_dimensions(test): variants = dimension.variants diff --git a/tests/wpt/tests/html/canvas/tools/templates/reftest_img.html b/tests/wpt/tests/html/canvas/tools/templates/reftest_img.html new file mode 100644 index 00000000000..c058406d49a --- /dev/null +++ b/tests/wpt/tests/html/canvas/tools/templates/reftest_img.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: {{ name }}</title> +<h1>{{ name }}</h1> +<p>{{ desc }}</p> +{% if notes %}<p>{{ notes }}</p>{% endif %} + +<img src="{{ img_reference }}"> diff --git a/tests/wpt/tests/html/canvas/tools/templates/reftest_img_grid.html b/tests/wpt/tests/html/canvas/tools/templates/reftest_img_grid.html new file mode 100644 index 00000000000..20026c3e82c --- /dev/null +++ b/tests/wpt/tests/html/canvas/tools/templates/reftest_img_grid.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: {{ name }}</title> +<h1 style="font-size: 20px;">{{ name }}</h1> +<p>{{ desc }}</p> +{% if notes %}<p>{{ notes }}</p>{% endif %} + +<div style="display: grid; grid-gap: 4px; + grid-template-columns: repeat({{ grid_width }}, max-content); + font-size: 13px; text-align: center;"> +{% for variant in element_variants %} +<span> + {% for variant_name in variant.grid_variant_names %} + <div>{{ variant_name }}</div> + {% endfor %} + {% set x_pos = ((loop.index0 % grid_width) | int) * variant.size[0] %} + {% set y_pos = ((loop.index0 / grid_width) | int) * variant.size[1] %} + <img src="{{ img_reference }}" + style="outline: 1px solid; + width: {{ variant.size[0] }}px; + height: {{ variant.size[1] }}px; + object-position: {{ -x_pos }}px {{ -y_pos }}px; + object-fit: none;"> +</span> + +{% endfor %} +</div> diff --git a/tests/wpt/tests/html/canvas/tools/yaml-new/compositing.yaml b/tests/wpt/tests/html/canvas/tools/yaml-new/compositing.yaml index 6bd0aaad8a5..1db0c590db2 100644 --- a/tests/wpt/tests/html/canvas/tools/yaml-new/compositing.yaml +++ b/tests/wpt/tests/html/canvas/tools/yaml-new/compositing.yaml @@ -230,3 +230,179 @@ ctx.globalAlpha = 0.51; ctx.drawImage(offscreenCanvas2, 0, 0); @assert pixel 50,25 ==~ 0,255,0,130; + +- name: 2d.composite.grid + size: [80, 60] + code: | + ctx.fillStyle = 'rgb(0, 102, 255)'; + ctx.fillRect(15, 15, 50, 30); + + ctx.translate(25, 20); + ctx.rotate(Math.PI / 2); + ctx.scale(0.6, 1.2); + ctx.translate(-25, -20); + + ctx.globalAlpha = 0.5; + + {{ js_filter_code }} + {{ js_shadow_code }} + + ctx.globalCompositeOperation = '{{ variant_names[0] }}' + + {{ js_draw_code }} + cairo_reference: | + # Background. + cr.push_group() + cr.set_source_rgb(0, 102/255, 1) + cr.rectangle(15, 15, 50, 30) + cr.fill() + background = cr.pop_group() + + # Foreground. + cr.push_group() + cr.translate(25, 20) + cr.rotate(math.pi / 2) + cr.scale(0.6, 1.2) + cr.translate(-25, -20) + cr.set_source_rgba(52/255, 1, 52/255, 0.5) + cr.rectangle(5, 5, 50, 30) + cr.fill() + foreground = cr.pop_group() + + # Filtered foreground. + cr.push_group() + {{ cairo_filter_code }} + cr.set_source(foreground) + cr.paint() + filtered_foreground = cr.pop_group() + + {% if cairo_operator != 'SOURCE' %} + cr.set_source(background) + cr.paint() + {% endif %} + + cr.set_operator(cairo.OPERATOR_{{ cairo_operator }}) + + {% if cairo_operator != 'SOURCE' %} + {{ cairo_shadow_code }} + {% endif %} + + cr.set_source(filtered_foreground) + cr.paint() + fuzzy: maxDifference=0-2; totalPixels=0-10210 + variants_layout: + - single_file + - multi_files + - multi_files + - multi_files + grid_width: 6 + variants: + - source-over: + cairo_operator: OVER + source-in: + cairo_operator: IN + source-out: + cairo_operator: OUT + source-atop: + cairo_operator: ATOP + destination-over: + cairo_operator: DEST_OVER + destination-in: + cairo_operator: DEST_IN + destination-out: + cairo_operator: DEST_OUT + destination-atop: + cairo_operator: DEST_ATOP + lighter: + cairo_operator: ADD + copy: + cairo_operator: SOURCE + xor: + cairo_operator: XOR + multiply: + cairo_operator: MULTIPLY + screen: + cairo_operator: SCREEN + overlay: + cairo_operator: OVERLAY + darken: + cairo_operator: DARKEN + lighten: + cairo_operator: LIGHTEN + color-dodge: + cairo_operator: COLOR_DODGE + color-burn: + cairo_operator: COLOR_BURN + hard-light: + cairo_operator: HARD_LIGHT + soft-light: + cairo_operator: SOFT_LIGHT + difference: + cairo_operator: DIFFERENCE + exclusion: + cairo_operator: EXCLUSION + hue: + cairo_operator: HSL_HUE + saturation: + cairo_operator: HSL_SATURATION + color: + cairo_operator: HSL_COLOR + luminosity: + cairo_operator: HSL_LUMINOSITY + + - no_filter: + js_filter_code: // No filter. + cairo_filter_code: "# No filter." + filter: + js_filter_code: ctx.filter = 'drop-shadow(5px -5px 0px rgb(255, 154, 0))' + cairo_filter_code: |- + cr.push_group() + cr.set_operator(cairo.OPERATOR_OVER) + cr.translate(5, -5) # Filter offset. + cr.set_source(foreground) + cr.paint() + cr.set_operator(cairo.OPERATOR_IN) + cr.set_source_rgba(1, 154/255, 0) + cr.paint() + cr.pop_group_to_source() + cr.paint() + + - no_shadow: + js_shadow_code: // No shadow. + cairo_shadow_code: "# No shadow." + shadow: + js_shadow_code: |- + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.shadowColor = 'rgb(154, 0, 154)'; + cairo_shadow_code: |- + cr.push_group() + cr.set_operator(cairo.OPERATOR_OVER) + cr.translate(20, 20) # Shadow offset. + cr.set_source(filtered_foreground) + cr.paint() + cr.set_operator(cairo.OPERATOR_IN) + cr.set_source_rgb(154/255, 0, 154/255) + cr.paint() + cr.pop_group_to_source() + cr.paint() + + - fillRect: + js_draw_code: |- + ctx.fillStyle = 'rgb(52, 255, 52)'; + ctx.fillRect(5, 5, 50, 30); + drawImage: + js_draw_code: |- + const img_canvas = new OffscreenCanvas({{ size[0] }}, {{ size[1] }}); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, {{ size[0] }}, {{ size[1] }}); + ctx.drawImage(img_canvas, 5, 5, 50, 30); + pattern: + js_draw_code: |- + const img_canvas = new OffscreenCanvas({{ size[0] }}, {{ size[1] }}); + const img_ctx = img_canvas.getContext('2d'); + img_ctx.fillStyle = 'rgb(52, 255, 52)'; + img_ctx.fillRect(0, 0, {{ size[0] }}, {{ size[1] }}); + ctx.fillStyle = ctx.createPattern(img_canvas, 'repeat'); + ctx.fillRect(5, 5, 50, 30); diff --git a/tests/wpt/tests/html/canvas/tools/yaml-new/text.yaml b/tests/wpt/tests/html/canvas/tools/yaml-new/text.yaml index 4c2ae798596..78312640c08 100644 --- a/tests/wpt/tests/html/canvas/tools/yaml-new/text.yaml +++ b/tests/wpt/tests/html/canvas/tools/yaml-new/text.yaml @@ -2020,6 +2020,200 @@ () => tm.getTextClusters(text.length, text.length + 1) ); } +- name: 2d.text.measure.text-clusters-position.tentative + desc: >- + Test that TextMetrics::getTextClusters() returns clusters that are + positioned according to the target align and baseline passed as options. + size: [500, 500] + test_type: promise + fonts: + - CanvasTest + code: | + {{ load_font }} + ctx.font = '40px CanvasTest'; + const text = 'E'; + + // Origin for all the measurements is placed at the top left corner. + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + let tm = ctx.measureText(text); + + // X position. + @assert Math.abs(tm.getTextClusters({align: 'left'})[0].x) === 0; + @assert tm.getTextClusters({align: 'center'})[0].x === 20; + @assert tm.getTextClusters({align: 'right'})[0].x === 40; + + // Y position. + @assert Math.abs(tm.getTextClusters({baseline: 'top'})[0].y) === 0; + @assert tm.getTextClusters({baseline: 'middle'})[0].y === 20; + @assert tm.getTextClusters({baseline: 'bottom'})[0].y === 40; + @assert tm.getTextClusters({baseline: 'alphabetic'})[0].y === 30; + variants: + - *load-font-variant-definition + +- name: 2d.text.measure.text-clusters-rendering-align.tentative + desc: >- + Test that fillTextCluster() correctly positions the text, taking into + account the textAlign from the context at the time the text was measured. + size: [250, 43] + code: | + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = '{{ ctx_align }}'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + reference: | + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = canvas.width / 2; + const y = canvas.height / 2; + + ctx.textAlign = '{{ ctx_align }}'; + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + ctx.fillText(text, x, y); + variants_layout: + [single_file] + variants: + - ctx_align_left: + ctx_align: left + ctx_align_center: + ctx_align: center + ctx_align_right: + ctx_align: right + +- name: 2d.text.measure.text-clusters-rendering-baseline.tentative + desc: >- + Test that fillTextCluster() correctly positions the text, taking into + account the textBaseline from the context at the time the text was measured. + size: [180, 43] + code: | + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = '{{ ctx_baseline }}'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + // Rendering all clusters with the same (x, y) parameters must be + // equivalent to a fillText() call at (x, y). + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + reference: | + ctx.font = '20px serif'; + const text = 'Test ☺️ א'; + const x = 20; + const y = canvas.height / 2; + + ctx.textBaseline = '{{ ctx_baseline }}'; + ctx.fillText(text, x, y); + variants_layout: + [single_file] + variants: + - ctx_baseline_top: + ctx_baseline: top + ctx_baseline_middle: + ctx_baseline: middle + ctx_baseline_bottom: + ctx_baseline: bottom + ctx_baseline_alphabetic: + ctx_baseline: alphabetic + +- name: 2d.text.measure.text-clusters-rendering-font-change.tentative + desc: >- + Test that fillTextCluster() renders in the font used originally when the + text was measured, even if the font set on the context has changed since. + size: [500, 200] + code: | + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + ctx.font = '80px serif'; + + const x = 100; + const y = 100; + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + reference: | + ctx.font = '50px sans-serif'; + const text = 'Hello ♦️ World!'; + let tm = ctx.measureText(text); + const clusters = tm.getTextClusters(); + + const x = 100; + const y = 100; + ctx.fillText(text, x, y); + +- name: 2d.text.measure.text-clusters-range.tentative + desc: >- + Test that getTextClusters() and fillTextCluster() correctly render + different ranges of the input text. + test_type: promise + fonts: + - CanvasTest + size: [400, 300] + code: | + // Renders all the clusters in the list from position (x, y). + function renderClusters(clusters, x, y) { + for (const cluster of clusters) { + ctx.fillTextCluster(cluster, x, y); + } + } + + {{ load_font }} + + ctx.font = '50px CanvasTest'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + const text = 'EEEEE'; + let tm = ctx.measureText(text); + + // Background color. + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + ctx.fillStyle = '#0f0'; + + // Without the first character. + renderClusters(tm.getTextClusters(1, 5), 0, 0); + @assert pixel 5,5 ==~ 255,0,0,255; + @assert pixel 55,5 ==~ 0,255,0,255; + @assert pixel 105,5 ==~ 0,255,0,255; + @assert pixel 155,5 ==~ 0,255,0,255; + @assert pixel 205,5 ==~ 0,255,0,255; + // Without the last character. + renderClusters(tm.getTextClusters(0, 4), 0, 100); + @assert pixel 5,105 ==~ 0,255,0,255; + @assert pixel 55,105 ==~ 0,255,0,255; + @assert pixel 105,105 ==~ 0,255,0,255; + @assert pixel 155,105 ==~ 0,255,0,255; + @assert pixel 205,105 ==~ 255,0,0,255; + // Only the middle character. + renderClusters(tm.getTextClusters(2, 3), 0, 150); + @assert pixel 5,155 ==~ 255,0,0,255; + @assert pixel 55,155 ==~ 255,0,0,255; + @assert pixel 105,155 ==~ 0,255,0,255; + @assert pixel 155,155 ==~ 255,0,0,255; + @assert pixel 205,155 ==~ 255,0,0,255; + variants: + - *load-font-variant-definition + - name: 2d.text.drawing.style.absolute.spacing desc: Testing letter spacing and word spacing with absolute length code: | diff --git a/tests/wpt/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html b/tests/wpt/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html index 3f76d85a1bc..111738a1444 100644 --- a/tests/wpt/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html +++ b/tests/wpt/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html @@ -52,7 +52,7 @@ test(function() { }, "An img name appears in a document's property names when the img has no id."); test(function() { - assert_true(names.includes("exposed_object")) + assert_true(names.includes("exposed_object_with_name")) }, "An object name appears in a document's property names if the object is exposed."); test(function() { diff --git a/tests/wpt/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html b/tests/wpt/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html new file mode 100644 index 00000000000..c5696df9de8 --- /dev/null +++ b/tests/wpt/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<title>innerText with white-space:pre-line</title> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1923829"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div id="a" style="white-space: pre-line">one two three four</div> + +<div id="b" style="white-space: pre">one two three four</div> + +<div id="c" style="white-space: pre-line"> + one + two + <!-- comment --> + three + four +</div> + +<div id="d" style="white-space: pre"> + one + two + <!-- comment --> + three + four +</div> + +<script> +test(() => { + assert_equals(a.innerText, b.innerText); +}, "innerText should be the same for the pre-line and pre examples"); + +test(() => { + function collapseWhitespace(s) { + return s.replace(/ +/g, ' ') // collapse runs of spaces + .replace(/ $/mg, '') // strip trailing spaces + .replace(/^ /mg, '') // strip leading spaces + .replace(/\n\n+/g, '\n') // collapse runs of newlines + .replace(/^\n/, ''); // remove any initial newline + } + assert_equals(c.innerText, collapseWhitespace(d.innerText)); +}, "innerText has collapsed whitespace but preserved newlines with pre-line"); +</script> diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/tables/table-align-float-ref.xhtml b/tests/wpt/tests/html/rendering/non-replaced-elements/tables/table-align-float-ref.xhtml new file mode 100644 index 00000000000..fc6b7860575 --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/tables/table-align-float-ref.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta charset="utf-8"/> + <title>Table align attribute reference</title> + <style type="text/css"> + table { border: 1px solid black; width: 300px; } + .left { float: left; } + .center { margin-left: auto; margin-right: auto; } + .right { float: right; } + </style> +</head> +<body> + <table class="left"> + <tr><td>Left aligned table</td></tr> + </table> + <br/> + <table class="center"> + <tr><td>Center aligned table</td></tr> + </table> + <br/> + <table class="right"> + <tr><td>Right aligned table</td></tr> + </table> +</body> +</html>
\ No newline at end of file diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/tables/table-align-float.xhtml b/tests/wpt/tests/html/rendering/non-replaced-elements/tables/table-align-float.xhtml new file mode 100644 index 00000000000..05de0d6b280 --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/tables/table-align-float.xhtml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta charset="utf-8"/> + <title>Table align attribute test</title> + <link rel="help" href="https://html.spec.whatwg.org/#tables-2"/> + <link rel="match" href="table-align-float-ref.xhtml"/> + <style type="text/css"> + table { border: 1px solid black; width: 300px; } + </style> +</head> +<body> + <table align="LEFT"> + <tr><td>Left aligned table</td></tr> + </table> + <br/> + <table align="CENTER"> + <tr><td>Center aligned table</td></tr> + </table> + <br/> + <table align="RIGHT"> + <tr><td>Right aligned table</td></tr> + </table> +</body> +</html>
\ No newline at end of file diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/button-in-popover.tentative.html b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/button-in-popover.tentative.html new file mode 100644 index 00000000000..da217f03e15 --- /dev/null +++ b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/button-in-popover.tentative.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/issues/9799"> +<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> + +<style> +select, select::picker(select) { + appearance: base-select; +} +</style> + +<select> + <button id=invoker>invoker</button> + <option>one</option> + <option>two</option> + <button id=popover>popover button</button> +</select> + +<script> +promise_test(async () => { + const select = document.querySelector('select'); + const invokerButton = document.getElementById('invoker'); + const popoverButton = document.getElementById('popover'); + + await test_driver.click(invokerButton); + assert_true(select.matches(':open'), + 'Select should open after clicking the invoker button.'); + + let popoverButtonClicked = false; + popoverButton.onclick = () => popoverButtonClicked = true; + await test_driver.click(popoverButton); + assert_true(select.matches(':open'), + 'Clicking the button should not have closed the popover.'); + assert_true(popoverButtonClicked, + 'The button in the popover should have gotten a click event when clicked.'); +}, 'Buttons in the popover should be rendered and should not close the popover when clicked.'); +</script> diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html index 5aa4638f0be..1a5b059997b 100644 --- a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html +++ b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html @@ -42,6 +42,10 @@ </div> </select> +<select id=s7> + <input> +</select> + <div id=afterlast> keep this div after the last test case </div> @@ -101,6 +105,13 @@ test(() => { }, 'Divs and imgs should be allowed as direct children of select and within options without a datalist.'); test(() => { + assert_equals(document.getElementById('s7').parentNode, document.body); + assert_equals(document.getElementById('s7').innerHTML, ` + <input> +`); +}, 'Input tags should parse inside select instead of closing the select.'); + +test(() => { assert_equals(document.getElementById('afterlast').parentNode, document.body); }, 'The last test should not leave any tags open after parsing.'); </script> diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/popover-dialog-does-not-block-mouse-events.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/popover-dialog-does-not-block-mouse-events.html new file mode 100644 index 00000000000..97f17410f70 --- /dev/null +++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/popover-dialog-does-not-block-mouse-events.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Popover dialogs should not block mouse events</title> +<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element"> +<style> + #div { + height: 100px; + width: 100px; + background: red; + } +</style> +<div id="div"></div> +<dialog id="dialog" popover="manual"></dialog> + +<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> +<script> +promise_test(async () => { + const dialog = document.getElementById("dialog"); + dialog.showPopover(); + + const div = document.getElementById("div"); + div.addEventListener("click", function(event) { + div.firedOn = true; + div.style.backgroundColor = "green"; + }); + + var absoluteTop = 0; + var absoluteLeft = 0; + for (var parentNode = div; parentNode; parentNode = parentNode.offsetParent) { + absoluteLeft += parentNode.offsetLeft; + absoluteTop += parentNode.offsetTop; + } + + const x = absoluteLeft + div.offsetWidth / 2; + const y = absoluteTop + div.offsetHeight / 2; + const actions = new test_driver.Actions() + .pointerMove(x, y) + .pointerDown() + .pointerUp() + .pointerMove(0, 0); + await actions.send(); + assert_true(div.firedOn, "div should have gotten a click event."); +}, "Ensure that popover dialogs do not block mouse events. To test manually, click the red box. The test succeeds if the red box turns green."); +</script> diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html index b30433f4a92..555dc03b019 100644 --- a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html +++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/toggle-events.tentative.html @@ -1,6 +1,6 @@ <!doctype html> <link rel="author" href="mailto:jarhar@chromium.org" /> -<link rel=author title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk"> +<link rel="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" /> <link rel="help" href="https://github.com/whatwg/html/pull/10091" /> <link rel="help" href="https://github.com/whatwg/html/issues/9733" /> <script src="/resources/testharness.js"></script> @@ -257,5 +257,111 @@ mydialog.close(); await waitForTick(); }, `dialog.${methodName}() should coalesce asynchronous toggle events.`); + + promise_test(async (t) => { + let attributeChanges = 0; + const mo = new MutationObserver((records) => { + attributeChanges += records.length; + }); + mo.observe(mydialog, { attributeFilter: ['open'] }); + t.add_cleanup(() => { + mo.disconnect(); + }); + mydialog.addEventListener("beforetoggle", () => { + mydialog[methodName](); + }, { once: true }); + + mydialog[methodName](); + assert_true(mydialog.open, "Dialog is open"); + await waitForTick(); + mo.takeRecords(); + assert_equals(attributeChanges, 1, "Should have set open once"); + + attributeChanges = 0; + mydialog.addEventListener("beforetoggle", () => { + mydialog.close(); + }, { once: true }); + + mydialog.close(); + assert_false(mydialog.open, "Dialog is closed"); + await waitForTick(); + mo.takeRecords(); + assert_equals(attributeChanges, 1, "Should have removed open once"); + }, `dialog.${methodName}() should not double-set open/close if beforetoggle re-opens`); + + promise_test(async (t) => { + const abortController = new AbortController(); + const signal = abortController.signal; + const mydialog = document.getElementById("mydialog"); + t.add_cleanup(() => { + abortController.abort(); + mydialog.close(); + document.body.prepend(mydialog); + }); + mydialog.addEventListener("beforetoggle", () => { + mydialog.remove(); + }, { once: true }); + let toggleEventCounter = 0; + mydialog.addEventListener( + "toggle", + (event) => { + toggleEventCounter += 1; + }, + { signal } + ); + + mydialog[methodName](); + assert_false(mydialog.isConnected, "Dialog is not connected"); + if (methodName == 'show') { + assert_true(mydialog.open, "Dialog did open"); + } else { + assert_false(mydialog.open, "Dialog did not open"); + assert_false(mydialog.matches(':modal'), "Dialog is not modal"); + } + await waitForTick(); + if (methodName == 'show') { + assert_equals(toggleEventCounter, 1, "toggle event was fired"); + } else { + assert_equals(toggleEventCounter, 0, "toggle event not fired"); + } + }, `dialog.${methodName}() should not open if beforetoggle removes`); + + promise_test(async (t) => { + const abortController = new AbortController(); + const signal = abortController.signal; + t.add_cleanup(async () => { + try { mydialog.hidePopover(); } catch {} + try { mydialog.close(); } catch {} + mydialog.removeAttribute('popover'); + abortController.abort(); + await waitForTick(); + }); + mydialog.setAttribute('popover', ''); + mydialog.addEventListener("beforetoggle", () => { + mydialog.showPopover(); + }, { once: true }); + let toggleEventCounter = 0; + mydialog.addEventListener( + "toggle", + (event) => { + toggleEventCounter += 1; + }, + { signal } + ); + + mydialog[methodName](); + if (methodName == 'show') { + assert_true(mydialog.open, "Dialog did open"); + } else { + assert_false(mydialog.open, "Dialog did not open"); + assert_false(mydialog.matches(':modal'), "Dialog is not modal"); + } + await waitForTick(); + if (methodName == 'show') { + assert_equals(toggleEventCounter, 2, "toggle event was fired for show+showPopover"); + } else { + assert_equals(toggleEventCounter, 1, "toggle event was fired for showPopover"); + } + }, `dialog.${methodName}() should not open if beforetoggle calls showPopover`); }); </script> diff --git a/tests/wpt/tests/html/webappapis/update-rendering/child-document-raf-order.html b/tests/wpt/tests/html/webappapis/update-rendering/child-document-raf-order.html index eccc1bde7fb..222c1af444e 100644 --- a/tests/wpt/tests/html/webappapis/update-rendering/child-document-raf-order.html +++ b/tests/wpt/tests/html/webappapis/update-rendering/child-document-raf-order.html @@ -47,17 +47,6 @@ callbacks for each. <script> -// Split array into chunks of len. -function chunk (arr, len) { - var chunks = [], - i = 0, - n = arr.length; - while (i < n) { - chunks.push(arr.slice(i, i += len)); - } - return chunks; -} - async_test(function (t) { step_timeout(setup, 0); @@ -119,20 +108,9 @@ async_test(function (t) { }); let finish = t.step_func(function() { - - // The test requests rafs recursively, - // but since all three rafs run as part of the same "update the rendering" task, - // they should always come in a triplet. - assert_equals(notification_sequence.length % 3, 0); - - let chunks = chunk(notification_sequence, 3); - for (var i = 0; i < chunks.length; i++) { - // Assert correct ordering per triplet of rafs. - assert_array_equals(chunks[i], - ["parent_raf", "first_child_raf", "second_child_raf"], - "expected order of notifications"); - } - + assert_array_equals(notification_sequence, + ["parent_raf", "first_child_raf", "second_child_raf"], + "expected order of notifications"); t.done(); }); }); diff --git a/tests/wpt/tests/interfaces/turtledove.idl b/tests/wpt/tests/interfaces/turtledove.idl index ff48d311914..0309f5047b3 100644 --- a/tests/wpt/tests/interfaces/turtledove.idl +++ b/tests/wpt/tests/interfaces/turtledove.idl @@ -15,6 +15,7 @@ dictionary AuctionAd { USVString buyerReportingId; USVString buyerAndSellerReportingId; + sequence<USVString> selectableBuyerAndSellerReportingIds; sequence<USVString> allowedReportingOrigins; DOMString adRenderId; }; @@ -89,16 +90,16 @@ dictionary AuctionAdConfig { sequence<USVString> interestGroupBuyers; Promise<any> auctionSignals; Promise<any> sellerSignals; - Promise<DOMString> directFromSellerSignalsHeaderAdSlot; - Promise<record<USVString, USVString>> deprecatedRenderURLReplacements; + Promise<DOMString?> directFromSellerSignalsHeaderAdSlot; + Promise<record<USVString, USVString>?> deprecatedRenderURLReplacements; unsigned long long sellerTimeout; unsigned short sellerExperimentGroupId; - Promise<record<USVString, any>> perBuyerSignals; - Promise<record<USVString, unsigned long long>> perBuyerTimeouts; - Promise<record<USVString, unsigned long long>> perBuyerCumulativeTimeouts; + Promise<record<USVString, any>?> perBuyerSignals; + Promise<record<USVString, unsigned long long>?> perBuyerTimeouts; + Promise<record<USVString, unsigned long long>?> perBuyerCumulativeTimeouts; unsigned long long reportingTimeout; USVString sellerCurrency; - Promise<record<USVString, USVString>> perBuyerCurrencies; + Promise<record<USVString, USVString>?> perBuyerCurrencies; record<USVString, unsigned short> perBuyerMultiBidLimits; record<USVString, unsigned short> perBuyerGroupLimits; record<USVString, unsigned short> perBuyerExperimentGroupIds; @@ -198,6 +199,7 @@ dictionary GenerateBidOutput { DOMString bidCurrency; (DOMString or AdRender) render; any ad; + USVString selectedBuyerAndSellerReportingId; sequence<(DOMString or AdRender)> adComponents; double adCost; unrestricted double modelingSignals; @@ -294,6 +296,7 @@ dictionary ReportingBrowserSignals { USVString componentSeller; USVString buyerAndSellerReportingId; + USVString selectedBuyerAndSellerReportingId; }; dictionary ReportResultBrowserSignals : ReportingBrowserSignals { diff --git a/tests/wpt/tests/mediacapture-insertable-streams/VideoTrackGenerator-with-window-tracks.https.html b/tests/wpt/tests/mediacapture-insertable-streams/VideoTrackGenerator-with-window-tracks.https.html index 36fc4135e23..dfe000fbddb 100644 --- a/tests/wpt/tests/mediacapture-insertable-streams/VideoTrackGenerator-with-window-tracks.https.html +++ b/tests/wpt/tests/mediacapture-insertable-streams/VideoTrackGenerator-with-window-tracks.https.html @@ -64,11 +64,15 @@ const blob = new Blob([script], { type: 'text/javascript' }); const url = URL.createObjectURL(blob); const worker = new Worker(url); - await new Promise(resolve => worker.onmessage = () => { - resolve(); - }); - URL.revokeObjectURL(url); - return worker; + try { + await new Promise((resolve, reject) => { + worker.onmessage = resolve; + worker.onerror = (err) => reject(err.message); + }); + return worker; + } finally { + URL.revokeObjectURL(url); + } } promise_test(async t => { diff --git a/tests/wpt/tests/navigation-api/state/cross-document-away-and-back.html b/tests/wpt/tests/navigation-api/state/cross-document-away-and-back.html index cccaebdf7b9..f531ec67715 100644 --- a/tests/wpt/tests/navigation-api/state/cross-document-away-and-back.html +++ b/tests/wpt/tests/navigation-api/state/cross-document-away-and-back.html @@ -1,11 +1,15 @@ <!doctype html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<meta name="variant" content="?method=navigate"> +<meta name="variant" content="?method=updateCurrentEntry"> + <iframe id="i" src="/common/blank.html"></iframe> <script> async_test(t => { window.onload = t.step_func(() => { - i.contentWindow.navigation.navigate("#", { history: "replace", state: { data : "value" } }); + updateStateBasedOnTestVariant(i.contentWindow, { data : "value" }); assert_equals(i.contentWindow.navigation.entries().length, 1); assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); diff --git a/tests/wpt/tests/navigation-api/state/cross-document-location-api.html b/tests/wpt/tests/navigation-api/state/cross-document-location-api.html index 395d95c6fbe..5a22473e6bb 100644 --- a/tests/wpt/tests/navigation-api/state/cross-document-location-api.html +++ b/tests/wpt/tests/navigation-api/state/cross-document-location-api.html @@ -1,11 +1,15 @@ <!doctype html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<meta name="variant" content="?method=navigate"> +<meta name="variant" content="?method=updateCurrentEntry"> + <iframe id="i" src="/common/blank.html"></iframe> <script> async_test(t => { window.onload = t.step_func(() => { - i.contentWindow.navigation.navigate("#", { history: "replace", state: { data: "value" } }); + updateStateBasedOnTestVariant(i.contentWindow, { data : "value" }); assert_equals(i.contentWindow.navigation.entries().length, 1); assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); diff --git a/tests/wpt/tests/navigation-api/state/history-pushState.html b/tests/wpt/tests/navigation-api/state/history-pushState.html index 7d3c79ba6ca..8c63f72e53b 100644 --- a/tests/wpt/tests/navigation-api/state/history-pushState.html +++ b/tests/wpt/tests/navigation-api/state/history-pushState.html @@ -1,9 +1,13 @@ <!doctype html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<meta name="variant" content="?method=navigate"> +<meta name="variant" content="?method=updateCurrentEntry"> + <script> test(() => { - navigation.navigate("#", { history: "replace", state: { data: "value" } }); + updateStateBasedOnTestVariant(window, { data : "value" }); assert_equals(navigation.currentEntry.getState().data, "value"); history.pushState(1, "", "#push"); assert_equals(navigation.currentEntry.getState(), undefined); diff --git a/tests/wpt/tests/navigation-api/state/history-replaceState.html b/tests/wpt/tests/navigation-api/state/history-replaceState.html index bdf35616393..7098201caa7 100644 --- a/tests/wpt/tests/navigation-api/state/history-replaceState.html +++ b/tests/wpt/tests/navigation-api/state/history-replaceState.html @@ -1,9 +1,13 @@ <!doctype html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<meta name="variant" content="?method=navigate"> +<meta name="variant" content="?method=updateCurrentEntry"> + <script> test(() => { - navigation.navigate("#", { history: "replace", state: { data: "value" } }); + updateStateBasedOnTestVariant(window, { data : "value" }); assert_equals(navigation.currentEntry.getState().data, "value"); history.replaceState(1, "", "#replace"); assert_equals(navigation.currentEntry.getState(), undefined); diff --git a/tests/wpt/tests/navigation-api/state/location-reload.html b/tests/wpt/tests/navigation-api/state/location-reload.html index bf1bc105fbf..5a566c66fd5 100644 --- a/tests/wpt/tests/navigation-api/state/location-reload.html +++ b/tests/wpt/tests/navigation-api/state/location-reload.html @@ -1,11 +1,15 @@ <!doctype html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<meta name="variant" content="?method=navigate"> +<meta name="variant" content="?method=updateCurrentEntry"> + <iframe id="i" src="/common/blank.html"></iframe> <script> async_test(t => { window.onload = t.step_func(() => { - i.contentWindow.navigation.navigate("#", { history: "replace", state: { data: "value" } }); + updateStateBasedOnTestVariant(i.contentWindow, { data : "value" }); assert_equals(i.contentWindow.navigation.entries().length, 1); assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); diff --git a/tests/wpt/tests/navigation-api/state/resources/helpers.js b/tests/wpt/tests/navigation-api/state/resources/helpers.js new file mode 100644 index 00000000000..658d267351b --- /dev/null +++ b/tests/wpt/tests/navigation-api/state/resources/helpers.js @@ -0,0 +1,18 @@ +window.updateStateBasedOnTestVariant = (w, state) => { + const usp = new URLSearchParams(location.search); + const method = usp.get("method"); + + switch (method) { + case "navigate": { + w.navigation.navigate("#", { history: "replace", state }); + break; + } + case "updateCurrentEntry": { + w.navigation.updateCurrentEntry({ state }); + break; + } + default: { + assert_unreached(`method must be either "navigate" or "updateCurrentEntry"`); + } + } +}; diff --git a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/cross-document-away-and-back.html b/tests/wpt/tests/navigation-api/updateCurrentEntry-method/cross-document-away-and-back.html deleted file mode 100644 index c37d5e979a0..00000000000 --- a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/cross-document-away-and-back.html +++ /dev/null @@ -1,31 +0,0 @@ -<!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<iframe id="i" src="/common/blank.html"></iframe> -<script> -async_test(t => { - window.onload = t.step_func(() => { - i.contentWindow.navigation.updateCurrentEntry({ state: { data: "value" } }); - assert_equals(i.contentWindow.navigation.entries().length, 1); - assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); - - let navigated_back = false; - i.contentWindow.navigation.navigate("?1"); - i.onload = t.step_func(() => { - if (navigated_back) { - let back_entry = i.contentWindow.navigation.currentEntry; - assert_equals(i.contentWindow.navigation.entries().length, 2); - assert_equals(back_entry.index, 0); - assert_equals(back_entry.getState().data, "value"); - t.done(); - } else { - assert_equals(i.contentWindow.navigation.entries().length, 2); - assert_equals(i.contentWindow.navigation.currentEntry, i.contentWindow.navigation.entries()[1]); - assert_equals(i.contentWindow.navigation.currentEntry.getState(), undefined); - history.back(); - navigated_back = true; - } - }); - }); -}, "entry.getState() behavior after navigating away and back"); -</script> diff --git a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/cross-document-location-api.html b/tests/wpt/tests/navigation-api/updateCurrentEntry-method/cross-document-location-api.html deleted file mode 100644 index 26191fb8761..00000000000 --- a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/cross-document-location-api.html +++ /dev/null @@ -1,20 +0,0 @@ -<!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<iframe id="i" src="/common/blank.html"></iframe> -<script> -async_test(t => { - window.onload = t.step_func(() => { - i.contentWindow.navigation.updateCurrentEntry({ state: { data: "value" } }); - assert_equals(i.contentWindow.navigation.entries().length, 1); - assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); - - i.contentWindow.location.href = "?1"; - i.onload = t.step_func_done(() => { - assert_equals(i.contentWindow.navigation.entries().length, 2); - assert_equals(i.contentWindow.navigation.currentEntry.index, 1); - assert_equals(i.contentWindow.navigation.currentEntry.getState(), undefined); - }); - }); -}, "entry.getState() behavior after cross-document location API navigation"); -</script> diff --git a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/history-pushState.html b/tests/wpt/tests/navigation-api/updateCurrentEntry-method/history-pushState.html deleted file mode 100644 index 852294c64f4..00000000000 --- a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/history-pushState.html +++ /dev/null @@ -1,11 +0,0 @@ -<!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -test(() => { - navigation.updateCurrentEntry({ state : { data : "value" } }); - assert_equals(navigation.currentEntry.getState().data, "value"); - history.pushState(1, "", "#push"); - assert_equals(navigation.currentEntry.getState(), undefined); -}, "entry.getState() after history.pushState()"); -</script> diff --git a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/history-replaceState.html b/tests/wpt/tests/navigation-api/updateCurrentEntry-method/history-replaceState.html deleted file mode 100644 index 3eb91a9a80c..00000000000 --- a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/history-replaceState.html +++ /dev/null @@ -1,11 +0,0 @@ -<!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -test(() => { - navigation.updateCurrentEntry({ state : { data : "value" } }); - assert_equals(navigation.currentEntry.getState().data, "value"); - history.replaceState(1, "", "#replace"); - assert_equals(navigation.currentEntry.getState(), undefined); -}, "entry.getState() after history.replaceState()"); -</script> diff --git a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/location-reload.html b/tests/wpt/tests/navigation-api/updateCurrentEntry-method/location-reload.html deleted file mode 100644 index 8589eeb694e..00000000000 --- a/tests/wpt/tests/navigation-api/updateCurrentEntry-method/location-reload.html +++ /dev/null @@ -1,19 +0,0 @@ -<!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<iframe id="i" src="/common/blank.html"></iframe> -<script> -async_test(t => { - window.onload = t.step_func(() => { - i.contentWindow.navigation.updateCurrentEntry({ state: { data: "value" } }); - assert_equals(i.contentWindow.navigation.entries().length, 1); - assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); - - i.contentWindow.location.reload(); - i.onload = t.step_func_done(() => { - assert_equals(i.contentWindow.navigation.entries().length, 1); - assert_equals(i.contentWindow.navigation.currentEntry.getState().data, "value"); - }); - }); -}, "entry.getState() after location.reload()"); -</script> diff --git a/tests/wpt/tests/permissions-policy/resources/digital-credentials-get.html b/tests/wpt/tests/permissions-policy/resources/digital-credentials-get.html index 489e4291359..543417f230a 100644 --- a/tests/wpt/tests/permissions-policy/resources/digital-credentials-get.html +++ b/tests/wpt/tests/permissions-policy/resources/digital-credentials-get.html @@ -27,6 +27,7 @@ window.parent.postMessage({ type, enabled }, "*"); } } + test_driver.set_test_context(parent); window.onload = notify; </script> <body> diff --git a/tests/wpt/tests/sanitizer-api/html5lib-basics.tentative.html b/tests/wpt/tests/sanitizer-api/html5lib-basics.tentative.html new file mode 100644 index 00000000000..1df4d49f704 --- /dev/null +++ b/tests/wpt/tests/sanitizer-api/html5lib-basics.tentative.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<head> +<title>Basic setHTMLUnsafe test cases</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/html5lib-testcase-support.js"></script +</head> +<body> +<script type="html5lib-tests"> +#data +Hello! +#document +| "Hello!" + +#data +<p>bla +#document +| <p> +| "bla" + +#data +<p id=abc def='123'>texty<!-- xxx -->textz +#document +| <p> +| def="123" +| id="abc" +| "texty" +| <!-- xxx --> +| "textz" + +#data +<p>Hello <b>World</b><span>! +#document +| <p> +| "Hello " +| <b> +| "World" +| <span> +| "!" + +#data +<p>A template example.<template>Hello <b>World</b></template>! +#document +| <p> +| "A template example." +| <template> +| content +| "Hello " +| <b> +| "World" +| "!" + +#data +<td>Interesting parse context.</td> +#document-fragment +table +#document +| <tbody> +| <tr> +| <td> +| "Interesting parse context." + +#data +<p>A rather boring parse context. +#document-fragment +p +#document +| <p> +| "A rather boring parse context." + +</script> +<script> +// This runs a number of simple test cases that test setHTMLUnsafe, and +// setHTMLUnsafe vs innerHTML. This purposely doesn't include "advanced" test +// cases where the behaviours of those two methodsis supposed to differ. +// +// This sort of also doubles as unit tests for html5lib-testcase-support.js +html5lib_testcases_from_script().forEach((testcase, index) => { + test(_ => { + const context = document.createElement(testcase["document-fragment"] ?? "div"); + context.setHTMLUnsafe(testcase.data); + assert_testcase(context, testcase); + }, `Testcase #${index} with .setHTMLUnsafe("${testcase.data}")`); + + test(_ => { + const context_element = testcase["document-fragment"] ?? "div"; + const context = document.createElement(context_element); + const context2 = document.createElement(context_element); + + context.setHTMLUnsafe(testcase.data); + context2.innerHTML = testcase.data; + assert_subtree_equals(context, context2); + }, `Testcase #${index}, .innerHTML matches .setHTMLUnsafe`); +}); +</script> diff --git a/tests/wpt/tests/sanitizer-api/support/html5lib-testcase-support.js b/tests/wpt/tests/sanitizer-api/support/html5lib-testcase-support.js new file mode 100644 index 00000000000..4f15e46a7eb --- /dev/null +++ b/tests/wpt/tests/sanitizer-api/support/html5lib-testcase-support.js @@ -0,0 +1,196 @@ +// This library supports HTML5lib-style test cases. +// +// The HTMLlib test case format describes an actual DOM tree. For testing, and +// particular for testing of DOM parsers and DOM parser-related functionality, +// this has the advantage of being able to represent edge cases. +// +// Example: If `.replaceWithChildren` is called on the `<span>` element as a +// result of parsing `"<p>Hello<span>World</span></p>"`, then this results in +// a tree with two adjacent text nodes. This behaviour will affect subsequent +// DOM operations and should thus be tested. The HTML5lib format makes it easy +// to describe the expected result unambiguously. +// +// References: +// - HTML5lib: https://github.com/html5lib +// - HTML5lib testcases: https://github.com/html5lib/html5lib-tests/tree/master/tree-construction +// - test case format description: +// https://github.com/html5lib/html5lib-tests/blob/master/tree-construction/README.md +// +// The main "API" is: +// +// - parse_html5lib_testcases(string) +// This returns an array of dictionaries, where the dictionary contains the +// the text of the test file, keyed by the lines starting with a hashtag. +// +// E.g. #data\nbla results in [{data: "bla"}]. +// +// - html5lib_testcases_from_script() +// Wrapper for parse_html5lib_testcases that gets the test data from a script +// element with type "html5lib-tests". This allows to specify the test data +// in the test file, but requires working around closing script tags. +// +// - html5lib_testcases_from_response(response_promise) +// Wrapper for parse_html5lib_testcases that gets the data from a Response +// Promise, as is returned from `fetch()`, and returns a Promise for the array +// of testcases. This allows getting the test dat from a text resource. +// +// - build_node_tree(node, documentstr) +// This builds a node tree from the "#document" string from a testcase, and +// appends it to the node argument. Returns node. +// +// - assert_subtree_equals(node1, node2) +// Asserts that the child trees of node1 and node2 are equals. This +// recursively descends the trees. +// +// - assert_testcase(node, testcase) +// Wrapper for build_node_tree and assert_subtree_equals, for use with a +// result of parse_html5lib_testcases. +// + +function html5lib_testcases_from_script() { + return parse_html5lib_testcases( + document.querySelector("script[type='html5lib-tests']").textContent); +} + +function html5lib_testcases_from_response(response_promise) { + return response_promise + .then(response => response.text()) + .then(parse_html5lib_testcases); +} + +function add_html5lib_testcase(testcases, current) { + for (const item in current) { + current[item] = current[item].join("\n"); + } + if (Object.entries(current).length) { + testcases.push(current); + } +} + +function parse_html5lib_testcases(content) { + const testcases = []; + var state = undefined; + var current = {}; + for (const line of content.split("\n")) { + if (!line) { + add_html5lib_testcase(testcases, current); + state = undefined; + current = {}; + } else if (line[0] == "#") { + state = line.substring(1); + current[state] = []; + } else if (state) { + current[state].push(line); + } else { + // Error handling is for another day. + } + } + return testcases; +} + +function get_child_at(node, level) { + for (i = 0; i < level; i++) { + if (is_html_template(node)) { + // For <template>, continue with the content fragment. + node = node.content; + } else { + node = node.lastChild; + } + } + return node; +} + +function append_child_at(node, level, child) { + get_child_at(node, level).appendChild(child); +} + +function is_element(node) { + return node.tagName && node.namespaceURI; +} + +function is_html_template(node) { + return is_element(node) && node.tagName == "TEMPLATE" && + node.namespaceURI == "http://www.w3.org/1999/xhtml"; +} + +function build_node_tree(root, docstr) { + // Format described here: + // https://github.com/html5lib/html5lib-tests/blob/master/tree-construction/README.md + for (const line of docstr.split("\n")) { + const [_, indent, remainder] = line.match(/^\| ( *)(.*)/); + const level = indent.length / 2; + if (match = remainder.match(/^<([a-z]*)>$/)) { + // `Element nodes must be represented by a "<, the tag name string, ">".` + append_child_at(root, level, document.createElement(match[1])); + } else if (match = remainder.match(/^"([^"]*)"$/)) { + // `Text nodes must be the string, in double quotes.` + append_child_at(root, level, document.createTextNode(match[1])); + } else if (match = remainder.match(/^(.*)="(.*)"$/)) { + // `Attribute nodes must have the attribute name string, then an "=" sign, + // then the attribute value in double quotes (").` + get_child_at(root, level).setAttribute(match[1], match[2]); + } else if (match = remainder.match(/^<!--(.*)-->$/)) { + // `Comments must be "<" then "!-- " then the data then " -->".` + append_child_at(root, level, document.createComment(match[1])); + } else if (match = remainder.match( + /^<!DOCTYPE ([^ ]*)( "([^"]*)"( "([^"]*)")?)?>$/)) { + // `DOCTYPEs must be "<!DOCTYPE " then [... bla bla ...]` + append_child_at(root, level, + document.implementation.createDocumentType(match[1], match[3], match[5])); + } else if (match = remainder.match(/^<?([a-z]*)( (.*))>$/)) { + // `Processing instructions must be "<?", then the target, then [...]` + append_child_at(root, level, document.createProcessingInstruction( + match[1], match[3])); + } else if (remainder == "content") { + // Template contents are represented by the string "content" with the + // children below it. + // Nothing to do here; so let's just check we're actually in a template. + assert_true(is_html_template(get_child_at(root, level)), + "\"content\" only expected as child of a <template>."); + } else { + assert_unreached( + `Unknown line type. Maybe test data is malformed. ("${line}")`); + } + } + return root; +} + +function assert_subtree_equals(node1, node2) { + // Iterate in parallel over both trees. + const tree1 = document.createNodeIterator(node1); + const tree2 = document.createNodeIterator(node2); + // Skip the root/context node, so that we can re-use the test with different + // context types. + var current1 = tree1.nextNode(); + var current2 = tree2.nextNode(); + do { + current1 = tree1.nextNode(); + current2 = tree2.nextNode(); + + // Conceptually, we only want to check whether a.isEqualNode(b). But that + // yields terrible error messages ("expected true but got false"). With + // this being a test suite and all, let's invest a bit of effort into nice + // error messages. + if (current1 && !current1.isEqualNode(current2)) { + let breadcrumbs = ""; + let current = current1; + while (current) { + const here = is_element(current) ? `<${current.tagName}>` : `${current}`; + breadcrumbs = `${here} / ${breadcrumbs}`; + current = current.parentNode; + } + breadcrumbs = breadcrumbs.substring(0, breadcrumbs.length - 3); + assert_true(current1.isEqualNode(current2), + `${current1}.isEqual(${current2}) fails. Path: ${breadcrumbs}.`); + } + } while (current1); + + // Ensure that both iterators have come to an end. + assert_false(!!current2, "Additional nodes at the of node2."); +} + +function assert_testcase(node, testcase) { + const context = document.createElement(testcase["document-fragment"] ?? "div"); + const tree = build_node_tree(context, testcase.document); + assert_subtree_equals(node, tree); +} diff --git a/tests/wpt/tests/scroll-animations/css/animation-timeline-computed.html b/tests/wpt/tests/scroll-animations/css/animation-timeline-computed.html index 1e621eee531..51454f6853d 100644 --- a/tests/wpt/tests/scroll-animations/css/animation-timeline-computed.html +++ b/tests/wpt/tests/scroll-animations/css/animation-timeline-computed.html @@ -69,5 +69,8 @@ test_computed_value('animation-timeline', 'view(y 1px auto)'); test_computed_value('animation-timeline', 'view(1px y)', 'view(y 1px)'); test_computed_value('animation-timeline', 'view(y auto)', 'view(y)'); test_computed_value('animation-timeline', 'view(y auto auto)', 'view(y)'); +test_computed_value('animation-timeline', 'view(10% 10px)', 'view(10% 10px)'); +test_computed_value('animation-timeline', 'view(auto calc(1% + 1px))'); +test_computed_value('animation-timeline', 'view(2em calc(1% + 1em))', 'view(32px calc(1% + 16px))'); </script> diff --git a/tests/wpt/tests/scroll-animations/css/animation-timeline-parsing.html b/tests/wpt/tests/scroll-animations/css/animation-timeline-parsing.html index 9e3c1078b5b..44e9caf002e 100644 --- a/tests/wpt/tests/scroll-animations/css/animation-timeline-parsing.html +++ b/tests/wpt/tests/scroll-animations/css/animation-timeline-parsing.html @@ -75,6 +75,7 @@ test_valid_value('animation-timeline', 'view(1px)'); test_valid_value('animation-timeline', 'view(1px 1px)', 'view(1px)'); test_valid_value('animation-timeline', 'view(1px auto)'); test_valid_value('animation-timeline', 'view(auto calc(1% + 1px))'); +test_valid_value('animation-timeline', 'view(2em calc(1% + 1em))'); test_valid_value('animation-timeline', 'view(auto)', 'view()'); test_valid_value('animation-timeline', 'view(auto auto)', 'view()'); diff --git a/tests/wpt/tests/scroll-animations/scroll-timelines/setting-current-time.html b/tests/wpt/tests/scroll-animations/scroll-timelines/setting-current-time.html index f6c826db699..5daa459bbeb 100644 --- a/tests/wpt/tests/scroll-animations/scroll-timelines/setting-current-time.html +++ b/tests/wpt/tests/scroll-animations/scroll-timelines/setting-current-time.html @@ -42,13 +42,13 @@ promise_test(async t => { promise_test(async t => { const animation = createScrollLinkedAnimation(t); - assert_throws_dom('NotSupportedError', () => { + assert_throws_js(TypeError, () => { animation.currentTime = CSSNumericValue.parse("300"); }); - assert_throws_dom('NotSupportedError', () => { + assert_throws_js(TypeError, () => { animation.currentTime = CSSNumericValue.parse("300ms"); }); - assert_throws_dom('NotSupportedError', () => { + assert_throws_js(TypeError, () => { animation.currentTime = CSSNumericValue.parse("0.3s"); }); }, 'Setting the current time to an absolute time value throws exception'); diff --git a/tests/wpt/tests/scroll-animations/scroll-timelines/setting-start-time.html b/tests/wpt/tests/scroll-animations/scroll-timelines/setting-start-time.html index aae1849565b..d950eb8188d 100644 --- a/tests/wpt/tests/scroll-animations/scroll-timelines/setting-start-time.html +++ b/tests/wpt/tests/scroll-animations/scroll-timelines/setting-start-time.html @@ -26,13 +26,13 @@ promise_test(async t => { const animation = createScrollLinkedAnimation(t); - assert_throws_dom('NotSupportedError', () => { + assert_throws_js(TypeError, () => { animation.startTime = CSSNumericValue.parse("300"); }); - assert_throws_dom('NotSupportedError', () => { + assert_throws_js(TypeError, () => { animation.startTime = CSSNumericValue.parse("300ms"); }); - assert_throws_dom('NotSupportedError', () => { + assert_throws_js(TypeError, () => { animation.startTime = CSSNumericValue.parse("0.3s"); }); }, 'Setting the start time to an absolute time value throws exception'); diff --git a/tests/wpt/tests/selection/caret-position-should-be-correct-while-moveup-movedown.html b/tests/wpt/tests/selection/caret-position-should-be-correct-while-moveup-movedown.html new file mode 100644 index 00000000000..45d95a96b04 --- /dev/null +++ b/tests/wpt/tests/selection/caret-position-should-be-correct-while-moveup-movedown.html @@ -0,0 +1,450 @@ +<!DOCTYPE html> +<html> + <head> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <style> + .vertical-lr { + writing-mode: vertical-lr; + border: 1px solid black; + padding: 10px; + width: 100px; + height: 200px; + } + .vertical-rl { + writing-mode: vertical-rl; + border: 1px solid black; + padding: 10px; + width: 100px; + height: 200px; + } + </style> + </head> + <body> + <div contenteditable id="horizontal">text1<br />text2</div> + <div contenteditable class="vertical-lr" id="vertical_lr"> + text1<br /> + text2 + </div> + <div contenteditable class="vertical-rl" id="vertical_rl"> + text1<br /> + text2 + </div> + + <script> + const horizontal = document.getElementById("horizontal"); + const verticalLR = document.getElementById("vertical_lr"); + const verticalRL = document.getElementById("vertical_rl"); + const tests = [ + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[2], + endNode: horizontal.childNodes[0], + anchorOffset: horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ), + focusOffset: + horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ) + horizontal.childNodes[2].textContent.trim().length, + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in moving up horizontal div when selection was left to right with line granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[2], + endNode: horizontal.childNodes[0], + anchorOffset: + horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ) + horizontal.childNodes[2].textContent.trim().length, + focusOffset: horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ), + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in moving up horizontal div when selection was right to left with line granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[0], + endNode: horizontal.childNodes[2], + anchorOffset: horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ), + focusOffset: + horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ) + horizontal.childNodes[0].textContent.trim().length, + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in moving down horizontal div when selection was left to right with line granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[0], + endNode: horizontal.childNodes[2], + anchorOffset: + horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ) + horizontal.childNodes[0].textContent.trim().length, + focusOffset: horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ), + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in moving down horizontal div when selection was right to left with line granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[2], + endNode: horizontal.childNodes[0], + anchorOffset: horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ), + focusOffset: + horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ) + horizontal.childNodes[2].textContent.trim().length, + direction: "backward", + granularity: "paragraph", + description: + "Caret position should be correct in moving up horizontal div when selection was left to right with paragraph granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[2], + endNode: horizontal.childNodes[0], + anchorOffset: + horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ) + horizontal.childNodes[2].textContent.trim().length, + focusOffset: horizontal.childNodes[2].textContent.indexOf( + horizontal.childNodes[2].textContent.trim() + ), + direction: "backward", + granularity: "paragraph", + description: + "Caret position should be correct in moving up horizontal div when selection was right to left with paragraph granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[0], + endNode: horizontal.childNodes[2], + anchorOffset: horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ), + focusOffset: + horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ) + horizontal.childNodes[0].textContent.trim().length, + direction: "forward", + granularity: "paragraph", + description: + "Caret position should be correct in moving down horizontal div when selection was left to right with paragraph granularity", + }, + { + elementUnderTest: horizontal, + startNode: horizontal.childNodes[0], + endNode: horizontal.childNodes[2], + anchorOffset: + horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ) + horizontal.childNodes[0].textContent.trim().length, + focusOffset: horizontal.childNodes[0].textContent.indexOf( + horizontal.childNodes[0].textContent.trim() + ), + direction: "forward", + granularity: "paragraph", + description: + "Caret position should be correct in moving down horizontal div when selection was right to left with paragraph granularity", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in move right with line granularity for vertical-lr div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + focusOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in move right with line granularity for vertical-lr div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in move left with line granularity for vertical-lr div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + focusOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in move left with line granularity for vertical-lr div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + direction: "forward", + granularity: "paragraph", + description: + "Caret position should be correct in move right with paragraph granularity for vertical-lr div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + focusOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + direction: "forward", + granularity: "paragraph", + description: + "Caret position should be correct in move right with paragraph granularity for vertical-lr div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + direction: "backward", + granularity: "paragraph", + description: + "Caret position should be correct in move left with paragraph granularity for vertical-lr div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + focusOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + direction: "backward", + granularity: "paragraph", + description: + "Caret position should be correct in move left with paragraph granularity for vertical-lr div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in move left with line granularity for vertical-rl div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + focusOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in move left with line granularity for vertical-rl div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in move right with line granularity for vertical-rl div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + focusOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in move right with line granularity for vertical-rl div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in move left with paragraph granularity for vertical-rl div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[0], + endNode: verticalLR.childNodes[2], + anchorOffset: + verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ) + verticalLR.childNodes[0].textContent.trim().length, + focusOffset: verticalLR.childNodes[0].textContent.indexOf( + verticalLR.childNodes[0].textContent.trim() + ), + direction: "forward", + granularity: "line", + description: + "Caret position should be correct in move left with paragraph granularity for vertical-rl div when selection was bottom to top", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + focusOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in move right with paragraph granularity for vertical-rl div when selection was top to bottom", + }, + { + elementUnderTest: verticalLR, + startNode: verticalLR.childNodes[2], + endNode: verticalLR.childNodes[0], + anchorOffset: + verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ) + verticalLR.childNodes[2].textContent.trim().length, + focusOffset: verticalLR.childNodes[2].textContent.indexOf( + verticalLR.childNodes[2].textContent.trim() + ), + direction: "backward", + granularity: "line", + description: + "Caret position should be correct in move right with paragraph granularity for vertical-rl div when selection was bottom to top", + }, + ]; + for (const testData of tests) { + test(function () { + // Get the selection object and set startNode to it. + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.setBaseAndExtent( + testData.startNode, + testData.anchorOffset, + testData.startNode, + testData.focusOffset + ); + // Modify the selection as per the direction and granularity of the test + testData.elementUnderTest.focus(); + selection.modify( + "move", + testData.direction, + testData.granularity + ); + // After modification, the selection should should have collapsed and should be on the endNode of the test with offset same as the initial focus offset + assert_true(selection.isCollapsed); + assert_equals(selection.focusOffset, testData.focusOffset); + assert_equals(selection.focusNode, testData.endNode); + }, testData.description); + } + </script> + </body> +</html> diff --git a/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-collapsed.html b/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-collapsed.html index 99ab82eb39c..3ea6e0c62c7 100644 --- a/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-collapsed.html +++ b/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-collapsed.html @@ -14,7 +14,7 @@ </div> <div id="host2"> <template shadowrootmode=open>D</template> - <div id=b>B - not slotted</div> + B - not slotted </div> </div> @@ -25,20 +25,6 @@ const d = host2.shadowRoot; test(() => { const sel = getSelection(); - sel.setBaseAndExtent(b, 0, c, 0); - assert_equals(sel.getRangeAt(0).startContainer, b); - assert_equals(sel.getRangeAt(0).startOffset, 0); - assert_equals(sel.getRangeAt(0).endContainer, b); - assert_equals(sel.getRangeAt(0).endOffset, 0); - - assert_equals(sel.getComposedRanges()[0].startContainer, b); - assert_equals(sel.getComposedRanges()[0].startOffset, 0); - assert_equals(sel.getComposedRanges()[0].endContainer, b); - assert_equals(sel.getComposedRanges()[0].endOffset, 0); -}, 'Setting the range to nodes that aren\'t in the same tree collapses both composed and non-composed ranges.'); - -test(() => { - const sel = getSelection(); sel.setBaseAndExtent(c, 0, d, 0); assert_equals(sel.getRangeAt(0).startContainer, d); diff --git a/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html b/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html new file mode 100644 index 00000000000..d89dcb2ce9d --- /dev/null +++ b/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-dom-mutations-removal.html @@ -0,0 +1,110 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="author" href="mailto:dizhangg@chromium.org"> +<link rel="help" href="https://w3c.github.io/selection-api/#dom-selection-getcomposedranges"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name="variant" content="?mode=closed"> +<meta name="variant" content="?mode=open"> + +<div id="container"></div> + +<script> + +const mode = (new URLSearchParams(document.location.search)).get("mode"); + +test(() => { + container.innerHTML = 'a<div id="host"></div>b'; + const host = container.querySelector('#host'); + const shadowRoot = host.attachShadow({ mode }); + shadowRoot.innerHTML = 'hello, world'; + getSelection().setBaseAndExtent(shadowRoot.firstChild, 7, container, 2); + const rangeBefore = getSelection().getComposedRanges({ shadowRoots: [shadowRoot] })[0]; + host.remove(); + const rangeAfter = getSelection().getComposedRanges({ shadowRoots: [shadowRoot] })[0]; + + assert_equals(rangeBefore.startContainer, shadowRoot.firstChild, 'StaticRange does not update on new mutation.'); + assert_equals(rangeBefore.startOffset, 7); + assert_equals(rangeBefore.endContainer, container); + assert_equals(rangeBefore.endOffset, 2); + + assert_equals(rangeAfter.startContainer, container, 'collapsed to the host parent: container'); + assert_equals(rangeAfter.startOffset, 1); + assert_equals(rangeAfter.endContainer, container); + assert_equals(rangeAfter.endOffset, 1); +}, 'Range is fully in shadow tree. Removing shadow host collapses composed StaticRange. Note it does not update previously returned composed StaticRange.'); + +test(() => { + container.innerHTML = '<div id="wrapper">a<div id="host"></div>b</div>'; + const wrapper = container.querySelector('#wrapper'); + const host = container.querySelector('#host'); + const shadowRoot = host.attachShadow({ mode }); + shadowRoot.innerHTML = 'hello, world'; + getSelection().setBaseAndExtent(shadowRoot.firstChild, 4, shadowRoot.firstChild, 7); + wrapper.remove(); + + const rangeAfter = getSelection().getComposedRanges({ shadowRoots: [shadowRoot] })[0]; + assert_equals(rangeAfter.startContainer, container, 'collapsed to parent of removed node'); + assert_equals(rangeAfter.startOffset, 0); + assert_equals(rangeAfter.endContainer, container); + assert_equals(rangeAfter.endOffset, 0); +}, 'Range is fully in shadow tree. Removing parent of shadow host collapses composed StaticRange.'); + +test(() => { + container.innerHTML = '<div id="hello">Hello,</div><div id="world"> World</div>'; + getSelection().setBaseAndExtent(hello.firstChild, 1, world.firstChild, 3); + hello.firstChild.remove(); + const rangeAfter = getSelection().getComposedRanges()[0]; + + assert_equals(rangeAfter.startContainer, hello); + assert_equals(rangeAfter.startOffset, 0); + assert_equals(rangeAfter.endContainer, world.firstChild); + assert_equals(rangeAfter.endOffset, 3); +}, 'Range is in light DOM. Removing startContainer rescopes new composed range to its parent.'); + +test(() => { + container.innerHTML = 'a<div id="host"></div>b'; + const host = container.querySelector('#host'); + const shadowRoot = host.attachShadow({ mode }); + shadowRoot.innerHTML = 'hello, world'; + getSelection().setBaseAndExtent(shadowRoot.firstChild, 7, container, 2); + shadowRoot.innerHTML = ''; + const rangeAfter = getSelection().getComposedRanges({ shadowRoots: [shadowRoot] })[0]; + + assert_equals(rangeAfter.startContainer, shadowRoot, 'collapsed to be at the parent shadow root'); + assert_equals(rangeAfter.startOffset, 0); + assert_equals(rangeAfter.endContainer, container); + assert_equals(rangeAfter.endOffset, 2); +}, 'Range is across shadow trees. Replacing shadowRoot content rescopes new composed range to the shadowRoot.'); + +test(() => { + container.innerHTML = [ + '<div id=host>', + '<div id=div1 slot=slot2>slotted content 1</div>', + '<div id=div2 slot=slot1>slotted content 2</div>', + '</div>' + ].join(''); + const shadowRoot = host.attachShadow({mode: 'open'}); + shadowRoot.innerHTML = [ + '<span>before</span>', + '<slot name=slot1></slot>', + '<span>between</span>', + '<slot name=slot2></slot>', + '<span>after</span>', + ].join(''); + + const sel = getSelection(); + sel.setBaseAndExtent(div1.firstChild, 2, div2.firstChild, 2); + div1.remove(); + + const rangeAfter = getSelection().getComposedRanges({ shadowRoots: [shadowRoot] })[0]; + assert_equals(rangeAfter.startContainer, host); + assert_equals(rangeAfter.startOffset, 0); + assert_equals(rangeAfter.endContainer, div2.firstChild); + assert_equals(rangeAfter.endOffset, 2); +}, 'Range is between two light slotted contents. Removing start container rescopes to its parent in light tree.'); + +</script> +</body> +</html> diff --git a/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html b/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html new file mode 100644 index 00000000000..d9664b0e150 --- /dev/null +++ b/tests/wpt/tests/selection/shadow-dom/tentative/Selection-getComposedRanges-slot.html @@ -0,0 +1,124 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="author" href="mailto:dizhangg@chromium.org"> +<meta name="assert" content="Selection's getComposedRanges should return a sequence of static ranges, selecting from slotted content"> +<link rel="help" href="https://w3c.github.io/selection-api/#dom-selection-getcomposedranges"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div id="container"></div> + +<script> + +test(() => { + container.innerHTML = '<div id=host>Second</div>'; + const shadowRoot = host.attachShadow({ mode:"open" }); + shadowRoot.innerHTML = 'First <slot></slot> Third'; + const second = host.firstChild; + const third = shadowRoot.querySelector('slot').nextSibling; + + const sel = getSelection(); + // Select from slotted second to shadowed third. + sel.setBaseAndExtent(second, 3, third, 4); + + assert_equals(sel.getRangeAt(0).startContainer, second); + assert_equals(sel.getRangeAt(0).startOffset, 3); + assert_equals(sel.getRangeAt(0).endContainer, second, 'Collapsed because crossing shadow tree is not supported for getRangeAt.'); + assert_equals(sel.getRangeAt(0).endOffset, 3); + + assert_equals(sel.getComposedRanges()[0].startContainer, container); + assert_equals(sel.getComposedRanges()[0].startOffset, 0, 'Rescoped because no shadow roots were provided'); + assert_equals(sel.getComposedRanges()[0].endContainer, second); + assert_equals(sel.getComposedRanges()[0].endOffset, 3); + + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); + + // Repeat the test, but reversing base and extent. This should not affect the range's start and end positions. + sel.setBaseAndExtent(third, 4, second, 3); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); +}, 'Setting the range to start on slotted content and end in shadow tree, should follow DOM tree order.'); + +test(() => { + container.innerHTML = [ + '<div id=host>', + '<div id=div1 slot=slot2>slotted content 1</div>', + '<div id=div2 slot=slot1>slotted content 2</div>', + '</div>' + ].join(''); + const shadowRoot = host.attachShadow({mode: 'open'}); + shadowRoot.innerHTML = [ + '<span>before</span>', + '<slot name=slot1></slot>', + '<span>between</span>', + '<slot name=slot2></slot>', + '<span>after</span>', + ].join(''); + + const sel = getSelection(); + // Select from slotted div1 to slotted div2. + sel.setBaseAndExtent(div1.firstChild, 2, div2.firstChild, 2); + + assert_equals(sel.getRangeAt(0).startContainer, div1.firstChild); + assert_equals(sel.getRangeAt(0).startOffset, 2); + assert_equals(sel.getRangeAt(0).endContainer, div2.firstChild, 'Not collapsed because we are not crossing shadow trees.'); + assert_equals(sel.getRangeAt(0).endOffset, 2); + + assert_equals(sel.getComposedRanges()[0].startContainer, div1.firstChild); + assert_equals(sel.getComposedRanges()[0].startOffset, 2); + assert_equals(sel.getComposedRanges()[0].endContainer, div2.firstChild, 'Not rescoped because we are not crossing shadow trees.'); + assert_equals(sel.getComposedRanges()[0].endOffset, 2); + + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, div1.firstChild); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 2); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, div2.firstChild); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 2); + + // Repeat the test, but reversing base and extent. This should not affect the range's start and end positions. + sel.setBaseAndExtent(div2.firstChild, 2, div1.firstChild, 2); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, div1.firstChild); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 2); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, div2.firstChild); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 2); +}, 'Setting the range to start and end on slotted content, should follow DOM tree order.'); + +test(() => { + container.innerHTML = '<div id=host>Second</div>'; + const shadowRoot = host.attachShadow({ mode:"open" }); + shadowRoot.innerHTML = '<span id="first">First</span><span id=third>Third</span>'; + const second = host.firstChild; + const third = shadowRoot.getElementById('third').firstChild; + + const sel = getSelection(); + // Select from unslotted second to shadowed third. + sel.setBaseAndExtent(second, 3, third, 4); + + assert_equals(sel.getRangeAt(0).startContainer, second); + assert_equals(sel.getRangeAt(0).startOffset, 3); + assert_equals(sel.getRangeAt(0).endContainer, second, 'Collapsed because crossing shadow tree is not supported for getRangeAt.'); + assert_equals(sel.getRangeAt(0).endOffset, 3); + + assert_equals(sel.getComposedRanges()[0].startContainer, container); + assert_equals(sel.getComposedRanges()[0].startOffset, 0, 'Rescoped because no shadow roots were provided'); + assert_equals(sel.getComposedRanges()[0].endContainer, second); + assert_equals(sel.getComposedRanges()[0].endOffset, 3); + + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); + + // Repeat the test, but reversing base and extent. This should not affect the range's start and end positions. + sel.setBaseAndExtent(third, 4, second, 3); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); + assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); +}, 'Setting the range to start on unslotted content and end in shadow tree, should follow DOM tree order.'); +</script> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-across-scopes.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-across-scopes.html index 76e5af8c74b..629bfea2aff 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-across-scopes.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-across-scopes.html @@ -18,9 +18,9 @@ } </style> -<!-- Since C is a direct reading flow item, it is visited first. --> -<!-- Since B,A are inside a display: contents, they are visited after. --> -<div class="test-case" data-expect="C,B,A" +<!-- Since B,A are inside a display: contents, they are visited together. --> +<!-- Since B has order 1, its display: contents parent is visited first. --> +<div class="test-case" data-expect="B,A,C" data-description="Grid items in shadow host that is a display contents grid item"> <div class=wrapper> <div style="display: contents"> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-display-contents.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-display-contents.html index b69f3d20799..6d012f49cea 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-display-contents.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-display-contents.html @@ -19,8 +19,8 @@ } </style> -<div class="test-case" data-expect="order1,order3,order2,order4" - data-description="Items in display contents are sorted in same grid container."> +<div class="test-case" data-expect="order1,order2,order4,order3" + data-description="Items in display contents are sorted in same grid container and are placed in the position where their first child resides."> <div class="wrapper"> <div style="display: contents"> <button id="order3" style="order: 3">Order 3</button> @@ -33,8 +33,8 @@ </div> </div> -<div class="test-case" data-expect="div1B,order1B,order3B,div2B,order2B,order4B" - data-description="Items in display contents are sorted in same grid container, with focusable display contents divs at the end of the focus sequence."> +<div class="test-case" data-expect="div1B,order1B,div2B,order2B,order4B,order3B" + data-description="Items in display contents are sorted in same grid container and are placed in the position where their first child resides. The display contents have tabindex and should be focusable."> <div class="wrapper"> <div id="div1B" style="display: contents" tabindex="0"> <button id="order3B" style="order: 3">Order 3</button> @@ -47,9 +47,9 @@ </div> </div> -<div class="test-case" data-expect="A1,A2,A3,B1,B2,B3,C1,C2,C3,D1,D2,D3" +<div class="test-case" data-expect="C1,C2,C3,D1,D2,D3,B1,B2,B3,A1,A2,A3" data-description="Grid items are in nested display contents containers."> - <div class=box> + <div class=wrapper> <div style="display:contents" tabindex="0" id="A1"> <div style="display:contents" tabindex="0" id="A2"> <button style="order: 4" id="A3">A</button> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-slots.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-slots.html index f52c9ebdc81..eff412296d9 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-slots.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-flow/tentative/grid-order-with-slots.html @@ -55,7 +55,7 @@ </span> <br> -<span id="host3" class="test-case" data-expect="host3/o2,host3/o4,o1,o3,o5" +<span id="host3" class="test-case" data-expect="o1,o3,o5,host3/o2,host3/o4" data-description="Slot is inside a grid container with reading-flow."> <template shadowrootmode="open"> <style> @@ -77,7 +77,7 @@ <br> <span id="host4" class="test-case" - data-expect="host4/after,host4/before,b4,a4,d42,d41,d43,c4" + data-expect="b4,a4,d42,d41,d43,c4,host4/after,host4/before" data-description="Slot is a grid with reading-flow inside a grid container with reading-flow."> <template shadowrootmode="open"> <style> @@ -120,7 +120,7 @@ </span> <br> -<span id="host6" class="test-case" data-expect="host6/after,host6/before,b6,a6" +<span id="host6" class="test-case" data-expect="b6,a6,host6/after,host6/before" data-description="Slot is a display contents inside a grid container."> <template shadowrootmode="open"> <style> @@ -140,7 +140,7 @@ </span> <br> -<span id="host7" class="test-case" data-expect="a7,b7,host7/after,host7/before" +<span id="host7" class="test-case" data-expect="host7/after,a7,b7,host7/before" data-description="Slot is a display block inside a grid container."> <template shadowrootmode="open"> <style> @@ -150,8 +150,8 @@ } </style> <div class="wrapper"> - <button style="order: 4" id="before">Before</button> - <slot style="display: block" style="order: 4"></slot> + <button style="order: 5" id="before">Before</button> + <slot style="display: block; order: 4"></slot> <button style="order: 3" id="after">After</button> </div> </template> diff --git a/tests/wpt/tests/shared-storage/interest-groups.tentative.https.sub.html b/tests/wpt/tests/shared-storage/interest-groups.tentative.https.sub.html new file mode 100644 index 00000000000..2889500be23 --- /dev/null +++ b/tests/wpt/tests/shared-storage/interest-groups.tentative.https.sub.html @@ -0,0 +1,41 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/shared-storage/resources/util.js"></script> +<script src="/fenced-frame/resources/utils.js"></script> + +<body> +<script> +'use strict'; + +promise_test(async t => { + const ig = { + owner: window.location.origin, + name: 'default name', + lifetimeMs: 100000 + }; + + await navigator.joinAdInterestGroup(ig); + await sharedStorage.worklet.addModule('resources/simple-module.js'); + + const ancestor_key = token(); + let url0 = generateURL("/shared-storage/resources/frame0.html", + [ancestor_key]); + let url1 = generateURL("/shared-storage/resources/frame1.html", + [ancestor_key]); + + let select_url_result = await sharedStorage.selectURL( + "verify-interest-groups", [{url: url0}, {url: url1}], + {data: {'expectedOwner': ig.owner, 'expectedName': ig.name}, + resolveToConfig: true}); + assert_true(validateSelectURLResult(select_url_result, true)); + attachFencedFrame(select_url_result, 'opaque-ads'); + const result = await nextValueFromServer(ancestor_key); + + // This indicates that `interestGroups()` returns expected result. + assert_equals(result, "frame1_loaded"); +}, 'Basic test for `interestGroups()` in the shared storage worklet'); + +</script> +</body> diff --git a/tests/wpt/tests/shared-storage/resources/simple-module.js b/tests/wpt/tests/shared-storage/resources/simple-module.js index 11b650811dc..eeb0ce95b04 100644 --- a/tests/wpt/tests/shared-storage/resources/simple-module.js +++ b/tests/wpt/tests/shared-storage/resources/simple-module.js @@ -4,6 +4,13 @@ var globalVar = 0; +async function busyWaitMs(time_to_wait) { + const startTime = Date.now(); + while (Date.now() - startTime < time_to_wait) { + + } +} + class TestURLSelectionOperation { async run(urls, data) { if (data && data.hasOwnProperty('setKey') && data.hasOwnProperty('setValue')) { @@ -50,8 +57,54 @@ class VerifyKeyNotFound { } } +class VerifyInterestGroups { + async run(urls, data) { + if (data && + data.hasOwnProperty('expectedOwner') && + data.hasOwnProperty('expectedName')) { + + const groups = await interestGroups(); + + if (groups.length !== 1) { + return -1; + } + + if (groups[0]["owner"] !== data['expectedOwner']) { + return -1; + } + + if (groups[0]["name"] !== data['expectedName']) { + return -1; + } + + return 1; + } + return -1; + } +} + +class GetWaitIncrementWithinLockOperation { + async run(urls, data) { + if (data && data.hasOwnProperty('key')) { + await navigator.locks.request("lock0", async (lock) => { + let value_read = await sharedStorage.get(data['key']); + value_read = value_read ? Number(value_read) : 0; + + await busyWaitMs(100); + + await sharedStorage.set(data['key'], value_read + 1); + }); + + return 1; + } + return -1; + } +} + register('test-url-selection-operation', TestURLSelectionOperation); register('increment-global-variable-and-return-original-value-operation', IncrementGlobalVariableAndReturnOriginalValueOperation); register('verify-key-value', VerifyKeyValue); register('verify-key-not-found', VerifyKeyNotFound); +register('verify-interest-groups', VerifyInterestGroups); +register('get-wait-increment-within-lock', GetWaitIncrementWithinLockOperation); diff --git a/tests/wpt/tests/shared-storage/web-locks.tentative.https.sub.html b/tests/wpt/tests/shared-storage/web-locks.tentative.https.sub.html new file mode 100644 index 00000000000..49a039368a3 --- /dev/null +++ b/tests/wpt/tests/shared-storage/web-locks.tentative.https.sub.html @@ -0,0 +1,62 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/shared-storage/resources/util.js"></script> +<script src="/fenced-frame/resources/utils.js"></script> + +<body> +<script> +'use strict'; + +promise_test(async t => { + let worklet1 = await sharedStorage.createWorklet('resources/simple-module.js'); + let worklet2 = await sharedStorage.createWorklet('resources/simple-module.js'); + + const ancestor_key1 = token(); + let url1_0 = generateURL("/shared-storage/resources/frame0.html", + [ancestor_key1]); + let url1_1 = generateURL("/shared-storage/resources/frame1.html", + [ancestor_key1]); + + const ancestor_key2 = token(); + let url2_0 = generateURL("/shared-storage/resources/frame0.html", + [ancestor_key2]); + let url2_1 = generateURL("/shared-storage/resources/frame1.html", + [ancestor_key2]); + + // Two `selectURL()`s run in parallel. Each performs the following steps: + // 1. Acquires the lock. + // 2. Reads the current value of the given key. + // 3. Waits for 100ms. + // 4. Increments the value. + // 5. Releases the lock. + // + // Expected behavior: After both operations finish, the value of the given key + // should be 2. + // + // This demonstrates that the lock is effective, preventing the + // "get and increment" operations from interleaving. If the lock were not + // used, both worklets would likely read 0 and set the value to 1. + + let select_url_result1 = await worklet1.selectURL( + "get-wait-increment-within-lock", [{url: url1_0}, {url: url1_1}], + {data: {'key': 'key'}, resolveToConfig: true}); + + let select_url_result2 = await worklet2.selectURL( + "get-wait-increment-within-lock", [{url: url2_0}, {url: url2_1}], + {data: {'key': 'key'}, resolveToConfig: true}); + + attachFencedFrame(select_url_result1, 'opaque-ads'); + const result1 = await nextValueFromServer(ancestor_key1); + assert_equals(result1, "frame1_loaded"); + + attachFencedFrame(select_url_result2, 'opaque-ads'); + const result2 = await nextValueFromServer(ancestor_key2); + assert_equals(result2, "frame1_loaded"); + + await verifyKeyValueForOrigin('key', '2', location.origin); +}, 'Basic test for Web Locks API in the shared storage worklet'); + +</script> +</body> diff --git a/tests/wpt/tests/speculation-rules/prerender/resources/csp-script-src-self.html b/tests/wpt/tests/speculation-rules/prerender/resources/csp-script-src-self.html index 8dc382068a3..61a8f31396c 100644 --- a/tests/wpt/tests/speculation-rules/prerender/resources/csp-script-src-self.html +++ b/tests/wpt/tests/speculation-rules/prerender/resources/csp-script-src-self.html @@ -2,14 +2,14 @@ <head> <!-- disallow inline script --> - <meta http-equiv="Content-Security-Policy" content="script-src 'self'"> + <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-allowed-inline-script-for-test'"> </head> <script src="/common/utils.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="utils.js"></script> <script src="csp-script-src.js"></script> -<script> - const params = new URLSearchParams(location.search); - writeValueToServer(params.get('key'), "csp is ignored unexpectedly"); +<script nonce="allowed-inline-script-for-test"> + const searchParams = new URLSearchParams(location.search); + writeValueToServer(searchParams.get('key'), "csp is ignored unexpectedly"); </script> diff --git a/tests/wpt/tests/storage/quotachange-in-detached-iframe.tentative.https.html b/tests/wpt/tests/storage/quotachange-in-detached-iframe.tentative.https.html deleted file mode 100644 index 123af50e3ce..00000000000 --- a/tests/wpt/tests/storage/quotachange-in-detached-iframe.tentative.https.html +++ /dev/null @@ -1,21 +0,0 @@ -<!doctype html> -<meta charset="utf-8"> -<title>quotachange event on DOMWindow of detached iframe</title> -<link rel="author" href="jarrydg@chromium.org" title="Jarryd"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<iframe id="iframe"></iframe> -<script> -'use strict'; - -test(t => { - const iframe = document.getElementById('iframe'); - const frameWindow = iframe.contentWindow; - const storageManager = frameWindow.navigator.storage; - - iframe.parentNode.removeChild(iframe); - const emptyListener = () => {}; - storageManager.addEventListener('quotachange', emptyListener); - storageManager.removeEventListener('quotachange', emptyListener); -}, "Add quotachange listener on detached iframe."); -</script> diff --git a/tests/wpt/tests/svg/animations/animate-display-to-none-001.html b/tests/wpt/tests/svg/animations/animate-display-to-none-001.html new file mode 100644 index 00000000000..ce8e493840e --- /dev/null +++ b/tests/wpt/tests/svg/animations/animate-display-to-none-001.html @@ -0,0 +1,30 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Test that underlying style gets restored when seeking away from the + 'to' portion of a SVG/SMIL animation to 'display:none'</title> +<link rel="help" href="https://www.w3.org/TR/smil-animation/#ToAttribute"> +<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> +<link rel="match" href="../struct/reftests/reference/green-100x100.html"> +<script> + function go() { + svgElem.pauseAnimations(); + + /* Seek to 75% of the way through duration, when the animation should be + * imposing the "to" value. (This is necessary to trigger the bug + * that we're regression-testing for here.) */ + svgElem.setCurrentTime(3); + + /* Now, seek back to 25% of the way through duration, when the underlying + * value should be restored. This should make the green rect show up + * in our reftest screenshot. */ + svgElem.setCurrentTime(1); + } +</script> +<body onload="go()"> +<svg id="svgElem"> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green"> + <animate attributeName="display" to="none" + begin="0s" dur="4s"/> + </rect> +</svg> diff --git a/tests/wpt/tests/svg/painting/reftests/small-nested-viewbox-ref.html b/tests/wpt/tests/svg/painting/reftests/small-nested-viewbox-ref.html new file mode 100644 index 00000000000..f737b09ff49 --- /dev/null +++ b/tests/wpt/tests/svg/painting/reftests/small-nested-viewbox-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<style> + svg { + width: 16px; + padding: 4px; + background: #ccc; + color: #000; + } +</style> +<svg width='16' height='16'> + <svg viewBox='0 0 256 256'> + <rect width="256" height="256" x="0" y="0" fill="green" /> + </svg> +</svg> diff --git a/tests/wpt/tests/svg/painting/reftests/small-nested-viewbox.html b/tests/wpt/tests/svg/painting/reftests/small-nested-viewbox.html new file mode 100644 index 00000000000..3d9fb8cb45f --- /dev/null +++ b/tests/wpt/tests/svg/painting/reftests/small-nested-viewbox.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1922222"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="match" href="small-nested-viewbox-ref.html"> +<style> + svg { + width: 16px; + padding: 4px; + background: #ccc; + color: #000; + } +</style> +<svg viewBox="0 0 4 4"> + <svg viewBox='0 0 256 256'> + <rect width="256" height="256" x="0" y="0" fill="green" /> + </svg> +</svg> diff --git a/tests/wpt/tests/tools/certs/cacert.key b/tests/wpt/tests/tools/certs/cacert.key index 421cae4c51a..dd47af3f939 100644 --- a/tests/wpt/tests/tools/certs/cacert.key +++ b/tests/wpt/tests/tools/certs/cacert.key @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQISJq4lddWxR0CAggA -MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECNwjuqbwzC5YBIIEyGihC3NgVhjk -hIu+a8kWhGQvYRyBB0Da0IKdJeNx4KUrSqGdseH84Fss3pv0IpP35okkQ2M7Ityr -bmrS1XeEFJB6ghBNNodAk/nB1HdRdIfwOy8DYA20kD+loe5UMx5i+hwbJUPrSlKq -KeJIvn5TahKPi480iQ6NwtHcpmwjtG6gbS4zDa0x1Oe1UrtyTKo5VHRNexXiqjxS -AwTjAQJXHoZCVh275gppqu58Sh+XKz9vQ0UMUogc50v8+lXCHb4EAQeD4uO5p+8M -DveSV31RSBfT7ZjeF+5u08gdEpTvZVF21Jn9OR4PzHX/sGf13RboLEmy3k3dRWVS -40ux4U61WEij7oM9oXrL9429K3CesNPB+HOdmqVi2Y/NviX4UdFdOb2oJqs4CA6L -ERqD/Q2SL1KaWQmvFfsg6OPWp4Q6mrGC+Qj0nH3Tkw6l3QUktCqPly6ZaH4Whf3X -0pzDov1r9LMcfqA3MPWevTkjJUFIqigSp9On/ofzLTLXRzmZfh5cpEvSrOQTJ0jV -prVdKT+2rEFLEG3rNG5dj73ADxlagO/3bgI/Kvy80Jf95x1BTG/1nOuTJKZ99Q+K -6KrxZNQdVqfoOJlI+uV1rc25ufY1ttHXTCozKDL2+xVqByL9FnqtnlSJc27PayF4 -r7gQNp8fdjruBPt+hyhVkCrg/LhPx0bSQQZYZ/DYFaFcKow25AGUlJbTipgp/YDb -mBBLYoyqfK6BXSQc1NGYvj/jMkJnaL5TcsHUYPB66225PCPl9xr8lug6dtTFeIg0 -/lGeB0ppGtu4npfSV1YBaKvNfs0EWKK0wbarbLl97yoGBOnT5cTe9Mzkohry3Uoc -AUCed1Enx2fFela9XzVQsrzoqQUtXuRrFOH/7avyncpRoRAJ7OzsLiVtAO2uq9Eo -wERu5IviHABHrn7EQZnTPpVEWfoOol9zu5vnG4rlvgffe7Mobx0eC1xlK37J+sez -x3hmOcKoJZx2PXsaxLX7vaF/PgO8vt2KGciJ9s3nS4QubZnFOmoPj87hUg+f0y3i -wY8Xea+rJeiLurX4S9ZlUuN8/xroYIMPS1KuP7pT6lUlmQONy/vECZsHhjvHVybh -pC9Q13W5bW7vaOOWHEBz/poh1AlnNQjELhBQ2sv1OYWHZAvP+vw2n/P9uTCvg4Rl -34fCAsrh4gd35DH1VEwFwKQh7QuexR7Cxrrtw0Ac7XOU8Fx2ktrf65gV7zN/TrZK -H2JuEjDbWXqpAy7Y2+WpldueCx8GN10eere1G1S89AVD2LR+SB4n1CrCgwBf4JFK -soqYTUsK6jSIaM9NY0LxykwaT2WD7lRIFu826GnMLQ2C3LgFUtxms1uiAdfwe/J+ -Dtsx8z6CKJ0fkNXbx/kMKEfY8EmMShWwU3kAbUlMZezUZLlynuqOyF/ahML538bC -/12tvDds8/n8ZAwS3uLrawxTSOUD3AbVi80brsyF3dfavycUY5ViI7i/5Ie/mIt0 -acX0VWH0mSZgSUeox0pPtB8B6ow3/DIGrdZ5r34Hm4XT1VynMm0jgAq7AUv3gVwJ -GUMWU6teGv+Jov/CKUwfe0xWgVqcd/aJgVS1U8pu729l5WBhHTxh2xVK3ciBN8bv -UeDxQ//R4iyzwXG352JHpA== +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIQ5KidoYVfxkCAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECMn0jRuVwL1yBIIEyP+RfjlPlBdC +KpYXU3bQMGIXnYeQLoaaGjVGtsOsTs5qtvFVMkU2dbSmJHS81n4s8F2fDO0R8QiR +EICZJsD8/A16teQrxBy29ZSlpKNZQyGJkaJSoyPgLHBTMWJDvYKlu407xzoxXnx6 +FDVdTrVNmza0tdG2MN9r/hAuZoobWYyjJrazELB5yTTm2ZFNT7H9gF+K2eTDa/g5 +1cTeUBDNoC7ejtILyJALBNcN6eGnXZeeQLg1Dx93aUObSUpiYrqn9Q4zhzOUkaYw +jvErFMQvU9YW0HFN/J2YVbvlC/jsk6l3rFFObiWHkwhKJc2+pXu9z6Hhv/o1i7uu +XlXcNPD+poqsmrhOvEjmTK4Og8QvEcoR/lOUWBBhgLqtkD88SHJrqBb5JStaAStH +c/Q+oYnox3VAhMU0sB8thg2KQ+piTGLQP/2aD1NJvNul2JEB9zAcVAoCSCz1mc8P +yGyvoZKGBmvqEskX0JMCnx6sLKOlKtqFF2/9Uair/6vrQND8MLU/ksjzzUncb24n +jokua7HbmrBw7GKQH+75/0nJWOMusTZtrwxCVKWJL3M6LQ9N4NaP0nbvfj54lyVy +lGBD6W9fXB3/4FjmIFEqd9T+ltgmJlHSUUox3avXS3PAuGfaIFYZ4Tjoik1uYIt4 +S3NMwH6ysI+4UrU1D/1UJl+7/KSLo/k+hq0hH/0D0XEva8FDq4/4HrX843awR0Em +BUVE7MVIF0hHpbpZ/znV5LFY4czXlgpp3B32ac07i4iJCDk8KCclyCjyMWEFQ87O +zIMk8h/BjiP1Uzyr0wGFjyYP2gu7nmuzjrBAkIlWQ9xU9aiTfwQkEkMo7RJA4M1b +DC9Vdt4Mfzv603UdwAF8BVozgWxONV37VLbAu4r0ENw0C2rf9ZGxO1D9KITjVVF8 +xcSWsm7n0VATqd5MB6sUyzc7AuyQbewQ1AMsTNv5baxLooka/NZTcfqXQmD08C7O +pXJP3kUJweNXw6lUsjtR0VYe0MJOeo2oe/CLoDv+xej4Ez5xTPDAdzIJEk6K8Y7C +jCcIhTz2WOiTA2MDE1UmY8lZJzaWNjNfetGcfIBh00YYcsmSVByr/YbKgh7KN1Rb +Qek2k0l390jLOG64t1MM6QaNCDX11bq+pS2hSVyivfE7olrrWjxdjHFOlFqcHRVE +8+lMewf6RfO8iYZtHNgcVFYZcTyo/wbf9fEN5YAuoG++3U6vTITtWhXp9GoRGZ/i +EBfJzvuFt2FU5GbBub9n3fC/d+iOUeVl8jtZ3+xK5MAHdbTs1E4+AW9goU8pSXcF +JEJcF4AAj76XbKH0U+jC2umrkFOlVXP/hnuPxZcKDhaHVBB0Z8xSHo6RClUc/+rP +pgfeMvFf4tnEdGPdj2ZUc808nilzJ63jB+cVuZJB7lnGQCPMH8k+pnBSFkJmk+To +vk2HckfrW1d3rZ59jHBPySEbv8a7wLm+adSJGtG1CK8wHKhhGyXbgpE1OTtLWUec +n//yDEvVhs/p8HDmRvARBdc93CLWhM/YhPLzSrItCFuPWOMuOTXINZGb4KqQixcN +yb6GjBGNwNnXjDlpj23vlxUBYS3iRnOit84aPH1JdAxElTc8oI63siwjc5LoUhQZ +cY5MQqTzu2MhIeEwgqlXmQ== -----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/wpt/tests/tools/certs/cacert.pem b/tests/wpt/tests/tools/certs/cacert.pem index cf16ae8aea3..7b3fb3da14d 100644 --- a/tests/wpt/tests/tools/certs/cacert.pem +++ b/tests/wpt/tests/tools/certs/cacert.pem @@ -1,125 +1,125 @@ -----BEGIN CERTIFICATE----- -MIIW5zCCFc+gAwIBAgIDAb4YMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEndl -Yi1wbGF0Zm9ybS10ZXN0czAeFw0yNDA5MTIwMTAzMTBaFw0yNTA5MTIwMTAzMTBa -MB0xGzAZBgNVBAMMEndlYi1wbGF0Zm9ybS10ZXN0czCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKk/RuiyVSsKvV1yaETX9S6zQ4V0zMsjbWZOTZ09NoIj -r/vMnmrthOzGsUoU2tArgEFsWA2drKwNJqsp4aXuit4F2lNoP4Fp16KrT6k2NQyY -hRJltaPhfLYpZHX4KBKyu5zojxVnbrxxEgbp+F/GcVHmwR9bZImCWJKJwWdP/zrM -JLHvXAHXk+h1PiovC1U3EU0iOcLCQM4jTimvoKdgcDe06vjHlFk43pM7Y6AnHxai -g/GAJufGhkOfm4re+bow5akZinFt68uvwL198mcl/76ozLQaU2qPP/EAzV8jNdf7 -HK8JNX2sGP+QItSO1EPsDZwjWTlcaE/PaXIyffUiWZsCAwEAAaOCFC4wghQqMAwG -A1UdEwQFMAMBAf8wHQYDVR0OBBYEFP5kQf3rJdJUaqbhNvYSKlb5gva1MEcGA1Ud -IwRAMD6AFP5kQf3rJdJUaqbhNvYSKlb5gva1oSGkHzAdMRswGQYDVQQDDBJ3ZWIt -cGxhdGZvcm0tdGVzdHOCAwG+GDALBgNVHQ8EBAMCAgQwggoFBgNVHR4Eggn8MIIJ -+KCCCfQwE4IRd2ViLXBsYXRmb3JtLnRlc3QwF4IVbm90LXdlYi1wbGF0Zm9ybS50 -ZXN0MBeCFXd3dy53ZWItcGxhdGZvcm0udGVzdDAYghZ3d3cyLndlYi1wbGF0Zm9y -bS50ZXN0MBiCFnd3dzEud2ViLXBsYXRmb3JtLnRlc3QwG4IZd3d3Lnd3dy53ZWIt -cGxhdGZvcm0udGVzdDAbghl3d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGnd3 -dy53d3cxLndlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dzIud3d3LndlYi1wbGF0Zm9y -bS50ZXN0MByCGnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dzEud3d3 -LndlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0 -MByCGnd3dy53d3cyLndlYi1wbGF0Zm9ybS50ZXN0MB2CG3d3dzEud3d3Mi53ZWIt -cGxhdGZvcm0udGVzdDAdght3d3cyLnd3dzEud2ViLXBsYXRmb3JtLnRlc3QwHYIb -d3d3Mi53d3cyLndlYi1wbGF0Zm9ybS50ZXN0MB2CG3d3dzEud3d3MS53ZWItcGxh -dGZvcm0udGVzdDAfgh13d3cud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAggh53 -d3cud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIIIed3d3Lnd3dzIubm90LXdl -Yi1wbGF0Zm9ybS50ZXN0MCCCHnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVz -dDAggh53d3cyLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIIIed3d3MS53d3cu -bm90LXdlYi1wbGF0Zm9ybS50ZXN0MCGCH3d3dzIud3d3Mi5ub3Qtd2ViLXBsYXRm -b3JtLnRlc3QwIYIfd3d3MS53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAhgh93 -d3cxLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCGCH3d3dzIud3d3MS5ub3Qt -d2ViLXBsYXRmb3JtLnRlc3QwJIIieG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZv -cm0udGVzdDAkgiJ3d3cueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0MCSC -InhuLS1sdmUtNmxhZC53d3cud2ViLXBsYXRmb3JtLnRlc3QwJYIjd3d3MS54bi0t -bHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3QwJYIjd3d3Mi54bi0tbHZlLTZsYWQu -d2ViLXBsYXRmb3JtLnRlc3QwJYIjeG4tLWx2ZS02bGFkLnd3dzEud2ViLXBsYXRm -b3JtLnRlc3QwJYIjeG4tLWx2ZS02bGFkLnd3dzIud2ViLXBsYXRmb3JtLnRlc3Qw -KIImd3d3LnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwKIImeG4t -LWx2ZS02bGFkLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwKYInd3d3Mi54bi0t -bHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCmCJ3huLS1sdmUtNmxhZC53 -d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdDApgid3d3cxLnhuLS1sdmUtNmxhZC5u -b3Qtd2ViLXBsYXRmb3JtLnRlc3QwKYIneG4tLWx2ZS02bGFkLnd3dzIubm90LXdl -Yi1wbGF0Zm9ybS50ZXN0MCuCKXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1w -bGF0Zm9ybS50ZXN0MC2CK3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQud2ViLXBs -YXRmb3JtLnRlc3QwL4Itd3d3LnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1w -bGF0Zm9ybS50ZXN0MC+CLXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dy53ZWIt -cGxhdGZvcm0udGVzdDAvgi14bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2Vi -LXBsYXRmb3JtLnRlc3QwMIIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3Mi53 -ZWItcGxhdGZvcm0udGVzdDAwgi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cx -LndlYi1wbGF0Zm9ybS50ZXN0MDCCLnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYy -OGEud2ViLXBsYXRmb3JtLnRlc3QwMIIud3d3Mi54bi0tbjhqNmRzNTNsd3drcnFo -djI4YS53ZWItcGxhdGZvcm0udGVzdDAxgi94bi0tbHZlLTZsYWQueG4tLWx2ZS02 -bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdDAzgjF4bi0tbjhqNmRzNTNsd3drcnFo -djI4YS53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDOCMXd3dy54bi0tbjhqNmRz -NTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwNIIyeG4tLW44ajZk -czUzbHd3a3JxaHYyOGEud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwNIIyeG4t -LW44ajZkczUzbHd3a3JxaHYyOGEud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3Qw -NIIyd3d3MS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3Jt -LnRlc3QwNIIyd3d3Mi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBs -YXRmb3JtLnRlc3QwOII2eG4tLWx2ZS02bGFkLnhuLS1uOGo2ZHM1M2x3d2tycWh2 -MjhhLndlYi1wbGF0Zm9ybS50ZXN0MDiCNnhuLS1uOGo2ZHM1M2x3d2tycWh2Mjhh -LnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdDA8gjp4bi0tbHZlLTZsYWQu -eG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDyC -OnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBs -YXRmb3JtLnRlc3QwQ4JBeG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4tLW44ajZk -czUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3QwR4JFeG4tLW44ajZkczUz -bHd3a3JxaHYyOGEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0 -Zm9ybS50ZXN0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMIIJhQYDVR0RBIIJfDCCCXiC -EXdlYi1wbGF0Zm9ybS50ZXN0ghVub3Qtd2ViLXBsYXRmb3JtLnRlc3SCFXd3dy53 -ZWItcGxhdGZvcm0udGVzdIIWd3d3Mi53ZWItcGxhdGZvcm0udGVzdIIWd3d3MS53 -ZWItcGxhdGZvcm0udGVzdIIZd3d3Lnd3dy53ZWItcGxhdGZvcm0udGVzdIIZd3d3 -Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIad3d3Lnd3dzEud2ViLXBsYXRmb3JtLnRl -c3SCGnd3dzIud3d3LndlYi1wbGF0Zm9ybS50ZXN0ghp3d3cxLm5vdC13ZWItcGxh -dGZvcm0udGVzdIIad3d3MS53d3cud2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIubm90 -LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIb -d3d3MS53d3cyLndlYi1wbGF0Zm9ybS50ZXN0ght3d3cyLnd3dzEud2ViLXBsYXRm -b3JtLnRlc3SCG3d3dzIud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cx -LndlYi1wbGF0Zm9ybS50ZXN0gh13d3cud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVz -dIIed3d3Lnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cud3d3Mi5ub3Qt -d2ViLXBsYXRmb3JtLnRlc3SCHnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVz -dIIed3d3Mi53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cxLnd3dy5ub3Qt -d2ViLXBsYXRmb3JtLnRlc3SCH3d3dzIud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRl -c3SCH3d3dzEud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzEud3d3MS5u -b3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzIud3d3MS5ub3Qtd2ViLXBsYXRmb3Jt -LnRlc3SCInhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCInd3dy54 -bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCInhuLS1sdmUtNmxhZC53d3cu -d2ViLXBsYXRmb3JtLnRlc3SCI3d3dzEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9y -bS50ZXN0giN3d3cyLnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIjeG4t -LWx2ZS02bGFkLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCI3huLS1sdmUtNmxhZC53 -d3cyLndlYi1wbGF0Zm9ybS50ZXN0giZ3d3cueG4tLWx2ZS02bGFkLm5vdC13ZWIt -cGxhdGZvcm0udGVzdIImeG4tLWx2ZS02bGFkLnd3dy5ub3Qtd2ViLXBsYXRmb3Jt -LnRlc3SCJ3d3dzIueG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIIn -eG4tLWx2ZS02bGFkLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gid3d3cxLnhu -LS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53 -d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIpeG4tLW44ajZkczUzbHd3a3JxaHYy -OGEud2ViLXBsYXRmb3JtLnRlc3SCK3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQu -d2ViLXBsYXRmb3JtLnRlc3SCLXd3dy54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53 -ZWItcGxhdGZvcm0udGVzdIIteG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3Lndl -Yi1wbGF0Zm9ybS50ZXN0gi14bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2Vi -LXBsYXRmb3JtLnRlc3SCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIud2Vi -LXBsYXRmb3JtLnRlc3SCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzEud2Vi -LXBsYXRmb3JtLnRlc3SCLnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi -LXBsYXRmb3JtLnRlc3SCLnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi -LXBsYXRmb3JtLnRlc3SCL3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQubm90LXdl -Yi1wbGF0Zm9ybS50ZXN0gjF4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cubm90 -LXdlYi1wbGF0Zm9ybS50ZXN0gjF3d3cueG4tLW44ajZkczUzbHd3a3JxaHYyOGEu -bm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53 -d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIyeG4tLW44ajZkczUzbHd3a3JxaHYy -OGEud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMnd3dzEueG4tLW44ajZkczUz -bHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ3d3cyLnhuLS1uOGo2 -ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdII2eG4tLWx2ZS02 -bGFkLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0gjZ4 -bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3Jt -LnRlc3SCOnhuLS1sdmUtNmxhZC54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qt -d2ViLXBsYXRmb3JtLnRlc3SCOnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1s -dmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCQXhuLS1uOGo2ZHM1M2x3d2ty -cWh2MjhhLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0 -gkV4bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbjhqNmRzNTNsd3drcnFodjI4 -YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwDQYJKoZIhvcNAQELBQADggEBAG0UL9KU -qA8vHcdylWhvBI3cITzCn1kyX31Lr/9x68SEMV50pY7AFZMEBTVT1OzACzk9rc/p -OIRo1m+Z5CGhng6wOThjFtfYTmOvSqlLdYr/AOND9PvJ8iR4zbXpwTSQgiVBgW3u -aIYbBHbrOTD7mFdcrIo8nPc6seilpbzcEvLLAiGV7qgLvJXrC6lIg2eKXQHCuZO1 -SpQKhKi1+11JvbU3d9h96iVLG4WOVxmhALkJJvAZ7kPaTs76md4G6/B7WcO+F5wc -oEgnZoLU0rDMPDFCWsKLWVadseJiRCMs6Nrjog8Y1bMQPLTzCDO/8l2h8Ny1lxWx -GfyYQSXWV8lnS0w= +MIIW5TCCFc2gAwIBAgICBIIwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAwwSd2Vi +LXBsYXRmb3JtLXRlc3RzMB4XDTI0MTAxMjAxMDQ0NloXDTI1MTAxMjAxMDQ0Nlow +HTEbMBkGA1UEAwwSd2ViLXBsYXRmb3JtLXRlc3RzMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA03kHWKuFeT1xtYw3M/hYmoGe9ZM26J2WIPIVD0SOU86w +g+2L5JwllOH5L4i6vSz4qV2NAYnpSCUNNIGk7F8YLWFXP8O8GDMgjg1V/JDYCPj5 +KFa6bAjLhHD9tLKVcRn7h6L7Y7FYWkYm6LWNOctg5UTbZVUEcCq0xeZKJXGJFguV +RK9CTz5wWUxYN3LvdAnW2XyryPqyUZSHcF55zYJBLDNUxkdPjI7nLS/y+WryIK89 +47RhiwbI9yI26Ir3IcFy2xLjs5+qo1DJcfCVC/m/8+86tgiSqmJwTJUW/cAVSd51 +F5X0P2SSP2YZctEXSInSUDMFmdQMecpxQBZV2pWNjQIDAQABo4IULTCCFCkwDAYD +VR0TBAUwAwEB/zAdBgNVHQ4EFgQUyWVn3/hgxfvg9xXR7Vttc+Jz1OcwRgYDVR0j +BD8wPYAUyWVn3/hgxfvg9xXR7Vttc+Jz1OehIaQfMB0xGzAZBgNVBAMMEndlYi1w +bGF0Zm9ybS10ZXN0c4ICBIIwCwYDVR0PBAQDAgIEMIIKBQYDVR0eBIIJ/DCCCfig +ggn0MBOCEXdlYi1wbGF0Zm9ybS50ZXN0MBeCFXd3dy53ZWItcGxhdGZvcm0udGVz +dDAXghVub3Qtd2ViLXBsYXRmb3JtLnRlc3QwGIIWd3d3MS53ZWItcGxhdGZvcm0u +dGVzdDAYghZ3d3cyLndlYi1wbGF0Zm9ybS50ZXN0MBuCGXd3dy53d3cud2ViLXBs +YXRmb3JtLnRlc3QwG4IZd3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghp3d3cy +Lnd3dy53ZWItcGxhdGZvcm0udGVzdDAcghp3d3cxLm5vdC13ZWItcGxhdGZvcm0u +dGVzdDAcghp3d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghp3d3cud3d3MS53 +ZWItcGxhdGZvcm0udGVzdDAcghp3d3cud3d3Mi53ZWItcGxhdGZvcm0udGVzdDAc +ghp3d3cxLnd3dy53ZWItcGxhdGZvcm0udGVzdDAdght3d3cyLnd3dzIud2ViLXBs +YXRmb3JtLnRlc3QwHYIbd3d3MS53d3cxLndlYi1wbGF0Zm9ybS50ZXN0MB2CG3d3 +dzIud3d3MS53ZWItcGxhdGZvcm0udGVzdDAdght3d3cxLnd3dzIud2ViLXBsYXRm +b3JtLnRlc3QwH4Idd3d3Lnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIIIed3d3 +Lnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCCCHnd3dzIud3d3Lm5vdC13ZWIt +cGxhdGZvcm0udGVzdDAggh53d3cud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3Qw +IIIeeG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0MCCCHnd3dzEud3d3Lm5v +dC13ZWItcGxhdGZvcm0udGVzdDAhgh93d3cxLnd3dzIubm90LXdlYi1wbGF0Zm9y +bS50ZXN0MCGCH3d3dzIud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIYIfd3d3 +Mi53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAhgh93d3cxLnd3dzEubm90LXdl +Yi1wbGF0Zm9ybS50ZXN0MCSCInhuLS1sdmUtNmxhZC53d3cud2ViLXBsYXRmb3Jt +LnRlc3QwJIIid3d3LnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdDAkgiJ4 +bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCWCI3d3dzEueG4tLWx2 +ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0MCWCI3huLS1sdmUtNmxhZC53d3cxLndl +Yi1wbGF0Zm9ybS50ZXN0MCWCI3d3dzIueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9y +bS50ZXN0MCWCI3huLS1sdmUtNmxhZC53d3cyLndlYi1wbGF0Zm9ybS50ZXN0MCiC +Jnd3dy54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCiCJnhuLS1s +dmUtNmxhZC53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCmCJ3d3dzIueG4tLWx2 +ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdDApgid4bi0tbHZlLTZsYWQud3d3 +MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwKYIneG4tLWx2ZS02bGFkLnd3dzIubm90 +LXdlYi1wbGF0Zm9ybS50ZXN0MCmCJ3d3dzEueG4tLWx2ZS02bGFkLm5vdC13ZWIt +cGxhdGZvcm0udGVzdDArgil4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxh +dGZvcm0udGVzdDAtgit4bi0tbHZlLTZsYWQueG4tLWx2ZS02bGFkLndlYi1wbGF0 +Zm9ybS50ZXN0MC+CLXd3dy54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxh +dGZvcm0udGVzdDAvgi14bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cud2ViLXBs +YXRmb3JtLnRlc3QwL4IteG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1w +bGF0Zm9ybS50ZXN0MDCCLnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi +LXBsYXRmb3JtLnRlc3QwMIIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3MS53 +ZWItcGxhdGZvcm0udGVzdDAwgi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cy +LndlYi1wbGF0Zm9ybS50ZXN0MDCCLnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYy +OGEud2ViLXBsYXRmb3JtLnRlc3QwMYIveG4tLWx2ZS02bGFkLnhuLS1sdmUtNmxh +ZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwM4Ixd3d3LnhuLS1uOGo2ZHM1M2x3d2ty +cWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdDAzgjF4bi0tbjhqNmRzNTNsd3dr +cnFodjI4YS53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDSCMnd3dzEueG4tLW44 +ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDSCMnhuLS1u +OGo2ZHM1M2x3d2tycWh2MjhhLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDSC +Mnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50 +ZXN0MDSCMnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIubm90LXdlYi1wbGF0 +Zm9ybS50ZXN0MDiCNnhuLS1sdmUtNmxhZC54bi0tbjhqNmRzNTNsd3drcnFodjI4 +YS53ZWItcGxhdGZvcm0udGVzdDA4gjZ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS54 +bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3QwPII6eG4tLWx2ZS02bGFkLnhu +LS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdDA8gjp4 +bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0 +Zm9ybS50ZXN0MEOCQXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1uOGo2ZHM1 +M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0MEeCRXhuLS1uOGo2ZHM1M2x3 +d2tycWh2MjhhLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZv +cm0udGVzdDATBgNVHSUEDDAKBggrBgEFBQcDATCCCYUGA1UdEQSCCXwwggl4ghF3 +ZWItcGxhdGZvcm0udGVzdIIVd3d3LndlYi1wbGF0Zm9ybS50ZXN0ghVub3Qtd2Vi +LXBsYXRmb3JtLnRlc3SCFnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCFnd3dzIud2Vi +LXBsYXRmb3JtLnRlc3SCGXd3dy53d3cud2ViLXBsYXRmb3JtLnRlc3SCGXd3dy5u +b3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIud3d3LndlYi1wbGF0Zm9ybS50ZXN0 +ghp3d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIad3d3Mi5ub3Qtd2ViLXBsYXRm +b3JtLnRlc3SCGnd3dy53d3cxLndlYi1wbGF0Zm9ybS50ZXN0ghp3d3cud3d3Mi53 +ZWItcGxhdGZvcm0udGVzdIIad3d3MS53d3cud2ViLXBsYXRmb3JtLnRlc3SCG3d3 +dzIud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cxLndlYi1wbGF0Zm9y +bS50ZXN0ght3d3cyLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCG3d3dzEud3d3Mi53 +ZWItcGxhdGZvcm0udGVzdIIdd3d3Lnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC +Hnd3dy53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIed3d3Mi53d3cubm90LXdl +Yi1wbGF0Zm9ybS50ZXN0gh53d3cud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC +HnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIed3d3MS53d3cubm90LXdl +Yi1wbGF0Zm9ybS50ZXN0gh93d3cxLnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0 +gh93d3cyLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gh93d3cyLnd3dzIubm90 +LXdlYi1wbGF0Zm9ybS50ZXN0gh93d3cxLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50 +ZXN0giJ4bi0tbHZlLTZsYWQud3d3LndlYi1wbGF0Zm9ybS50ZXN0giJ3d3cueG4t +LWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0giJ4bi0tbHZlLTZsYWQubm90LXdl +Yi1wbGF0Zm9ybS50ZXN0giN3d3cxLnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0u +dGVzdIIjeG4tLWx2ZS02bGFkLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCI3d3dzIu +eG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0giN4bi0tbHZlLTZsYWQud3d3 +Mi53ZWItcGxhdGZvcm0udGVzdIImd3d3LnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBs +YXRmb3JtLnRlc3SCJnhuLS1sdmUtNmxhZC53d3cubm90LXdlYi1wbGF0Zm9ybS50 +ZXN0gid3d3cyLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3hu +LS1sdmUtNmxhZC53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIneG4tLWx2ZS02 +bGFkLnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0gid3d3cxLnhuLS1sdmUtNmxh +ZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCKXhuLS1uOGo2ZHM1M2x3d2tycWh2Mjhh +LndlYi1wbGF0Zm9ybS50ZXN0git4bi0tbHZlLTZsYWQueG4tLWx2ZS02bGFkLndl +Yi1wbGF0Zm9ybS50ZXN0gi13d3cueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi +LXBsYXRmb3JtLnRlc3SCLXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dy53ZWIt +cGxhdGZvcm0udGVzdIIteG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1w +bGF0Zm9ybS50ZXN0gi53d3cxLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1w +bGF0Zm9ybS50ZXN0gi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cxLndlYi1w +bGF0Zm9ybS50ZXN0gi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cyLndlYi1w +bGF0Zm9ybS50ZXN0gi53d3cyLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1w +bGF0Zm9ybS50ZXN0gi94bi0tbHZlLTZsYWQueG4tLWx2ZS02bGFkLm5vdC13ZWIt +cGxhdGZvcm0udGVzdIIxd3d3LnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13 +ZWItcGxhdGZvcm0udGVzdIIxeG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3Lm5v +dC13ZWItcGxhdGZvcm0udGVzdIIyd3d3MS54bi0tbjhqNmRzNTNsd3drcnFodjI4 +YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMnhuLS1uOGo2ZHM1M2x3d2tycWh2Mjhh +Lnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ3d3cyLnhuLS1uOGo2ZHM1M2x3 +d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdIIyeG4tLW44ajZkczUzbHd3 +a3JxaHYyOGEud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCNnhuLS1sdmUtNmxh +ZC54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdII2eG4t +LW44ajZkczUzbHd3a3JxaHYyOGEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50 +ZXN0gjp4bi0tbHZlLTZsYWQueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdl +Yi1wbGF0Zm9ybS50ZXN0gjp4bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbHZl +LTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0gkF4bi0tbjhqNmRzNTNsd3drcnFo +djI4YS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIJF +eG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEu +bm90LXdlYi1wbGF0Zm9ybS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQBifqUfZhtG +pcQJgQ86u/1+uO39IfQ7gpLcBVc6YBmZ9NBBkk7Du8+JJ1eDBw+U47usXPkc1oqu +Nv7k9Gg2Ln0I5mVVVcBUP84z0pxKCc6KKhJXcjSu9dMFBxT/pjDpPQ1WVzPJVmNw +ywuRlVHQxk5Pc3dXKUAZoti7GoX1yd1xMH8Rz2vL9f7QLW+uVvRbhSp6DcTq8BPJ +RLni1DQ9J02nHhD/JULUoxp/2HLDdPt/++145Eoy5GlycNcqw7VVraongsVAuG6h +7zZYthFwc6+81dxaGmsgOG7baljBN4k4Jdjkt6P+0QVodn/+5Sto+Gb1TzoYjYpY +J9G36zcLRJyc -----END CERTIFICATE----- diff --git a/tests/wpt/tests/tools/certs/web-platform.test.key b/tests/wpt/tests/tools/certs/web-platform.test.key index 0df3f579240..4f68bb3caa0 100644 --- a/tests/wpt/tests/tools/certs/web-platform.test.key +++ b/tests/wpt/tests/tools/certs/web-platform.test.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDOovdiO3UPxIH0 -s/PB2x3MBLJag+7XqjffxrGB5AOGBoRN+wlnEdUCK79CdFR+O4e30ArCJNzmcODj -rTaICx6JpL9oqEm8VxR7SLwQR6h/1mN4rK4KnqHVxxiUdDaINzkNzKB1fOSBh+Fc -9FspIc+1BbAhZYmoAXJ/wzfvCTHeEE+fpoQ8Nb7UdyBNJgsb9u1f8hahAiBrFy1i -HcG4p10YnUJVOfcIeiVWPjX3EHgbvgUdMuyMW57y83ZH6PQ+gLYAA8DrwT4etOtV -6YDR+b9Bsq6jWCPFdmcSIGPTTD8IvAepMsgt2Xfx8NUgd4IatpjPZmeU9H55Wxms -I097LMwtAgMBAAECggEBAKh+urqfQRVaZ53iHyI0SlfSfJzSeC/j3SvcGWKRS04+ -giQUT9Z78/WRNqQ5t6w3XrPEMQGejYJbCQaed5j3eC9E58+vanDpkQn2hWPBCuUz -LGl6ZXDDabOoZaKoIM9yOFPISA+Fh88XvezOVId1yqkRuk2BPn6Ar5z+0t1X4hHw -Q9ON3CMFBWrPjUntfvlChmMqXYlOnnd402EGUrm5E5mYQc5En4lEASNneo2uD6GX -Y72eDCPG/ShvRlunmg7nKn0ciHoH1L55He/V1QdcTqo/dTVX9mEFnvBmx+aV8XDw -VuRuLujHmXj9RKENOJs7n6W5n/Qd2/OTISzx6vI3PQECgYEA6nAKSK0B0MprZQUt -vOKETOExr8XMFDsbigt/o8kvXKixZoLYOkAzSObY9oDkCiy5RWdqhS/e1Ufivi9Y -IFqXmB8rpXeN04zx8z3pzo63ohS6CgWIg63YZ4+KScx00xGKNimb8Kug39onCN8b -M3Sbri0AGvUCtfHjd4MACGMqvUcCgYEA4aRVy7pF0yMV4wPuwjwzKkdVF9Dh2i9C -Gd0WDRKrccjtkSL7uy7QKYGYnGjLttOLnxx7GN3GhHWBoCE8kMsSOyMIhWzDv3a3 -LsbP2HI8fWmbmLaU25qMhdfKQiAlLgCJdvSuWzsjbcf3fZ+0LLsCagPF7V0ed9A1 -niy5sohclOsCgYEAi8ZVO1N7O6MUONzHklBzlOrHFweVT5KWLs4AQgTXaiVh776f -cMuKSDLqtL3QOIjFxa2NAu+xqfP8KmxL3K5mp9odyb/oHXNxZhdJ6U+KCObWrNbz -t57U4ZnhV3LBTH6uqvBP+0Q43H5Su6VZsGobz9MgtvHRte0MM9s1D8sgVk0CgYEA -t6eoZV/BwW5HPDVROisBgiH5Mp9DlPDuHlsCvbU6ciyWoJEWz2305DOlYXkyhiZ8 -+A6Yas7n65ww24Lx5vBCcHu9TcwPL2GTC7GqLoQck/9HM+84Dd4nDjFrYJMFcAHj -4TyaRYtG9O3TlR5N6jJ0bpGPofku+VowqgPBSX0Pze0CgYAbMqrQu/nCK5IC3Yyy -hkssanrfxV+GXTo351WqFWlHDaImbj4PaPsUR4IYJq62UyOWH8mQ81Rfpl/SKFbW -AQsCmBT8o5P81iVvLHHdYiyCqLgtLH3m7dgDYOze0BUlm4OUfT5tmewau75wVdiE -xxjzn20+iZ/rdfKXIE+30AZ3eg== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDg/mIE/8f6jTVz +bI2TZwmA+tIws6+TpSuhuot9JbArcIf1JSicQl2itKgDFqM1iktbHeLfYChZw3TS +QZUyhalfCG3aphUwH1bjGbRAuBHIOS3ncCl/aCvqbIrU3PRpCIVTMfz5OtDlT5CR +ynwg9qLlxacpiyj9nw2ASEoN3liLWbQOROhuPtvmRKwaFRm7OY669oFwaQqoeDrC +B9LPlEJiYjWjBZIghnsE1Y0DSV7lz+m7cKYG+PnZKNYfKg7/MV2g5PqWXqEziJBG +FoicL4Dbsk7X+wvG+T9NwKrQKE0t1sE+oIsRdLLXvp0k++um57IN1KuvK1xV/Mg9 +TeVx/zlpAgMBAAECggEASFMdmTPLygvYcckkXYzSrkZyiLtKJnEC7JM1wb36uowK ++E/AlTJ0PRhLpeqB/nT9MkYSJvIXJnvBMtFoL3xt7KGeBpo612RLnuclXWSOOsm+ +qtYQUOdgrpPDsRdx7c2SZiL8ifVRL1V7SJJJgqMlzCzURnN4csbNJT6Xp4ug9PH/ +sn8kWgZyEPW2MdkbY0APykbkWzXvkyJQ4l9qm3Z1sbWQLHkvyD3aP0fS4EGtOoY7 +shgufnXmkGRkSl3oSg/JT7+z/W0lExyN28O53Wm9kBlHxmSguHpmH8ihQTpuLy8K +16Xv9k5z+5qJMEg4oC8/VAHGnlV5gCAFayjfypoLnQKBgQDzVDJZPXNS9OUYCJJE +sOoAHfBul03uili9ThGtwg6rRBzClsd9ldmjqfBEdPF85o/fnRF8Hhp6IAGjP7wv +JCY0KKUkIl5KweWCfCtYkVzT6d7q0tMaIx/lL69F6XR0aK3GtMH5zfM6tOb+MVs5 +KxGdkQPEYIDNF2UtNbHeRFkNbwKBgQDstcK2WoCOy4kfifSCL4OKpdZrSXT/pTcA +3YUMjnNcX/XVNXgHU9z+FLf63oN3D0KvmLqPyz0NEX8ew77FxCxU5LcfPYLtDI0o +J3F7DZYQKk8MSe4HCbQDwMhDw+RHSE+JJICm0V8yrR9UpW0v7tqLrjk+HiSyx+yp +MkhgVGDqpwKBgQCSuHkngDsykUI2bKytyLNAYM0iEg/GvxrlAtb8G+A2evqQhtRB +MIMsAYND8/PM6UVlg1MQsSIr83KpWfwBvN1gZAW3tRWAJExckrycSgJcMU/d7kOm +JfnMeyVHlY5HxvrJryKrmviHtJ74NRCZdxPHG7LWzY28nNfAG/llWXcM9wKBgF+b +Eifg6efC4YFxkOY8Fp8bWD1BEBZpPowE7MYjiwiWYY5Z6D7danbdG2oiEWs3KLIP +t9p4NhJfLL7aROVP1K/9KNFfYNApr6G2PKl81U12KTNHcPI6wxB4/uoP5tW7qRQ1 +QBkgm5i2P99KaY1gpbihB9HFDwF+qmG0Q3NU4UglAoGBAI9fosEAe8SthkTZvUxQ +cqytj++mWX9Yz2ZKthORFwI6Q3FGYBUx1I67Lu7qiWe69frcw3pN2Yt65jc08w10 +TOEorKsvYnZx5vaPNiFicmW+bpgqfAkL/j7GdDrgddDL9NYVbVGDLHWPRqmtBEfa +fH90hyluwXFzzgKqYmg+GzKu -----END PRIVATE KEY----- diff --git a/tests/wpt/tests/tools/certs/web-platform.test.pem b/tests/wpt/tests/tools/certs/web-platform.test.pem index 1c5859d2066..02a2d94e935 100644 --- a/tests/wpt/tests/tools/certs/web-platform.test.pem +++ b/tests/wpt/tests/tools/certs/web-platform.test.pem @@ -1,133 +1,133 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 114201 (0x1be19) + Serial Number: 1155 (0x483) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=web-platform-tests Validity - Not Before: Sep 12 01:03:10 2024 GMT - Not After : Sep 12 01:03:10 2025 GMT + Not Before: Oct 12 01:04:46 2024 GMT + Not After : Oct 12 01:04:46 2025 GMT Subject: CN=web-platform.test Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: - 00:ce:a2:f7:62:3b:75:0f:c4:81:f4:b3:f3:c1:db: - 1d:cc:04:b2:5a:83:ee:d7:aa:37:df:c6:b1:81:e4: - 03:86:06:84:4d:fb:09:67:11:d5:02:2b:bf:42:74: - 54:7e:3b:87:b7:d0:0a:c2:24:dc:e6:70:e0:e3:ad: - 36:88:0b:1e:89:a4:bf:68:a8:49:bc:57:14:7b:48: - bc:10:47:a8:7f:d6:63:78:ac:ae:0a:9e:a1:d5:c7: - 18:94:74:36:88:37:39:0d:cc:a0:75:7c:e4:81:87: - e1:5c:f4:5b:29:21:cf:b5:05:b0:21:65:89:a8:01: - 72:7f:c3:37:ef:09:31:de:10:4f:9f:a6:84:3c:35: - be:d4:77:20:4d:26:0b:1b:f6:ed:5f:f2:16:a1:02: - 20:6b:17:2d:62:1d:c1:b8:a7:5d:18:9d:42:55:39: - f7:08:7a:25:56:3e:35:f7:10:78:1b:be:05:1d:32: - ec:8c:5b:9e:f2:f3:76:47:e8:f4:3e:80:b6:00:03: - c0:eb:c1:3e:1e:b4:eb:55:e9:80:d1:f9:bf:41:b2: - ae:a3:58:23:c5:76:67:12:20:63:d3:4c:3f:08:bc: - 07:a9:32:c8:2d:d9:77:f1:f0:d5:20:77:82:1a:b6: - 98:cf:66:67:94:f4:7e:79:5b:19:ac:23:4f:7b:2c: - cc:2d + 00:e0:fe:62:04:ff:c7:fa:8d:35:73:6c:8d:93:67: + 09:80:fa:d2:30:b3:af:93:a5:2b:a1:ba:8b:7d:25: + b0:2b:70:87:f5:25:28:9c:42:5d:a2:b4:a8:03:16: + a3:35:8a:4b:5b:1d:e2:df:60:28:59:c3:74:d2:41: + 95:32:85:a9:5f:08:6d:da:a6:15:30:1f:56:e3:19: + b4:40:b8:11:c8:39:2d:e7:70:29:7f:68:2b:ea:6c: + 8a:d4:dc:f4:69:08:85:53:31:fc:f9:3a:d0:e5:4f: + 90:91:ca:7c:20:f6:a2:e5:c5:a7:29:8b:28:fd:9f: + 0d:80:48:4a:0d:de:58:8b:59:b4:0e:44:e8:6e:3e: + db:e6:44:ac:1a:15:19:bb:39:8e:ba:f6:81:70:69: + 0a:a8:78:3a:c2:07:d2:cf:94:42:62:62:35:a3:05: + 92:20:86:7b:04:d5:8d:03:49:5e:e5:cf:e9:bb:70: + a6:06:f8:f9:d9:28:d6:1f:2a:0e:ff:31:5d:a0:e4: + fa:96:5e:a1:33:88:90:46:16:88:9c:2f:80:db:b2: + 4e:d7:fb:0b:c6:f9:3f:4d:c0:aa:d0:28:4d:2d:d6: + c1:3e:a0:8b:11:74:b2:d7:be:9d:24:fb:eb:a6:e7: + b2:0d:d4:ab:af:2b:5c:55:fc:c8:3d:4d:e5:71:ff: + 39:69 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: - 43:82:25:04:5A:01:43:01:03:CE:51:1D:0C:4F:F6:48:3A:91:55:1A + 6D:E6:53:45:A0:4B:96:3B:B6:C1:D8:5B:E8:C4:E2:2A:9D:9B:A2:BA X509v3 Authority Key Identifier: - keyid:FE:64:41:FD:EB:25:D2:54:6A:A6:E1:36:F6:12:2A:56:F9:82:F6:B5 + keyid:C9:65:67:DF:F8:60:C5:FB:E0:F7:15:D1:ED:5B:6D:73:E2:73:D4:E7 X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Subject Alternative Name: - DNS:web-platform.test, DNS:not-web-platform.test, DNS:www.web-platform.test, DNS:www2.web-platform.test, DNS:www1.web-platform.test, DNS:www.www.web-platform.test, DNS:www.not-web-platform.test, DNS:www.www1.web-platform.test, DNS:www2.www.web-platform.test, DNS:www1.not-web-platform.test, DNS:www1.www.web-platform.test, DNS:www2.not-web-platform.test, DNS:www.www2.web-platform.test, DNS:www1.www2.web-platform.test, DNS:www2.www1.web-platform.test, DNS:www2.www2.web-platform.test, DNS:www1.www1.web-platform.test, DNS:www.www.not-web-platform.test, DNS:www.www1.not-web-platform.test, DNS:www.www2.not-web-platform.test, DNS:xn--lve-6lad.web-platform.test, DNS:www2.www.not-web-platform.test, DNS:www1.www.not-web-platform.test, DNS:www2.www2.not-web-platform.test, DNS:www1.www2.not-web-platform.test, DNS:www1.www1.not-web-platform.test, DNS:www2.www1.not-web-platform.test, DNS:xn--lve-6lad.not-web-platform.test, DNS:www.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www.web-platform.test, DNS:www1.xn--lve-6lad.web-platform.test, DNS:www2.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www1.web-platform.test, DNS:xn--lve-6lad.www2.web-platform.test, DNS:www.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www.not-web-platform.test, DNS:www2.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www1.not-web-platform.test, DNS:www1.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www2.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.not-web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.not-web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test + DNS:web-platform.test, DNS:www.web-platform.test, DNS:not-web-platform.test, DNS:www1.web-platform.test, DNS:www2.web-platform.test, DNS:www.www.web-platform.test, DNS:www.not-web-platform.test, DNS:www2.www.web-platform.test, DNS:www1.not-web-platform.test, DNS:www2.not-web-platform.test, DNS:www.www1.web-platform.test, DNS:www.www2.web-platform.test, DNS:www1.www.web-platform.test, DNS:www2.www2.web-platform.test, DNS:www1.www1.web-platform.test, DNS:www2.www1.web-platform.test, DNS:www1.www2.web-platform.test, DNS:www.www.not-web-platform.test, DNS:www.www2.not-web-platform.test, DNS:www2.www.not-web-platform.test, DNS:www.www1.not-web-platform.test, DNS:xn--lve-6lad.web-platform.test, DNS:www1.www.not-web-platform.test, DNS:www1.www2.not-web-platform.test, DNS:www2.www1.not-web-platform.test, DNS:www2.www2.not-web-platform.test, DNS:www1.www1.not-web-platform.test, DNS:xn--lve-6lad.www.web-platform.test, DNS:www.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.not-web-platform.test, DNS:www1.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www1.web-platform.test, DNS:www2.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www2.web-platform.test, DNS:www.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www.not-web-platform.test, DNS:www2.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www1.not-web-platform.test, DNS:xn--lve-6lad.www2.not-web-platform.test, DNS:www1.xn--lve-6lad.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.not-web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.not-web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.not-web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.not-web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test Signature Algorithm: sha256WithRSAEncryption - 84:56:ff:85:c0:76:43:19:5a:7c:3d:e7:bf:19:f3:32:2d:18: - 1b:fd:4c:2d:ff:be:73:d7:b0:ae:d9:1f:c4:a6:ae:c3:73:38: - e7:ae:17:3a:e9:5e:d0:4a:f0:9b:d1:ca:6f:d9:8b:83:91:9e: - 17:00:42:f2:52:8e:58:04:dd:49:71:c1:ed:d2:e9:98:c8:dc: - 67:92:bb:60:15:df:37:5b:24:ef:ea:20:05:4d:fe:00:88:c3: - d7:6c:d3:95:6e:28:c6:7e:dd:f4:fe:dd:bc:06:36:b2:b2:59: - 2b:62:e1:a3:b8:4e:fc:4d:a9:e7:a7:38:c6:ec:d8:72:17:57: - c5:f0:b8:c4:f0:e8:87:5e:67:e5:0f:43:a9:cb:1c:7a:f1:d6: - 30:89:11:3f:ca:90:4a:3c:81:15:90:13:47:32:68:68:75:27: - 7f:39:e4:cb:d6:c3:5f:c1:a1:90:ff:9e:4c:6d:6a:e2:44:2e: - 09:d8:85:44:69:f8:55:ab:84:98:83:c6:e7:ed:e0:45:5d:f1: - 39:4a:d1:92:c8:56:5d:9d:42:9d:b6:02:78:d9:48:a9:7e:ad: - 45:37:bd:73:e6:ad:fa:c8:15:b3:90:bd:17:ec:9b:ae:63:e9: - 98:8a:36:da:99:7a:77:0c:8c:a9:98:70:af:97:69:e5:90:c1: - 4d:99:b2:a5 + 41:30:c3:35:8a:8c:3c:5d:5d:a3:d7:10:28:81:59:c7:cd:b0: + a8:73:8f:1a:d1:36:be:40:86:3c:63:cb:1c:a9:41:26:a0:0c: + 6a:cf:b7:cf:76:3f:64:fa:ea:e5:74:9b:57:1d:b2:dd:92:ce: + ed:c1:32:ec:65:eb:7d:c2:73:ab:8d:95:33:b3:a3:d2:b0:6d: + 81:0d:3f:31:c3:89:23:49:39:da:6f:22:b5:1d:12:97:6e:cc: + 20:43:5a:ca:f4:d5:3e:01:be:90:03:b2:4e:f7:9c:e2:97:21: + 39:a3:33:8c:45:a4:6c:e9:3a:eb:87:2d:1d:39:e6:d8:bb:b2: + 15:01:a4:8f:70:25:61:4f:0f:5f:35:8d:9c:c6:fb:81:3b:52: + 15:94:90:e4:ee:d7:3b:b2:b7:68:45:46:bb:56:06:7f:83:73: + d9:a8:1c:0d:17:fb:ce:81:5d:1c:0a:4f:0c:75:68:a2:70:64: + 6d:de:ad:cf:ac:10:e5:e5:04:1f:e8:12:8d:59:27:e2:9a:76: + dd:30:89:bc:2e:22:ac:97:12:86:a0:45:9e:2f:e2:3f:c3:0a: + fe:14:6c:2a:28:a6:a3:00:81:d0:53:e2:4d:66:9c:13:9e:e5: + 25:02:27:b3:05:62:73:08:49:43:6e:15:74:0d:ed:dc:71:47: + 6c:79:53:1d -----BEGIN CERTIFICATE----- -MIIMsjCCC5qgAwIBAgIDAb4ZMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEndl -Yi1wbGF0Zm9ybS10ZXN0czAeFw0yNDA5MTIwMTAzMTBaFw0yNTA5MTIwMTAzMTBa -MBwxGjAYBgNVBAMMEXdlYi1wbGF0Zm9ybS50ZXN0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAzqL3Yjt1D8SB9LPzwdsdzASyWoPu16o338axgeQDhgaE -TfsJZxHVAiu/QnRUfjuHt9AKwiTc5nDg4602iAseiaS/aKhJvFcUe0i8EEeof9Zj -eKyuCp6h1ccYlHQ2iDc5DcygdXzkgYfhXPRbKSHPtQWwIWWJqAFyf8M37wkx3hBP -n6aEPDW+1HcgTSYLG/btX/IWoQIgaxctYh3BuKddGJ1CVTn3CHolVj419xB4G74F -HTLsjFue8vN2R+j0PoC2AAPA68E+HrTrVemA0fm/QbKuo1gjxXZnEiBj00w/CLwH -qTLILdl38fDVIHeCGraYz2ZnlPR+eVsZrCNPeyzMLQIDAQABo4IJ+jCCCfYwCQYD -VR0TBAIwADAdBgNVHQ4EFgQUQ4IlBFoBQwEDzlEdDE/2SDqRVRowHwYDVR0jBBgw -FoAU/mRB/esl0lRqpuE29hIqVvmC9rUwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoG -CCsGAQUFBwMBMIIJhQYDVR0RBIIJfDCCCXiCEXdlYi1wbGF0Zm9ybS50ZXN0ghVu -b3Qtd2ViLXBsYXRmb3JtLnRlc3SCFXd3dy53ZWItcGxhdGZvcm0udGVzdIIWd3d3 -Mi53ZWItcGxhdGZvcm0udGVzdIIWd3d3MS53ZWItcGxhdGZvcm0udGVzdIIZd3d3 -Lnd3dy53ZWItcGxhdGZvcm0udGVzdIIZd3d3Lm5vdC13ZWItcGxhdGZvcm0udGVz -dIIad3d3Lnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIud3d3LndlYi1wbGF0 -Zm9ybS50ZXN0ghp3d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIad3d3MS53d3cu -d2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3 -d3cud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cyLndlYi1wbGF0Zm9y -bS50ZXN0ght3d3cyLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCG3d3dzIud3d3Mi53 -ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cxLndlYi1wbGF0Zm9ybS50ZXN0gh13 -d3cud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIed3d3Lnd3dzEubm90LXdlYi1w -bGF0Zm9ybS50ZXN0gh53d3cud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCHnhu -LS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIed3d3Mi53d3cubm90LXdlYi1w -bGF0Zm9ybS50ZXN0gh53d3cxLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3 -dzIud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzEud3d3Mi5ub3Qtd2Vi -LXBsYXRmb3JtLnRlc3SCH3d3dzEud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC -H3d3dzIud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCInhuLS1sdmUtNmxhZC5u -b3Qtd2ViLXBsYXRmb3JtLnRlc3SCInd3dy54bi0tbHZlLTZsYWQud2ViLXBsYXRm -b3JtLnRlc3SCInhuLS1sdmUtNmxhZC53d3cud2ViLXBsYXRmb3JtLnRlc3SCI3d3 -dzEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0giN3d3cyLnhuLS1sdmUt -NmxhZC53ZWItcGxhdGZvcm0udGVzdIIjeG4tLWx2ZS02bGFkLnd3dzEud2ViLXBs -YXRmb3JtLnRlc3SCI3huLS1sdmUtNmxhZC53d3cyLndlYi1wbGF0Zm9ybS50ZXN0 -giZ3d3cueG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIImeG4tLWx2 -ZS02bGFkLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3d3dzIueG4tLWx2ZS02 -bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIIneG4tLWx2ZS02bGFkLnd3dzEubm90 -LXdlYi1wbGF0Zm9ybS50ZXN0gid3d3cxLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBs -YXRmb3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53d3cyLm5vdC13ZWItcGxhdGZvcm0u -dGVzdIIpeG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SC -K3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCLXd3 -dy54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIteG4t -LW44ajZkczUzbHd3a3JxaHYyOGEud3d3LndlYi1wbGF0Zm9ybS50ZXN0gi14bi0t -bjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCLnhuLS1u -OGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIud2ViLXBsYXRmb3JtLnRlc3SCLnhuLS1u -OGo2ZHM1M2x3d2tycWh2MjhhLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCLnd3dzEu -eG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCLnd3dzIu -eG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCL3huLS1s -dmUtNmxhZC54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjF4bi0t -bjhqNmRzNTNsd3drcnFodjI4YS53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjF3 -d3cueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0 -gjJ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cxLm5vdC13ZWItcGxhdGZvcm0u -dGVzdIIyeG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3Mi5ub3Qtd2ViLXBsYXRm -b3JtLnRlc3SCMnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1w -bGF0Zm9ybS50ZXN0gjJ3d3cyLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13 -ZWItcGxhdGZvcm0udGVzdII2eG4tLWx2ZS02bGFkLnhuLS1uOGo2ZHM1M2x3d2ty -cWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0gjZ4bi0tbjhqNmRzNTNsd3drcnFodjI4 -YS54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCOnhuLS1sdmUtNmxhZC54 -bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCOnhu -LS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRm -b3JtLnRlc3SCQXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1uOGo2ZHM1M2x3 -d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0gkV4bi0tbjhqNmRzNTNsd3drcnFo -djI4YS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRl -c3QwDQYJKoZIhvcNAQELBQADggEBAIRW/4XAdkMZWnw9578Z8zItGBv9TC3/vnPX -sK7ZH8SmrsNzOOeuFzrpXtBK8JvRym/Zi4ORnhcAQvJSjlgE3Ulxwe3S6ZjI3GeS -u2AV3zdbJO/qIAVN/gCIw9ds05VuKMZ+3fT+3bwGNrKyWSti4aO4TvxNqeenOMbs -2HIXV8XwuMTw6IdeZ+UPQ6nLHHrx1jCJET/KkEo8gRWQE0cyaGh1J3855MvWw1/B -oZD/nkxtauJELgnYhURp+FWrhJiDxuft4EVd8TlK0ZLIVl2dQp22AnjZSKl+rUU3 -vXPmrfrIFbOQvRfsm65j6ZiKNtqZencMjKmYcK+XaeWQwU2ZsqU= +MIIMsTCCC5mgAwIBAgICBIMwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAwwSd2Vi +LXBsYXRmb3JtLXRlc3RzMB4XDTI0MTAxMjAxMDQ0NloXDTI1MTAxMjAxMDQ0Nlow +HDEaMBgGA1UEAwwRd2ViLXBsYXRmb3JtLnRlc3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDg/mIE/8f6jTVzbI2TZwmA+tIws6+TpSuhuot9JbArcIf1 +JSicQl2itKgDFqM1iktbHeLfYChZw3TSQZUyhalfCG3aphUwH1bjGbRAuBHIOS3n +cCl/aCvqbIrU3PRpCIVTMfz5OtDlT5CRynwg9qLlxacpiyj9nw2ASEoN3liLWbQO +ROhuPtvmRKwaFRm7OY669oFwaQqoeDrCB9LPlEJiYjWjBZIghnsE1Y0DSV7lz+m7 +cKYG+PnZKNYfKg7/MV2g5PqWXqEziJBGFoicL4Dbsk7X+wvG+T9NwKrQKE0t1sE+ +oIsRdLLXvp0k++um57IN1KuvK1xV/Mg9TeVx/zlpAgMBAAGjggn6MIIJ9jAJBgNV +HRMEAjAAMB0GA1UdDgQWBBRt5lNFoEuWO7bB2FvoxOIqnZuiujAfBgNVHSMEGDAW +gBTJZWff+GDF++D3FdHtW21z4nPU5zALBgNVHQ8EBAMCBeAwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwggmFBgNVHREEggl8MIIJeIIRd2ViLXBsYXRmb3JtLnRlc3SCFXd3 +dy53ZWItcGxhdGZvcm0udGVzdIIVbm90LXdlYi1wbGF0Zm9ybS50ZXN0ghZ3d3cx +LndlYi1wbGF0Zm9ybS50ZXN0ghZ3d3cyLndlYi1wbGF0Zm9ybS50ZXN0ghl3d3cu +d3d3LndlYi1wbGF0Zm9ybS50ZXN0ghl3d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0 +ghp3d3cyLnd3dy53ZWItcGxhdGZvcm0udGVzdIIad3d3MS5ub3Qtd2ViLXBsYXRm +b3JtLnRlc3SCGnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cud3d3MS53 +ZWItcGxhdGZvcm0udGVzdIIad3d3Lnd3dzIud2ViLXBsYXRmb3JtLnRlc3SCGnd3 +dzEud3d3LndlYi1wbGF0Zm9ybS50ZXN0ght3d3cyLnd3dzIud2ViLXBsYXRmb3Jt +LnRlc3SCG3d3dzEud3d3MS53ZWItcGxhdGZvcm0udGVzdIIbd3d3Mi53d3cxLndl +Yi1wbGF0Zm9ybS50ZXN0ght3d3cxLnd3dzIud2ViLXBsYXRmb3JtLnRlc3SCHXd3 +dy53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cud3d3Mi5ub3Qtd2ViLXBs +YXRmb3JtLnRlc3SCHnd3dzIud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIed3d3 +Lnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gh54bi0tbHZlLTZsYWQud2ViLXBs +YXRmb3JtLnRlc3SCHnd3dzEud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIfd3d3 +MS53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIfd3d3Mi53d3cxLm5vdC13ZWIt +cGxhdGZvcm0udGVzdIIfd3d3Mi53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIf +d3d3MS53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIieG4tLWx2ZS02bGFkLnd3 +dy53ZWItcGxhdGZvcm0udGVzdIIid3d3LnhuLS1sdmUtNmxhZC53ZWItcGxhdGZv +cm0udGVzdIIieG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIIjd3d3 +MS54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCI3huLS1sdmUtNmxhZC53 +d3cxLndlYi1wbGF0Zm9ybS50ZXN0giN3d3cyLnhuLS1sdmUtNmxhZC53ZWItcGxh +dGZvcm0udGVzdIIjeG4tLWx2ZS02bGFkLnd3dzIud2ViLXBsYXRmb3JtLnRlc3SC +Jnd3dy54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0giZ4bi0tbHZl +LTZsYWQud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIInd3d3Mi54bi0tbHZlLTZs +YWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0gid4bi0tbHZlLTZsYWQud3d3MS5ub3Qt +d2ViLXBsYXRmb3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53d3cyLm5vdC13ZWItcGxh +dGZvcm0udGVzdIInd3d3MS54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50 +ZXN0gil4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIr +eG4tLWx2ZS02bGFkLnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIItd3d3 +LnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0gi14bi0t +bjhqNmRzNTNsd3drcnFodjI4YS53d3cud2ViLXBsYXRmb3JtLnRlc3SCLXhuLS1u +OGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdIIud3d3MS54 +bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIueG4tLW44 +ajZkczUzbHd3a3JxaHYyOGEud3d3MS53ZWItcGxhdGZvcm0udGVzdIIueG4tLW44 +ajZkczUzbHd3a3JxaHYyOGEud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIud3d3Mi54 +bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIveG4tLWx2 +ZS02bGFkLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMXd3dy54 +bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMXhu +LS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC +Mnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50 +ZXN0gjJ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cxLm5vdC13ZWItcGxhdGZv +cm0udGVzdIIyd3d3Mi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBs +YXRmb3JtLnRlc3SCMnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIubm90LXdl +Yi1wbGF0Zm9ybS50ZXN0gjZ4bi0tbHZlLTZsYWQueG4tLW44ajZkczUzbHd3a3Jx +aHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCNnhuLS1uOGo2ZHM1M2x3d2tycWh2Mjhh +LnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdII6eG4tLWx2ZS02bGFkLnhu +LS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdII6eG4t +LW44ajZkczUzbHd3a3JxaHYyOGEueG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZv +cm0udGVzdIJBeG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4tLW44ajZkczUzbHd3 +a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCRXhuLS1uOGo2ZHM1M2x3d2tycWh2 +MjhhLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVz +dDANBgkqhkiG9w0BAQsFAAOCAQEAQTDDNYqMPF1do9cQKIFZx82wqHOPGtE2vkCG +PGPLHKlBJqAMas+3z3Y/ZPrq5XSbVx2y3ZLO7cEy7GXrfcJzq42VM7Oj0rBtgQ0/ +McOJI0k52m8itR0Sl27MIENayvTVPgG+kAOyTvec4pchOaMzjEWkbOk664ctHTnm +2LuyFQGkj3AlYU8PXzWNnMb7gTtSFZSQ5O7XO7K3aEVGu1YGf4Nz2agcDRf7zoFd +HApPDHVoonBkbd6tz6wQ5eUEH+gSjVkn4pp23TCJvC4irJcShqBFni/iP8MK/hRs +KiimowCB0FPiTWacE57lJQInswVicwhJQ24VdA3t3HFHbHlTHQ== -----END CERTIFICATE----- diff --git a/tests/wpt/tests/tools/ci/jobs.py b/tests/wpt/tests/tools/ci/jobs.py index fe8eaae069e..a831d24bebe 100644 --- a/tests/wpt/tests/tools/ci/jobs.py +++ b/tests/wpt/tests/tools/ci/jobs.py @@ -1,8 +1,10 @@ # mypy: allow-untyped-defs import argparse +import json import os import re +import sys from ..wpt.testfiles import branch_point, files_changed from tools import localpaths # noqa: F401 @@ -138,6 +140,7 @@ def create_parser(): parser.add_argument("revish", default=None, help="Commits to consider. Defaults to the commits on the current branch", nargs="?") parser.add_argument("--all", help="List all jobs unconditionally.", action="store_true") parser.add_argument("--includes", default=None, help="Jobs to check for. Return code is 0 if all jobs are found, otherwise 1", nargs="*") + parser.add_argument("--json", action="store_true", help="Output jobs as JSON, instead of one per line") return parser @@ -145,7 +148,11 @@ def run(**kwargs): paths = get_paths(**kwargs) jobs = get_jobs(paths, **kwargs) if not kwargs["includes"]: - for item in sorted(jobs): - print(item) + if kwargs["json"]: + json.dump(sorted(jobs), sys.stdout, indent=2) + sys.stdout.write("\n") + else: + for item in sorted(jobs): + print(item) else: return 0 if set(kwargs["includes"]).issubset(jobs) else 1 diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/chrome_spki_certs.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/chrome_spki_certs.py index 08ff16145cc..875ae3ea4a7 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/chrome_spki_certs.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/chrome_spki_certs.py @@ -2,7 +2,7 @@ # DO NOT EDIT MANUALLY. # tools/certs/web-platform.test.pem -WPT_FINGERPRINT = 'VoVeIyoD19UQniB0BHgC6THv+UvAkHror0gVsRketZQ=' +WPT_FINGERPRINT = '9cAz+9IkfB5eNjE005taHs+0OZkHahOazSQq3xQqQHo=' # signed-exchange/resources/127.0.0.1.sxg.pem SXG_WPT_FINGERPRINT = '0Rt4mT6SJXojEMHTnKnlJ/hBKMBcI4kteBlhR1eTTdk=' diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py index 53c11f133e5..914c5d1c0e3 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py @@ -80,66 +80,28 @@ class ChromeDriverTestharnessProtocolPart(WebDriverTestharnessProtocolPart): The main difference from the default WebDriver testharness implementation is that the test window can be reused between tests for better performance. """ - - def setup(self): - super().setup() - # Handle (an alphanumeric string) that may be set if window reuse is - # enabled. This state allows the protocol to distinguish the test - # window from other windows a test itself may create that the "Get - # Window Handles" command also returns. - # - # Because test window persistence is a Chrome-only feature, it's not - # exposed to the base WebDriver testharness executor. - self.test_window = None - self.reuse_window = self.parent.reuse_window - - def close_test_window(self): - if self.test_window: - self._close_window(self.test_window) - self.test_window = None - - def close_old_windows(self): - self.webdriver.actions.release() - for handle in self.webdriver.handles: - if handle not in {self.runner_handle, self.test_window}: - self._close_window(handle) - if not self.reuse_window: - self.close_test_window() - self.webdriver.window_handle = self.runner_handle - # TODO(web-platform-tests/wpt#48078): Find a cross-platform way to clear + def reset_browser_state(self): + # TODO(web-platform-tests/wpt#48078): Find a cross-vendor way to clear # cookies for all domains. self.parent.cdp.execute_cdp_command("Network.clearBrowserCookies") - return self.runner_handle - - def open_test_window(self, window_id): - if self.test_window: - # Try to reuse the existing test window by emulating the `about:blank` - # page with no history you would get with a new window. - try: - self.webdriver.window_handle = self.test_window - # Reset navigation history with Chrome DevTools Protocol: - # https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-resetNavigationHistory - self.parent.cdp.execute_cdp_command("Page.resetNavigationHistory") - self.webdriver.url = "about:blank" - return - except error.NoSuchWindowException: - self.test_window = None - super().open_test_window(window_id) - - def get_test_window(self, window_id, parent, timeout=5): - if self.test_window: - return self.test_window - # Poll the handles endpoint for the test window like the base WebDriver - # protocol part, but don't bother checking for the serialized - # WindowProxy (not supported by Chrome currently). - deadline = time.time() + timeout - while time.time() < deadline: - self.test_window = self._poll_handles_for_test_window(parent) - if self.test_window is not None: - assert self.test_window != parent - return self.test_window - time.sleep(0.03) - raise Exception("unable to find test window") + # Reset default permissions that `test_driver.set_permission(...)` may + # have altered. + self.parent.cdp.execute_cdp_command("Browser.resetPermissions") + # Chromium requires the `background-sync` permission for reporting APIs + # to work. Not all embedders (notably, `chrome --headless=old`) grant + # `background-sync` by default, so this CDP call ensures the permission + # is granted for all origins, in line with the background sync spec's + # recommendation [0]. + # + # WebDriver's "Set Permission" command can only act on the test's + # origin, which may be too limited. + # + # [0]: https://wicg.github.io/background-sync/spec/#permission + params = { + "permission": {"name": "background-sync"}, + "setting": "granted", + } + self.parent.cdp.execute_cdp_command("Browser.setPermission", params) class ChromeDriverFedCMProtocolPart(WebDriverFedCMProtocolPart): @@ -177,7 +139,6 @@ class ChromeDriverProtocol(WebDriverProtocol): if base_part.name not in {part.name for part in implements}: implements.append(base_part) - reuse_window = False # Prefix to apply to vendor-specific WebDriver extension commands. vendor_prefix = "goog" @@ -225,25 +186,24 @@ class ChromeDriverTestharnessExecutor(WebDriverTestharnessExecutor, _SanitizerMi def __init__(self, *args, reuse_window=False, **kwargs): super().__init__(*args, **kwargs) - self.protocol.reuse_window = reuse_window + self.reuse_window = reuse_window - def setup(self, runner, protocol=None): - super().setup(runner, protocol) - # Chromium requires the `background-sync` permission for reporting APIs - # to work. Not all embedders (notably, `chrome --headless=old`) grant - # `background-sync` by default, so this CDP call ensures the permission - # is granted for all origins, in line with the background sync spec's - # recommendation [0]. - # - # WebDriver's "Set Permission" command can only act on the test's - # origin, which may be too limited. - # - # [0]: https://wicg.github.io/background-sync/spec/#permission - params = { - "permission": {"name": "background-sync"}, - "setting": "granted", - } - self.protocol.cdp.execute_cdp_command("Browser.setPermission", params) + def get_or_create_test_window(self, protocol): + test_window = self.protocol.testharness.persistent_test_window + if test_window: + try: + # Mimic the "new window" WebDriver command by loading `about:blank` + # with no other browsing history. + protocol.base.set_window(test_window) + protocol.base.load("about:blank") + protocol.cdp.execute_cdp_command("Page.resetNavigationHistory") + except error.NoSuchWindowException: + 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.protocol.testharness.persistent_test_window = test_window + return test_window def _get_next_message_classic(self, protocol, url, test_window): try: diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py index 75a3313c55c..95b40bd8db1 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py @@ -30,10 +30,6 @@ class EdgeDriverRefTestExecutor(WebDriverRefTestExecutor, _SanitizerMixin): # t class EdgeDriverTestharnessExecutor(WebDriverTestharnessExecutor, _SanitizerMixin): # type: ignore protocol_cls = EdgeDriverProtocol - def __init__(self, *args, reuse_window=False, **kwargs): - super().__init__(*args, **kwargs) - self.protocol.reuse_window = reuse_window - class EdgeDriverPrintRefTestExecutor(EdgeDriverRefTestExecutor): protocol_cls = EdgeDriverProtocol diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py index 3c1bdfd7a72..f04d615ee11 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py @@ -5,9 +5,7 @@ import json import os import socket import threading -import time import traceback -import uuid from urllib.parse import urljoin from .base import (AsyncCallbackHandler, @@ -82,6 +80,9 @@ class WebDriverBaseProtocolPart(BaseProtocolPart): body = {"type": "script", "ms": timeout * 1000} self.webdriver.send_session_command("POST", "timeouts", body) + def create_window(self, type="tab", **kwargs): + return self.webdriver.new_window(type_hint=type) + @property def current_window(self): return self.webdriver.window_handle @@ -226,10 +227,9 @@ class WebDriverTestharnessProtocolPart(TestharnessProtocolPart): def setup(self): self.webdriver = self.parent.webdriver self.runner_handle = None + self.persistent_test_window = None with open(os.path.join(here, "runner.js")) as f: self.runner_script = f.read() - with open(os.path.join(here, "window-loaded.js")) as f: - self.window_loaded_script = f.read() def load_runner(self, url_protocol): if self.runner_handle: @@ -245,10 +245,11 @@ class WebDriverTestharnessProtocolPart(TestharnessProtocolPart): def close_old_windows(self): self.webdriver.actions.release() - handles = [item for item in self.webdriver.handles if item != self.runner_handle] - for handle in handles: - self._close_window(handle) + for handle in self.webdriver.handles: + if handle not in {self.runner_handle, self.persistent_test_window}: + self._close_window(handle) self.webdriver.window_handle = self.runner_handle + self.reset_browser_state() return self.runner_handle def _close_window(self, window_handle): @@ -258,65 +259,8 @@ class WebDriverTestharnessProtocolPart(TestharnessProtocolPart): except webdriver_error.NoSuchWindowException: pass - def open_test_window(self, window_id): - self.webdriver.execute_script( - "window.open('about:blank', '%s', 'noopener')" % window_id) - - def get_test_window(self, window_id, parent, timeout=5): - """Find the test window amongst all the open windows. - This is assumed to be either the named window or the one after the parent in the list of - window handles - - :param window_id: The DOM name of the Window - :param parent: The handle of the runner window - :param timeout: The time in seconds to wait for the window to appear. This is because in - some implementations there's a race between calling window.open and the - window being added to the list of WebDriver accessible windows.""" - test_window = None - end_time = time.time() + timeout - while time.time() < end_time: - try: - # Try using the JSON serialization of the WindowProxy object, - # it's in Level 1 but nothing supports it yet - win_s = self.webdriver.execute_script("return window['%s'];" % window_id) - win_obj = json.loads(win_s) - test_window = win_obj["window-fcc6-11e5-b4f8-330a88ab9d7f"] - except Exception: - pass - - if test_window is None: - test_window = self._poll_handles_for_test_window(parent) - - if test_window is not None: - assert test_window != parent - return test_window - - time.sleep(0.1) - - raise Exception("unable to find test window") - - def _poll_handles_for_test_window(self, parent): - test_window = None - after = self.webdriver.handles - if len(after) == 2: - test_window = next(iter(set(after) - {parent})) - elif after[0] == parent and len(after) > 2: - # Hope the first one here is the test window - test_window = after[1] - return test_window - - def test_window_loaded(self): - """Wait until the page in the new window has been loaded. - - Hereby ignore Javascript execptions that are thrown when - the document has been unloaded due to a process change. - """ - while True: - try: - self.webdriver.execute_script(self.window_loaded_script, asynchronous=True) - break - except webdriver_error.JavascriptErrorException: - pass + def reset_browser_state(self): + """Reset browser-wide state that normally persists between tests.""" class WebDriverPrintProtocolPart(PrintProtocolPart): @@ -828,7 +772,6 @@ class WebDriverTestharnessExecutor(TestharnessExecutor): self._get_next_message = self._get_next_message_classic self.close_after_done = close_after_done - self.window_id = str(uuid.uuid4()) self.cleanup_after_test = cleanup_after_test def is_alive(self): @@ -857,7 +800,7 @@ class WebDriverTestharnessExecutor(TestharnessExecutor): def do_testharness(self, protocol, url, timeout): # The previous test may not have closed its old windows (if something # went wrong or if cleanup_after_test was False), so clean up here. - parent_window = protocol.testharness.close_old_windows() + protocol.testharness.close_old_windows() # If protocol implements `bidi_events`, remove all the existing subscriptions. if hasattr(protocol, 'bidi_events'): @@ -865,12 +808,8 @@ class WebDriverTestharnessExecutor(TestharnessExecutor): protocol.loop.run_until_complete(protocol.bidi_events.unsubscribe_all()) # Now start the test harness - protocol.testharness.open_test_window(self.window_id) - test_window = protocol.testharness.get_test_window(self.window_id, - parent_window, - timeout=5*self.timeout_multiplier) + test_window = self.get_or_create_test_window(protocol) self.protocol.base.set_window(test_window) - # Wait until about:blank has been loaded protocol.base.execute_script(self.window_loaded_script, asynchronous=True) @@ -975,6 +914,9 @@ class WebDriverTestharnessExecutor(TestharnessExecutor): return rv, extra + def get_or_create_test_window(self, protocol): + return protocol.base.create_window() + def _get_next_message_classic(self, protocol, url, _): """ Get the next message from the test_driver using the classic WebDriver async script execution. This will block diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/protocol.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/protocol.py index 75edc146767..5b59482d9bd 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/protocol.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/protocol.py @@ -215,6 +215,7 @@ class TestharnessProtocolPart(ProtocolPart): contains the initial runner page. :param str url_protocol: "https" or "http" depending on the test metadata. + :returns: A browser-specific handle to the runner page. """ pass diff --git a/tests/wpt/tests/trusted-types/block-string-assignment-to-Element-insertAdjacentHTML.html b/tests/wpt/tests/trusted-types/block-string-assignment-to-Element-insertAdjacentHTML.html index e4fec3a8a70..af1f982e5a1 100644 --- a/tests/wpt/tests/trusted-types/block-string-assignment-to-Element-insertAdjacentHTML.html +++ b/tests/wpt/tests/trusted-types/block-string-assignment-to-Element-insertAdjacentHTML.html @@ -126,9 +126,17 @@ assert_equals(d.nextSibling, null); }, "`insertAdjacentHTML(null)` throws."); + // Due to a Gecko-specific bug + // (https://bugzilla.mozilla.org/show_bug.cgi?id=1270944), adjacent nodes are + // merged. Remove the children, to let the test pass on Gecko + // too. + function removeChildrenBecauseOfGeckoBug(element) { + element.innerHTML = null; + } + // After default policy creation string assignment implicitly calls createHTML. test(t => { - let p = window.trustedTypes.createPolicy("default", { createHTML: createHTMLJS }, true); + let p = window.trustedTypes.createPolicy("default", { createHTML: createHTMLJS }); var d = document.createElement('div'); container.appendChild(d); @@ -141,6 +149,8 @@ assert_equals(d.firstChild.nodeType, Node.TEXT_NODE); assert_equals(d.firstChild.data, RESULTS.HTML); + removeChildrenBecauseOfGeckoBug(d); + d.insertAdjacentHTML('beforeend', INPUTS.HTML); assert_equals(d.lastChild.nodeType, Node.TEXT_NODE); assert_equals(d.lastChild.data, RESULTS.HTML); @@ -166,6 +176,8 @@ assert_equals(d.firstChild.nodeType, Node.TEXT_NODE); assert_equals(d.firstChild.data, "null"); + removeChildrenBecauseOfGeckoBug(d); + d.insertAdjacentHTML('beforeend', null); assert_equals(d.lastChild.nodeType, Node.TEXT_NODE); assert_equals(d.lastChild.data, "null"); diff --git a/tests/wpt/tests/trusted-types/support/navigation-report-only-support.html b/tests/wpt/tests/trusted-types/support/navigation-report-only-support.html index a16995ba903..791559f7a19 100644 --- a/tests/wpt/tests/trusted-types/support/navigation-report-only-support.html +++ b/tests/wpt/tests/trusted-types/support/navigation-report-only-support.html @@ -1,53 +1,14 @@ <!DOCTYPE html> <head> + <script src="navigation-support.js"></script> </head> <body> <p>Support page for trusted-types-navigation-report-only.*.html tests.</p> <a id="anchor" href="#">link</a> +<form> + <input id="submit" type="submit"> +</form> <script> - const params = new URLSearchParams(location.search); - if (!!params.get("defaultpolicy")) { - trustedTypes.createPolicy("default", { - createScript: s => s.replace("continue", "defaultpolicywashere"), - }); - } - - function bounceEventToOpener(e) { - const msg = {}; - for (const field of ["effectiveDirective", "sample", "type"]) { - msg[field] = e[field]; - } - msg["uri"] = location.href; - window.opener.postMessage(msg, "*"); - } - - // If a navigation is blocked by Trusted Types, we expect this window to - // throw a SecurityPolicyViolationEvent. If it's not blocked, we expect the - // loaded frame to through DOMContentLoaded. In either case there should be - // _some_ event that we can expect. - document.addEventListener("DOMContentLoaded", bounceEventToOpener); - document.addEventListener("securitypolicyviolation", bounceEventToOpener); - - // Navigate to the non-report-only version of the test. That has the same - // event listening setup as this, but is a different target URI. - const target_script = `location.href='${location.href.replace("-report-only", "") + "#continue"}';`; - const target = `javascript:${target_script}`; - - // Navigate the anchor, but only after the content is loaded (so that we - // won't disturb delivery of that event to the opener. - const anchor = document.getElementById("anchor"); - anchor.href = target; - - if (!!params.get("frame")) { - const frame = document.createElement("iframe"); - frame.src = "frame-without-trusted-types.html"; - frames.name = "frame"; - document.body.appendChild(frame); - anchor.target = "frame"; - } - - if (!location.hash) { - document.addEventListener("DOMContentLoaded", _ => anchor.click()); - } + navigateToJavascriptURL(/* aReportOnly */ true); </script> </body> diff --git a/tests/wpt/tests/trusted-types/support/navigation-support.html b/tests/wpt/tests/trusted-types/support/navigation-support.html index c2c8a82f514..47f33c9fb64 100644 --- a/tests/wpt/tests/trusted-types/support/navigation-support.html +++ b/tests/wpt/tests/trusted-types/support/navigation-support.html @@ -1,51 +1,14 @@ <!DOCTYPE html> <head> + <script src="navigation-support.js"></script> </head> <body> <p>Support page for trusted-types-navigation.*.html tests.</p> <a id="anchor" href="#">link</a> +<form> + <input id="submit" type="submit"> +</form> <script> - const params = new URLSearchParams(location.search); - if (!!params.get("defaultpolicy")) { - trustedTypes.createPolicy("default", { - createScript: s => s.replace("continue", "defaultpolicywashere"), - }); - } - - function bounceEventToOpener(e) { - const msg = {}; - for (const field of ["effectiveDirective", "sample", "type"]) { - msg[field] = e[field]; - } - msg["uri"] = location.href; - window.opener.postMessage(msg, "*"); - } - - // If a navigation is blocked by Trusted Types, we expect this window to - // throw a SecurityPolicyViolationEvent. If it's not blocked, we expect the - // loaded frame to through DOMContentLoaded. In either case there should be - // _some_ event that we can expect. - document.addEventListener("DOMContentLoaded", bounceEventToOpener); - document.addEventListener("securitypolicyviolation", bounceEventToOpener); - - // We'll use a javascript:-url to navigate to ourselves, so that we can - // re-use the messageing mechanisms above. In order to not end up in a loop, - // we'll only click if we don't find fragment in the current URL. - const target_script = `location.href='${location.href}&continue';`; - const target = `javascript:${target_script}`; - - const anchor = document.getElementById("anchor"); - anchor.href = target; - - if (!!params.get("frame")) { - const frame = document.createElement("iframe"); - frame.src = "frame-without-trusted-types.html"; - frames.name = "frame"; - document.body.appendChild(frame); - anchor.target = "frame"; - } - - if (!location.hash) - document.addEventListener("DOMContentLoaded", _ => anchor.click()); + navigateToJavascriptURL(/* aReportOnly */ false); </script> </body> diff --git a/tests/wpt/tests/trusted-types/support/navigation-support.js b/tests/wpt/tests/trusted-types/support/navigation-support.js new file mode 100644 index 00000000000..41dce761def --- /dev/null +++ b/tests/wpt/tests/trusted-types/support/navigation-support.js @@ -0,0 +1,75 @@ +const kNavigationAttempted = "navigationattempted=1"; + +function navigateToJavascriptURL(reportOnly) { + let params = new URLSearchParams(location.search); + + if (!!params.get("defaultpolicy")) { + trustedTypes.createPolicy("default", { + createScript: s => { + return s.replace("continue", "defaultpolicywashere") + }, + }); + } + + function bounceEventToOpener(e) { + const msg = {}; + for (const field of ["effectiveDirective", "sample", "type"]) { + msg[field] = e[field]; + } + + msg["uri"] = location.href; + window.opener.postMessage(msg, "*"); + } + + // If a navigation is blocked by Trusted Types, we expect this window to + // throw a SecurityPolicyViolationEvent. If it's not blocked, we expect the + // loaded frame to through DOMContentLoaded. In either case there should be + // _some_ event that we can expect. + document.addEventListener("DOMContentLoaded", bounceEventToOpener); + document.addEventListener("securitypolicyviolation", bounceEventToOpener); + + let target_script; + if (reportOnly) { + // Navigate to the non-report-only version of the test. That has the same + // event listening setup as this, but is a different target URI. + target_script = `location.href='${location.href.replace("-report-only", "") + + (location.href.endsWith(".html") ? "?" : "&") + kNavigationAttempted + "&continue"}';`; + } else { + // We'll use a javascript:-url to navigate to ourselves, so that we can + // re-use the messageing mechanisms above. + target_script = `location.href='${location.href + "&" + kNavigationAttempted}&continue';`; + } + + function getAndPreparareNavigationElement(javaScriptURL) { + let target = "_self"; + if (!!params.get("frame")) { + const frame = document.createElement("iframe"); + frame.src = "frame-without-trusted-types.html"; + frames.name = "frame"; + document.body.appendChild(frame); + target = "frame"; + } + + if (!!params.get("form-submission")) { + const submit = document.getElementById("submit"); + + // Careful, the IDL attributes are defined in camel-case. + submit.formAction = javaScriptURL; + submit.formTarget = target; + + return submit; + } + + const anchor = document.getElementById("anchor"); + anchor.href = javaScriptURL; + anchor.target = target; + return anchor; + } + + const navigationElement = getAndPreparareNavigationElement(`javascript:${target_script}`); + + // Prevent loops. + if (!location.search.includes(kNavigationAttempted)) { + document.addEventListener("DOMContentLoaded", _ => navigationElement.click()); + } +} diff --git a/tests/wpt/tests/trusted-types/trusted-types-navigation.html b/tests/wpt/tests/trusted-types/trusted-types-navigation.html index 2113711902a..74a25fa3480 100644 --- a/tests/wpt/tests/trusted-types/trusted-types-navigation.html +++ b/tests/wpt/tests/trusted-types/trusted-types-navigation.html @@ -2,25 +2,48 @@ <head> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> + <script src="support/navigation-support.js"></script> </head> <body> <script> + "use strict"; + function expectMessage(filter) { return new Promise(resolve => { - window.addEventListener("message", e => { if (filter(e)) resolve(); }); + + function listener(e) { + if (filter(e)) { + window.removeEventListener("message", listener); + resolve(); + } + } + window.addEventListener("message", listener); }); } function expectViolationAsMessage(sample) { - const filter = e => ((e.data.effectiveDirective == "require-trusted-types-for" || - e.data.effectiveDirective == "trusted-types") && + const filter = e => { + const result = (e.data.effectiveDirective == "require-trusted-types-for" && (!sample || e.data.sample.startsWith(sample))); + if (result) { + assert_true(true, "Expected violation as message: " + sample); + } + + return result; + } return new expectMessage(filter); } function expectLoadedAsMessage(uri) { - const filter = e => (e.data.type == "DOMContentLoaded" && + const filter = e => { + const result = (e.data.type == "DOMContentLoaded" && (!uri || e.data.uri.endsWith(uri))); + if (result) { + assert_true(true, "Expected loaded as message: " + uri); + } + + return result; + } return new expectMessage(filter); } @@ -29,72 +52,116 @@ test.add_cleanup(_ => win.close()); } - promise_test(t => { - openWindow(t, "support/navigation-support.html"); - return Promise.all([ - expectLoadedAsMessage("navigation-support.html"), - expectViolationAsMessage("Location href"), - ]); - }, "Navigate a window with javascript:-urls in enforcing mode."); - - promise_test(t => { - openWindow(t, "support/navigation-support.html?defaultpolicy=1"); - return Promise.all([ - expectLoadedAsMessage("navigation-support.html?defaultpolicy=1"), - expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&defaultpolicywashere"), - ]); - }, "Navigate a window with javascript:-urls w/ default policy in enforcing mode."); - - promise_test(t => { - const page = "navigation-report-only-support.html" - openWindow(t, `support/${page}`); - return Promise.all([ - expectLoadedAsMessage(page), - expectLoadedAsMessage("navigation-support.html#continue"), - ]); - }, "Navigate a window with javascript:-urls in report-only mode."); - - promise_test(t => { - const page = "navigation-report-only-support.html?defaultpolicy=1"; - openWindow(t, `support/${page}`); - return Promise.all([ - expectLoadedAsMessage(page), - expectLoadedAsMessage("navigation-support.html?defaultpolicy=1#defaultpolicywashere"), - ]); - }, "Navigate a window with javascript:-urls w/ default policy in report-only mode."); - - promise_test(t => { - openWindow(t, "support/navigation-support.html?frame=1"); - return Promise.all([ - expectLoadedAsMessage("navigation-support.html?frame=1"), - expectViolationAsMessage("Location href"), - ]); - }, "Navigate a frame with javascript:-urls in enforcing mode."); - - promise_test(t => { - openWindow(t, "support/navigation-support.html?defaultpolicy=1&frame=1"); - return Promise.all([ - expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1"), - expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1&defaultpolicywashere"), - ]); - }, "Navigate a frame with javascript:-urls w/ default policy in enforcing mode."); - - promise_test(t => { - const page = "navigation-report-only-support.html?frame=1" - openWindow(t, `support/${page}`); - return Promise.all([ - expectLoadedAsMessage(page), - expectLoadedAsMessage("navigation-support.html?frame=1#continue"), - ]); - }, "Navigate a frame with javascript:-urls in report-only mode."); - - promise_test(t => { - const page = "navigation-report-only-support.html?defaultpolicy=1&frame=1"; - openWindow(t, `support/${page}`); - return Promise.all([ - expectLoadedAsMessage(page), - expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1#defaultpolicywashere"), - ]); - }, "Navigate a frame with javascript:-urls w/ default policy in report-only mode."); + const kFormSubmission = "form-submission"; + // When adding more elements, adapt all functions consuming the existing elements. + const kNavigationElements = + [ + "anchor", + kFormSubmission, + ]; + + function maybeAddFormSubmissionToSearchParams(navigationElement, searchParams) { + return (navigationElement == kFormSubmission) ? + [kFormSubmission + "=1", ...searchParams] : searchParams; + } + + function joinToHref(searchParams, originAndPathName) { + if (searchParams.length > 0) { + return originAndPathName + "?" + searchParams.join("&"); + } + + return originAndPathName; + } + + for (const navigationElement of kNavigationElements) { + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, []), + "navigation-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectViolationAsMessage("Location href"), + ]); + }, `Navigate a window via ${navigationElement} with javascript:-urls in enforcing mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, ["defaultpolicy=1"]), + "navigation-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectLoadedAsMessage(page + "&" + kNavigationAttempted + "&defaultpolicywashere"), + ]); + }, `Navigate a window via ${navigationElement} with javascript:-urls w/ default policy in enforcing mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, []), + "navigation-report-only-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectLoadedAsMessage(joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, + [kNavigationAttempted, "continue"]), "navigation-support.html")), + ]); + }, `Navigate a window via ${navigationElement} with javascript:-urls in report-only mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, ["defaultpolicy=1"]), + "navigation-report-only-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectLoadedAsMessage(joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, + ["defaultpolicy=1", kNavigationAttempted, "defaultpolicywashere"]), + "navigation-support.html")), + ]); + }, `Navigate a window via ${navigationElement} with javascript:-urls w/ default policy in report-only mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, ["frame=1"]), + "navigation-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectViolationAsMessage("Location href"), + ]); + }, `Navigate a frame via ${navigationElement} with javascript:-urls in enforcing mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, + ["defaultpolicy=1", "frame=1"]), + "navigation-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectLoadedAsMessage(page + "&" + kNavigationAttempted + "&defaultpolicywashere"), + ]); + }, `Navigate a frame via ${navigationElement} with javascript:-urls w/ default policy in enforcing mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, ["frame=1"]), + "navigation-report-only-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectLoadedAsMessage(joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, + ["frame=1", kNavigationAttempted, "continue"]), + "navigation-support.html")), + ]); + }, `Navigate a frame via ${navigationElement} with javascript:-urls in report-only mode.`); + + promise_test(t => { + const page = joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, + ["defaultpolicy=1", "frame=1"]), + "navigation-report-only-support.html"); + openWindow(t, `support/${page}`); + return Promise.all([ + expectLoadedAsMessage(page), + expectLoadedAsMessage(joinToHref(maybeAddFormSubmissionToSearchParams(navigationElement, + ["defaultpolicy=1", "frame=1", kNavigationAttempted, "defaultpolicywashere"]), + "navigation-support.html")), + ]); + }, `Navigate a frame via ${navigationElement} with javascript:-urls w/ default policy in report-only mode.`); + } </script> </body> diff --git a/tests/wpt/tests/url/resources/urltestdata.json b/tests/wpt/tests/url/resources/urltestdata.json index 9dbe5456a96..0ebaf4cd4c4 100644 --- a/tests/wpt/tests/url/resources/urltestdata.json +++ b/tests/wpt/tests/url/resources/urltestdata.json @@ -9992,5 +9992,101 @@ "pathname": "/", "search": "", "hash": "" + }, + "# Non-special URL and backslashes", + { + "input": "non-special:\\\\opaque", + "base": null, + "href": "non-special:\\\\opaque", + "origin": "null", + "protocol": "non-special:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "\\\\opaque", + "search": "", + "hash": "" + }, + { + "input": "non-special:\\\\opaque/path", + "base": null, + "href": "non-special:\\\\opaque/path", + "origin": "null", + "protocol": "non-special:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "\\\\opaque/path", + "search": "", + "hash": "" + }, + { + "input": "non-special:\\\\opaque\\path", + "base": null, + "href": "non-special:\\\\opaque\\path", + "origin": "null", + "protocol": "non-special:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "\\\\opaque\\path", + "search": "", + "hash": "" + }, + { + "input": "non-special:\\/opaque", + "base": null, + "href": "non-special:\\/opaque", + "origin": "null", + "protocol": "non-special:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "\\/opaque", + "search": "", + "hash": "" + }, + { + "input": "non-special:/\\path", + "base": null, + "href": "non-special:/\\path", + "origin": "null", + "protocol": "non-special:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/\\path", + "search": "", + "hash": "" + }, + { + "input": "non-special://host\\a", + "base": null, + "failure": true + }, + { + "input": "non-special://host/a\\b", + "base": null, + "href": "non-special://host/a\\b", + "origin": "null", + "protocol": "non-special:", + "username": "", + "password": "", + "host": "host", + "hostname": "host", + "port": "", + "pathname": "/a\\b", + "search": "", + "hash": "" } ] diff --git a/tests/wpt/tests/wasm/jsapi/jspi/README.txt b/tests/wpt/tests/wasm/jsapi/jspi/README.txt new file mode 100644 index 00000000000..c65b9893c6f --- /dev/null +++ b/tests/wpt/tests/wasm/jsapi/jspi/README.txt @@ -0,0 +1,3 @@ +This suite tests JSPI. + +The tests are based on wasm spec tests. diff --git a/tests/wpt/tests/wasm/jsapi/jspi/js-promise-integration.any.js b/tests/wpt/tests/wasm/jsapi/jspi/js-promise-integration.any.js new file mode 100644 index 00000000000..19de3146f92 --- /dev/null +++ b/tests/wpt/tests/wasm/jsapi/jspi/js-promise-integration.any.js @@ -0,0 +1,372 @@ +// META: global=window,dedicatedworker,jsshell +// META: script=/wasm/jsapi/wasm-module-builder.js + +// Test for invalid wrappers +test(() => { + assert_throws_js(TypeError, () => WebAssembly.promising({}), + "Argument 0 must be a function"); + assert_throws_js(TypeError, () => WebAssembly.promising(() => {}), + "Argument 0 must be a WebAssembly exported function"); + assert_throws_js(TypeError, () => WebAssembly.Suspending(() => {}), + "WebAssembly.Suspending must be invoked with 'new'"); + assert_throws_js(TypeError, () => new WebAssembly.Suspending({}), + "Argument 0 must be a function"); + + function asmModule() { + "use asm"; + + function x(v) { + v = v | 0; + } + return x; + } + assert_throws_js(TypeError, () => WebAssembly.promising(asmModule()), + "Argument 0 must be a WebAssembly exported function"); +},"Valid use of API"); + +test(() => { + let builder = new WasmModuleBuilder(); + builder.addGlobal(kWasmI32, true).exportAs('g'); + builder.addFunction("test", kSig_i_v) + .addBody([ + kExprI32Const, 42, + kExprGlobalSet, 0, + kExprI32Const, 0 + ]).exportFunc(); + let instance = builder.instantiate(); + let wrapper = WebAssembly.promising(instance.exports.test); + wrapper(); + assert_equals(42, instance.exports.g.value); +},"Promising function always entered"); + +promise_test(async () => { + let builder = new WasmModuleBuilder(); + let import_index = builder.addImport('m', 'import', kSig_i_v); + builder.addFunction("test", kSig_i_i) + .addBody([ + kExprCallFunction, import_index, // suspend + ]).exportFunc(); + let js_import = () => 42; + let instance = builder.instantiate({ + m: { + import: js_import + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + assert_true(export_promise instanceof Promise); + assert_equals(await export_promise, 42); +}, "Always get a Promise"); + +promise_test(async () => { + let builder = new WasmModuleBuilder(); + let import_index = builder.addImport('m', 'import', kSig_i_i); + builder.addFunction("test", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprCallFunction, import_index, // suspend + ]).exportFunc(); + let js_import = new WebAssembly.Suspending(() => Promise.resolve(42)); + let instance = builder.instantiate({ + m: { + import: js_import + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + assert_true(export_promise instanceof Promise); + assert_equals(await export_promise, 42); +}, "Suspend once"); + +promise_test(async () => { + let builder = new WasmModuleBuilder(); + builder.addGlobal(kWasmI32, true).exportAs('g'); + let import_index = builder.addImport('m', 'import', kSig_i_v); + // void test() { + // for (i = 0; i < 5; ++i) { + // g = g + await import(); + // } + // } + builder.addFunction("test", kSig_v_i) + .addLocals({ + i32_count: 1 + }) + .addBody([ + kExprI32Const, 5, + kExprLocalSet, 1, + kExprLoop, kWasmStmt, + kExprCallFunction, import_index, // suspend + kExprGlobalGet, 0, + kExprI32Add, + kExprGlobalSet, 0, + kExprLocalGet, 1, + kExprI32Const, 1, + kExprI32Sub, + kExprLocalTee, 1, + kExprBrIf, 0, + kExprEnd, + ]).exportFunc(); + let i = 0; + + function js_import() { + return Promise.resolve(++i); + }; + let wasm_js_import = new WebAssembly.Suspending(js_import); + let instance = builder.instantiate({ + m: { + import: wasm_js_import + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + assert_equals(instance.exports.g.value, 0); + assert_true(export_promise instanceof Promise); + await export_promise; + assert_equals(instance.exports.g.value, 15); +}, "Suspend/resume in a loop"); + +promise_test(async () => { + let builder = new WasmModuleBuilder(); + let import_index = builder.addImport('m', 'import', kSig_i_v); + builder.addFunction("test", kSig_i_v) + .addBody([ + kExprCallFunction, import_index, // suspend + ]).exportFunc(); + let js_import = new WebAssembly.Suspending(() => Promise.resolve(42)); + let instance = builder.instantiate({ + m: { + import: js_import + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + assert_equals(await wrapped_export(), 42); + + // Also try with a JS function with a mismatching arity. + js_import = new WebAssembly.Suspending((unused) => Promise.resolve(42)); + instance = builder.instantiate({ + m: { + import: js_import + } + }); + wrapped_export = WebAssembly.promising(instance.exports.test); + assert_equals(await wrapped_export(), 42); + + // Also try with a proxy. + js_import = new WebAssembly.Suspending(new Proxy(() => Promise.resolve(42), {})); + instance = builder.instantiate({ + m: { + import: js_import + } + }); + wrapped_export = WebAssembly.promising(instance.exports.test); + assert_equals(await wrapped_export(), 42); +},"Suspending with mismatched args and via Proxy"); + +function recordAbeforeB() { + let AbeforeB = []; + let setA = () => { + AbeforeB.push("A") + } + let setB = () => { + AbeforeB.push("B") + } + let isAbeforeB = () => + AbeforeB[0] == "A" && AbeforeB[1] == "B"; + + let isBbeforeA = () => + AbeforeB[0] == "B" && AbeforeB[1] == "A"; + + return { + setA: setA, + setB: setB, + isAbeforeB: isAbeforeB, + isBbeforeA: isBbeforeA, + } +} + +promise_test(async () => { + let builder = new WasmModuleBuilder(); + let AbeforeB = recordAbeforeB(); + let import42_index = builder.addImport('m', 'import42', kSig_i_i); + let importSetA_index = builder.addImport('m', 'setA', kSig_v_v); + builder.addFunction("test", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprCallFunction, import42_index, // suspend? + kExprCallFunction, importSetA_index + ]).exportFunc(); + let import42 = new WebAssembly.Suspending(() => Promise.resolve(42)); + let instance = builder.instantiate({ + m: { + import42: import42, + setA: AbeforeB.setA + } + }); + + let wrapped_export = WebAssembly.promising(instance.exports.test); + + let exported_promise = wrapped_export(); + + AbeforeB.setB(); + + assert_equals(await exported_promise, 42); + + assert_true(AbeforeB.isBbeforeA()); +}, "Make sure we actually suspend"); + +promise_test(async () => { + let builder = new WasmModuleBuilder(); + let AbeforeB = recordAbeforeB(); + let import42_index = builder.addImport('m', 'import42', kSig_i_i); + let importSetA_index = builder.addImport('m', 'setA', kSig_v_v); + builder.addFunction("test", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprCallFunction, import42_index, // suspend? + kExprCallFunction, importSetA_index + ]).exportFunc(); + let import42 = new WebAssembly.Suspending(() => 42); + let instance = builder.instantiate({ + m: { + import42: import42, + setA: AbeforeB.setA + } + }); + + let wrapped_export = WebAssembly.promising(instance.exports.test); + + let exported_promise = wrapped_export(); + AbeforeB.setB(); + assert_true(AbeforeB.isAbeforeB()); + + assert_equals(await exported_promise, 42); +}, "Do not suspend if the import's return value is not a Promise"); + +promise_test(async (t) => { + let tag = new WebAssembly.Tag({ + parameters: ['i32'] + }); + let builder = new WasmModuleBuilder(); + let import_index = builder.addImport('m', 'import', kSig_i_i); + let tag_index = builder.addImportedTag('m', 'tag', kSig_v_i); + builder.addFunction("test", kSig_i_i) + .addBody([ + kExprTry, kWasmI32, + kExprLocalGet, 0, + kExprCallFunction, import_index, + kExprCatch, tag_index, + kExprEnd + ]).exportFunc(); + + function js_import(unused) { + return Promise.reject(new WebAssembly.Exception(tag, [42])); + }; + let wasm_js_import = new WebAssembly.Suspending(js_import); + + let instance = builder.instantiate({ + m: { + import: wasm_js_import, + tag: tag + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + assert_true(export_promise instanceof Promise); + assert_equals(await export_promise, 42); +}, "Catch rejected promise"); + +async function TestSandwich(suspend) { + // Set up a 'sandwich' scenario. The call chain looks like: + // top (wasm) -> outer (js) -> bottom (wasm) -> inner (js) + // If 'suspend' is true, the inner JS function returns a Promise, which + // suspends the bottom wasm function, which returns a Promise, which suspends + // the top wasm function, which returns a Promise. The inner Promise + // resolves first, which resumes the bottom continuation. Then the outer + // promise resolves which resumes the top continuation. + // If 'suspend' is false, the bottom JS function returns a regular value and + // no computation is suspended. + let builder = new WasmModuleBuilder(); + let inner_index = builder.addImport('m', 'inner', kSig_i_i); + let outer_index = builder.addImport('m', 'outer', kSig_i_i); + builder.addFunction("top", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprCallFunction, outer_index + ]).exportFunc(); + builder.addFunction("bottom", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprCallFunction, inner_index + ]).exportFunc(); + + let inner = new WebAssembly.Suspending(() => suspend ? Promise.resolve(42) : 43); + + let export_inner; + let outer = new WebAssembly.Suspending(() => export_inner()); + + let instance = builder.instantiate({ + m: { + inner, + outer + } + }); + export_inner = WebAssembly.promising(instance.exports.bottom); + let export_top = WebAssembly.promising(instance.exports.top); + let result = export_top(); + assert_true(result instanceof Promise); + if (suspend) + assert_equals(await result, 42); + else + assert_equals(await result, 43); +} + +promise_test(async () => { + TestSandwich(true); +}, "Test sandwich with suspension"); + +promise_test(async () => { + TestSandwich(false); +}, "Test sandwich with no suspension"); + +test(() => { + // Check that a promising function with no return is allowed. + let builder = new WasmModuleBuilder(); + builder.addFunction("export", kSig_v_v).addBody([]).exportFunc(); + let instance = builder.instantiate(); + let export_wrapper = WebAssembly.promising(instance.exports.export); + let export_sig = export_wrapper.type(); + assert_array_equals(export_sig.parameters, []); + assert_array_equals(export_sig.results, ['externref']); +},"Promising with no return"); + +promise_test(async () => { + let builder1 = new WasmModuleBuilder(); + let import_index = builder1.addImport('m', 'import', kSig_i_v); + builder1.addFunction("f", kSig_i_v) + .addBody([ + kExprCallFunction, import_index, // suspend + kExprI32Const, 1, + kExprI32Add, + ]).exportFunc(); + let js_import = new WebAssembly.Suspending(() => Promise.resolve(1)); + let instance1 = builder1.instantiate({ + m: { + import: js_import + } + }); + let builder2 = new WasmModuleBuilder(); + import_index = builder2.addImport('m', 'import', kSig_i_v); + builder2.addFunction("main", kSig_i_v) + .addBody([ + kExprCallFunction, import_index, + kExprI32Const, 1, + kExprI32Add, + ]).exportFunc(); + let instance2 = builder2.instantiate({ + m: { + import: instance1.exports.f + } + }); + let wrapped_export = WebAssembly.promising(instance2.exports.main); + assert_equals(await wrapped_export(), 3); +},"Suspend two modules");
\ No newline at end of file diff --git a/tests/wpt/tests/wasm/jsapi/jspi/rejects.any.js b/tests/wpt/tests/wasm/jsapi/jspi/rejects.any.js new file mode 100644 index 00000000000..3ec3b90592a --- /dev/null +++ b/tests/wpt/tests/wasm/jsapi/jspi/rejects.any.js @@ -0,0 +1,143 @@ +// META: global=window,dedicatedworker,jsshell +// META: script=/wasm/jsapi/wasm-module-builder.js +// META: script=/wasm/jsapi/jspi/testharness-additions.js + +promise_test(t => { + let tag = new WebAssembly.Tag({ + parameters: [] + }); + let builder = new WasmModuleBuilder(); + import_index = builder.addImport('m', 'import', kSig_i_i); + tag_index = builder.addImportedTag('m', 'tag', kSig_v_v); + builder.addFunction("test", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprCallFunction, import_index, + kExprThrow, tag_index + ]).exportFunc(); + + function js_import() { + return Promise.resolve(); + }; + let wasm_js_import = new WebAssembly.Suspending(js_import); + + let instance = builder.instantiate({ + m: { + import: wasm_js_import, + tag: tag + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + assert_true(export_promise instanceof Promise); + return promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise); +}, "Throw after the first suspension"); + +// Throw an exception before suspending. The export wrapper should return a +// promise rejected with the exception. +promise_test(async (t) => { + let tag = new WebAssembly.Tag({ + parameters: [] + }); + let builder = new WasmModuleBuilder(); + tag_index = builder.addImportedTag('m', 'tag', kSig_v_v); + builder.addFunction("test", kSig_i_v) + .addBody([ + kExprThrow, tag_index + ]).exportFunc(); + + let instance = builder.instantiate({ + m: { + tag: tag + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + + promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise); +}, "Throw before suspending"); + +// Throw an exception after the first resume event, which propagates to the +// promise wrapper. +promise_test(async (t) => { + let tag = new WebAssembly.Tag({ + parameters: [] + }); + let builder = new WasmModuleBuilder(); + import_index = builder.addImport('m', 'import', kSig_i_v); + tag_index = builder.addImportedTag('m', 'tag', kSig_v_v); + builder.addFunction("test", kSig_i_v) + .addBody([ + kExprCallFunction, import_index, + kExprThrow, tag_index + ]).exportFunc(); + + function js_import() { + return Promise.resolve(42); + }; + let wasm_js_import = new WebAssembly.Suspending(js_import); + + let instance = builder.instantiate({ + m: { + import: wasm_js_import, + tag: tag + } + }); + let wrapped_export = WebAssembly.promising(instance.exports.test); + let export_promise = wrapped_export(); + + promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise); +}, "Throw and propagate via Promise"); + +promise_test(async (t) => { + let builder = new WasmModuleBuilder(); + builder.addFunction("test", kSig_i_v) + .addBody([ + kExprCallFunction, 0 + ]).exportFunc(); + let instance = builder.instantiate(); + let wrapper = WebAssembly.promising(instance.exports.test); + + promise_rejects_js(t, RangeError, wrapper(), "Maximum call stack size exceeded"); +}, "Stack overflow"); + +promise_test(async (t) => { + // The call stack of this test looks like: + // export1 -> import1 -> export2 -> import2 + // Where export1 is "promising" and import2 is "suspending". Returning a + // promise from import2 should trap because of the JS import in the middle. + let builder = new WasmModuleBuilder(); + let import1_index = builder.addImport("m", "import1", kSig_i_v); + let import2_index = builder.addImport("m", "import2", kSig_i_v); + builder.addFunction("export1", kSig_i_v) + .addBody([ + // export1 -> import1 (unwrapped) + kExprCallFunction, import1_index, + ]).exportFunc(); + builder.addFunction("export2", kSig_i_v) + .addBody([ + // export2 -> import2 (suspending) + kExprCallFunction, import2_index, + ]).exportFunc(); + let instance; + + function import1() { + // import1 -> export2 (unwrapped) + instance.exports.export2(); + } + + function import2() { + return Promise.resolve(0); + } + import2 = new WebAssembly.Suspending(import2); + instance = builder.instantiate({ + 'm': { + 'import1': import1, + 'import2': import2 + } + }); + // export1 (promising) + let wrapper = WebAssembly.promising(instance.exports.export1); + promise_rejects_js(t, WebAssembly.RuntimeError, wrapper(), + "trying to suspend JS frames"); +}, "Try to suspend JS");
\ No newline at end of file diff --git a/tests/wpt/tests/wasm/jsapi/jspi/testharness-additions.js b/tests/wpt/tests/wasm/jsapi/jspi/testharness-additions.js new file mode 100644 index 00000000000..e146c52f96d --- /dev/null +++ b/tests/wpt/tests/wasm/jsapi/jspi/testharness-additions.js @@ -0,0 +1,26 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function assert_throws_jspi(code, func, description) { + try { + func(); + } catch (e) { + assert_true( + e.name === code.name, + 'expected exception ' + code.name + ', got ' + e.name); + return; + } + assert_true( + false, 'expected exception ' + code.name + ', no exception thrown'); + } + + function promise_rejects_jspi(test, expected, promise, description) { + return promise + .then(() => assert_unreached('Should have rejected: ' + description)) + .catch(function(e) { + assert_throws_jspi(expected, function() { + throw e; + }, description); + }); + } diff --git a/tests/wpt/tests/wasm/jsapi/memory/assertions.js b/tests/wpt/tests/wasm/jsapi/memory/assertions.js index b539513adca..1430c523882 100644 --- a/tests/wpt/tests/wasm/jsapi/memory/assertions.js +++ b/tests/wpt/tests/wasm/jsapi/memory/assertions.js @@ -26,6 +26,7 @@ function assert_ArrayBuffer(actual, { size=0, shared=false, detached=false }, me assert_equals(Object.isFrozen(actual), shared, "buffer frozen"); assert_equals(Object.isExtensible(actual), !shared, "buffer extensibility"); } +globalThis.assert_ArrayBuffer = assert_ArrayBuffer; function assert_Memory(memory, { size=0, shared=false }) { assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype, @@ -36,3 +37,4 @@ function assert_Memory(memory, { size=0, shared=false }) { assert_equals(memory.buffer, memory.buffer, "buffer should be idempotent"); assert_ArrayBuffer(memory.buffer, { size, shared }); } +globalThis.assert_Memory = assert_Memory; diff --git a/tests/wpt/tests/wasm/jsapi/table/assertions.js b/tests/wpt/tests/wasm/jsapi/table/assertions.js index 19cc5c3b92d..4fcd3517a6a 100644 --- a/tests/wpt/tests/wasm/jsapi/table/assertions.js +++ b/tests/wpt/tests/wasm/jsapi/table/assertions.js @@ -11,6 +11,7 @@ function assert_equal_to_array(table, expected, message) { assert_throws_js(RangeError, () => table.get(expected.length + 1), `${message}: table.get(${expected.length + 1} of ${expected.length})`); } +globalThis.assert_equal_to_array = assert_equal_to_array; function assert_Table(actual, expected) { assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype, @@ -22,3 +23,4 @@ function assert_Table(actual, expected) { assert_equals(actual.get(i), null, `actual.get(${i})`); } } +globalThis.assert_Table = assert_Table; diff --git a/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js b/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js index 90ccc954a5d..7fa196c58c1 100644 --- a/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js +++ b/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js @@ -81,6 +81,7 @@ let kWasmSubtypeFinalForm = 0x4f; let kWasmRecursiveTypeGroupForm = 0x4e; let kNoSuperType = 0xFFFFFFFF; +globalThis.kNoSuperType = kNoSuperType; let kHasMaximumFlag = 1; let kSharedHasMaximumFlag = 3; @@ -146,12 +147,27 @@ function wasmRefType(heap_type) { return {opcode: kWasmRef, heap_type: heap_type}; } +Object.assign(globalThis, { + kWasmStmt, kWasmI32, kWasmI64, kWasmF32, kWasmF64, kWasmS128, kWasmI8, + kWasmI16, kWasmNullFuncRef, kWasmNullExternRef, kWasmNullRef, kWasmFuncRef, + kWasmAnyFunc, kWasmExternRef, kWasmAnyRef, kWasmEqRef, kWasmI31Ref, + kWasmStructRef, kWasmArrayRef, kFuncRefCode, kAnyFuncCode, kExternRefCode, + kAnyRefCode, kEqRefCode, kI31RefCode, kNullExternRefCode, kNullFuncRefCode, + kStructRefCode, kArrayRefCode, kNullRefCode, kWasmRefNull, kWasmRef, + wasmRefNullType, wasmRefType +}); + let kExternalFunction = 0; let kExternalTable = 1; let kExternalMemory = 2; let kExternalGlobal = 3; let kExternalTag = 4; +Object.assign(globalThis, { + kExternalFunction, kExternalTable, kExternalMemory, kExternalGlobal, + kExternalTag +}); + let kTableZero = 0; let kMemoryZero = 0; let kSegmentZero = 0; @@ -227,6 +243,17 @@ function makeSig_r_xx(r, x) { return makeSig([x, x], [r]); } +Object.assign(globalThis, { + kSig_i_i, kSig_l_l, kSig_i_l, kSig_i_ii, kSig_i_iii, kSig_v_iiii, kSig_f_ff, + kSig_d_dd, kSig_l_ll, kSig_i_dd, kSig_v_v, kSig_i_v, kSig_l_v, kSig_f_v, + kSig_d_v, kSig_v_i, kSig_v_ii, kSig_v_iii, kSig_v_l, kSig_v_d, kSig_v_dd, + kSig_v_ddi, kSig_ii_v, kSig_iii_v, kSig_ii_i, kSig_iii_i, kSig_ii_ii, + kSig_iii_ii, kSig_v_f, kSig_f_f, kSig_f_d, kSig_d_d, kSig_r_r, kSig_a_a, + kSig_i_r, kSig_v_r, kSig_v_a, kSig_v_rr, kSig_v_aa, kSig_r_v, kSig_a_v, + kSig_a_i, + makeSig, makeSig_v_x, makeSig_v_xx, makeSig_r_v, makeSig_r_x, makeSig_r_xx +}); + // Opcodes let kExprUnreachable = 0x00; let kExprNop = 0x01; @@ -553,6 +580,89 @@ let kExprI32x4Eq = 0x2c; let kExprS1x4AllTrue = 0x75; let kExprF32x4Min = 0x9e; +Object.assign(globalThis, { + kExprUnreachable, kExprNop, kExprBlock, kExprLoop, kExprIf, kExprElse, + kExprTry, kExprCatch, kExprCatchAll, kExprThrow, kExprRethrow, kExprBrOnExn, + kExprEnd, kExprBr, kExprBrIf, kExprBrTable, kExprReturn, kExprCallFunction, + kExprCallIndirect, kExprReturnCall, kExprReturnCallIndirect, kExprDrop, + kExprSelect, kExprLocalGet, kExprLocalSet, kExprLocalTee, kExprGlobalGet, + kExprGlobalSet, kExprTableGet, kExprTableSet, kExprI32LoadMem, + kExprI64LoadMem, kExprF32LoadMem, kExprF64LoadMem, kExprI32LoadMem8S, + kExprI32LoadMem8U, kExprI32LoadMem16S, kExprI32LoadMem16U, kExprI64LoadMem8S, + kExprI64LoadMem8U, kExprI64LoadMem16S, kExprI64LoadMem16U, kExprI64LoadMem32S, + kExprI64LoadMem32U, kExprI32StoreMem, kExprI64StoreMem, kExprF32StoreMem, + kExprF64StoreMem, kExprI32StoreMem8, kExprI32StoreMem16, kExprI64StoreMem8, + kExprI64StoreMem16, kExprI64StoreMem32, kExprMemorySize, kExprMemoryGrow, + kExprI32Const, kExprI64Const, kExprF32Const, kExprF64Const, kExprI32Eqz, + kExprI32Eq, kExprI32Ne, kExprI32LtS, kExprI32LtU, kExprI32GtS, kExprI32GtU, + kExprI32LeS, kExprI32LeU, kExprI32GeS, kExprI32GeU, kExprI64Eqz, kExprI64Eq, + kExprI64Ne, kExprI64LtS, kExprI64LtU, kExprI64GtS, kExprI64GtU, kExprI64LeS, + kExprI64LeU, kExprI64GeS, kExprI64GeU, kExprF32Eq, kExprF32Ne, kExprF32Lt, + kExprF32Gt, kExprF32Le, kExprF32Ge, kExprF64Eq, kExprF64Ne, kExprF64Lt, + kExprF64Gt, kExprF64Le, kExprF64Ge, kExprI32Clz, kExprI32Ctz, kExprI32Popcnt, + kExprI32Add, kExprI32Sub, kExprI32Mul, kExprI32DivS, kExprI32DivU, + kExprI32RemS, kExprI32RemU, kExprI32And, kExprI32Ior, kExprI32Xor, + kExprI32Shl, kExprI32ShrS, kExprI32ShrU, kExprI32Rol, kExprI32Ror, + kExprI64Clz, kExprI64Ctz, kExprI64Popcnt, kExprI64Add, kExprI64Sub, + kExprI64Mul, kExprI64DivS, kExprI64DivU, kExprI64RemS, kExprI64RemU, + kExprI64And, kExprI64Ior, kExprI64Xor, kExprI64Shl, kExprI64ShrS, + kExprI64ShrU, kExprI64Rol, kExprI64Ror, kExprF32Abs, kExprF32Neg, + kExprF32Ceil, kExprF32Floor, kExprF32Trunc, kExprF32NearestInt, kExprF32Sqrt, + kExprF32Add, kExprF32Sub, kExprF32Mul, kExprF32Div, kExprF32Min, kExprF32Max, + kExprF32CopySign, kExprF64Abs, kExprF64Neg, kExprF64Ceil, kExprF64Floor, + kExprF64Trunc, kExprF64NearestInt, kExprF64Sqrt, kExprF64Add, kExprF64Sub, + kExprF64Mul, kExprF64Div, kExprF64Min, kExprF64Max, kExprF64CopySign, + kExprI32ConvertI64, kExprI32SConvertF32, kExprI32UConvertF32, + kExprI32SConvertF64, kExprI32UConvertF64, kExprI64SConvertI32, + kExprI64UConvertI32, kExprI64SConvertF32, kExprI64UConvertF32, + kExprI64SConvertF64, kExprI64UConvertF64, kExprF32SConvertI32, + kExprF32UConvertI32, kExprF32SConvertI64, kExprF32UConvertI64, + kExprF32ConvertF64, kExprF64SConvertI32, kExprF64UConvertI32, + kExprF64SConvertI64, kExprF64UConvertI64, kExprF64ConvertF32, + kExprI32ReinterpretF32, kExprI64ReinterpretF64, kExprF32ReinterpretI32, + kExprF64ReinterpretI64, kExprI32SExtendI8, kExprI32SExtendI16, + kExprI64SExtendI8, kExprI64SExtendI16, kExprI64SExtendI32, kExprRefNull, + kExprRefIsNull, kExprRefFunc, + GCInstr, + kExprStructNew, kExprStructNewDefault, kExprStructGet, kExprStructGetS, + kExprStructGetU, kExprStructSet, kExprArrayNew, kExprArrayNewDefault, + kExprArrayNewFixed, kExprArrayNewData, kExprArrayNewElem, kExprArrayGet, + kExprArrayGetS, kExprArrayGetU, kExprArraySet, kExprArrayLen, kExprArrayFill, + kExprArrayCopy, kExprArrayInitData, kExprArrayInitElem, kExprRefTest, + kExprRefTestNull, kExprRefCast, kExprRefCastNull, kExprBrOnCast, + kExprBrOnCastFail, kExprExternInternalize, kExprExternExternalize, + kExprI31New, kExprI31GetS, kExprI31GetU, + kExprMemoryInit, kExprDataDrop, kExprMemoryCopy, kExprMemoryFill, + kExprTableInit, kExprElemDrop, kExprTableCopy, kExprTableGrow, kExprTableSize, + kExprTableFill, + kExprAtomicNotify, kExprI32AtomicWait, kExprI64AtomicWait, kExprI32AtomicLoad, + kExprI32AtomicLoad8U, kExprI32AtomicLoad16U, kExprI32AtomicStore, + kExprI32AtomicStore8U, kExprI32AtomicStore16U, kExprI32AtomicAdd, + kExprI32AtomicAdd8U, kExprI32AtomicAdd16U, kExprI32AtomicSub, + kExprI32AtomicSub8U, kExprI32AtomicSub16U, kExprI32AtomicAnd, + kExprI32AtomicAnd8U, kExprI32AtomicAnd16U, kExprI32AtomicOr, + kExprI32AtomicOr8U, kExprI32AtomicOr16U, kExprI32AtomicXor, + kExprI32AtomicXor8U, kExprI32AtomicXor16U, kExprI32AtomicExchange, + kExprI32AtomicExchange8U, kExprI32AtomicExchange16U, + kExprI32AtomicCompareExchange, kExprI32AtomicCompareExchange8U, + kExprI32AtomicCompareExchange16U, kExprI64AtomicLoad, kExprI64AtomicLoad8U, + kExprI64AtomicLoad16U, kExprI64AtomicLoad32U, kExprI64AtomicStore, + kExprI64AtomicStore8U, kExprI64AtomicStore16U, kExprI64AtomicStore32U, + kExprI64AtomicAdd, kExprI64AtomicAdd8U, kExprI64AtomicAdd16U, + kExprI64AtomicAdd32U, kExprI64AtomicSub, kExprI64AtomicSub8U, + kExprI64AtomicSub16U, kExprI64AtomicSub32U, kExprI64AtomicAnd, + kExprI64AtomicAnd8U, kExprI64AtomicAnd16U, kExprI64AtomicAnd32U, + kExprI64AtomicOr, kExprI64AtomicOr8U, kExprI64AtomicOr16U, + kExprI64AtomicOr32U, kExprI64AtomicXor, kExprI64AtomicXor8U, + kExprI64AtomicXor16U, kExprI64AtomicXor32U, kExprI64AtomicExchange, + kExprI64AtomicExchange8U, kExprI64AtomicExchange16U, + kExprI64AtomicExchange32U, kExprI64AtomicCompareExchange, + kExprI64AtomicCompareExchange8U, kExprI64AtomicCompareExchange16U, + kExprI64AtomicCompareExchange32U, + kExprS128LoadMem, kExprS128StoreMem, kExprI32x4Splat, kExprI32x4Eq, + kExprS1x4AllTrue, kExprF32x4Min +}); + class Binary { constructor() { this.length = 0; diff --git a/tests/wpt/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-resume-after-suspended.html b/tests/wpt/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-resume-after-suspended.html new file mode 100644 index 00000000000..82b17faa5a2 --- /dev/null +++ b/tests/wpt/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-resume-after-suspended.html @@ -0,0 +1,106 @@ +<!doctype html> +<meta name="timeout" content="long"> +<title>AnalyzerNode resumed after suspended</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> + +function areFloat32ArraysEqual(arr1, arr2) { + if (arr1.length !== arr2.length) { + return false; + } + + for (let i = 0; i < arr1.length; i++) { + if (arr1[i] !== arr2[i]) { + return false; + } + } + + return true; +} + +// This test ensures that calling suspend() does not clear or reset +// the AnalyserNode, and that after resuming the AudioContext, +// it continues retrieving valid data without any interruptions. +promise_test(async () => { + function runTest(resolve) { + const context = new AudioContext(); + context.suspend(); + + const oscillator = new OscillatorNode(context); + oscillator.connect(context.destination); + oscillator.start(); + + const analyser = new AnalyserNode(context); + oscillator.connect(analyser); + + let analyserReadCount = 0; + let lastTime = 0; + // Time between checks in milliseconds. + const interval = 300; + + let previousTimeDomainDataArray = + new Float32Array(analyser.frequencyBinCount); + + // The analyser.getFloatTimeDomainData() is called every 300 ms under + // suspended or resumed state. If it is a suspended state, the value + // from the function should be the same as the previous value. If + // it is a resumed state, the value should be different. + async function readAnalyserData(timestamp) { + if (lastTime === 0) { + lastTime = timestamp; + } + + const elapsed = timestamp - lastTime; + + // Only run the readAnalyserData every 300ms in order to give enough time + // for context to pull the data. + if (elapsed >= interval) { + analyserReadCount++; + + let shouldSkipAsserts = false; + switch (analyserReadCount) { + case 1: + shouldSkipAsserts = true; + break; + case 10: + await context.suspend(); + shouldSkipAsserts = true; + break; + case 5: + case 15: + await context.resume(); + shouldSkipAsserts = true; + break; + case 20: + oscillator.stop(); + resolve(); + break; + default: + break; + } + + const timeDomainDataArray = + new Float32Array(analyser.frequencyBinCount); + analyser.getFloatTimeDomainData(timeDomainDataArray); + + if (!shouldSkipAsserts) { + let result = areFloat32ArraysEqual(timeDomainDataArray, + previousTimeDomainDataArray); + context.state === 'suspended' ? assert_true(result) + : assert_false(result); + } + + previousTimeDomainDataArray.set(timeDomainDataArray); + lastTime = timestamp; + } + + requestAnimationFrame(readAnalyserData); + } + + requestAnimationFrame(readAnalyserData); + } + + return new Promise((resolve) => runTest(resolve)); +}, 'AnalyserNode resume after suspended'); +</script> diff --git a/tests/wpt/tests/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https.html b/tests/wpt/tests/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https.html index a456f88e186..e000ab124fe 100644 --- a/tests/wpt/tests/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https.html +++ b/tests/wpt/tests/webaudio/the-audio-api/the-audiocontext-interface/processing-after-resume.https.html @@ -26,51 +26,30 @@ const modulePath = '/webaudio/the-audio-api/' + 'the-audioworklet-interface/processors/port-processor.js'; promise_test(async () => { - let construct1; - async function run_test() { - const timeBeforeResume = realtime.currentTime; - // Get the currentTime at the same time with AudioContext.currentTime. - const {node: node1} = await construct1; - const constructReply1 = await ping_for_reply(node1); - - // Two AudioWorkletNodes are constructed. - // node1 is constructed before and node2 after the resume() call. - await realtime.resume(); - const construct2 = get_node_and_reply(realtime); - - assert_equals(constructReply1.timeStamp, timeBeforeResume, - 'construct time before resume'); - const {node: node2, reply: constructReply2} = await construct2; - - assert_greater_than_equal(constructReply2.timeStamp, timeBeforeResume, - 'construct time after resume'); - - // Suspend the context to freeze time and check that the processing for each - // node matches the elapsed time. - await realtime.suspend(); - const timeAfterSuspend = realtime.currentTime; - const pong1 = await ping_for_reply(node1); - const pong2 = await ping_for_reply(node2); - assert_consistent(constructReply1, pong1, timeAfterSuspend, 'node1'); - assert_consistent(constructReply2, pong2, timeAfterSuspend, 'node2'); - assert_equals(pong1.currentFrame, pong2.currentFrame, - 'currentFrame matches'); - }; - const realtime = new AudioContext(); await realtime.audioWorklet.addModule(modulePath); - construct1 = get_node_and_reply(realtime); - - if (realtime.state === 'running') { - realtime.suspend(); - realtime.onstatechange = async (e) => { - if (e.target.state === 'suspended') { - e.target.onstatechange = null; - await run_test(); - } - }; - } else { - await run_test(); - } + await realtime.suspend(); + const timeBeforeResume = realtime.currentTime; + // Two AudioWorkletNodes are constructed. + // node1 is constructed before and node2 after the resume() call. + const construct1 = get_node_and_reply(realtime); + const resume = realtime.resume(); + const construct2 = get_node_and_reply(realtime); + const {node: node1, reply: constructReply1} = await construct1; + assert_equals(constructReply1.timeStamp, timeBeforeResume, + 'construct time before resume'); + const {node: node2, reply: constructReply2} = await construct2; + assert_greater_than_equal(constructReply2.timeStamp, timeBeforeResume, + 'construct time after resume'); + await resume; + // Suspend the context to freeze time and check that the processing for each + // node matches the elapsed time. + await realtime.suspend(); + const timeAfterSuspend = realtime.currentTime; + const pong1 = await ping_for_reply(node1); + const pong2 = await ping_for_reply(node2); + assert_consistent(constructReply1, pong1, timeAfterSuspend, 'node1'); + assert_consistent(constructReply2, pong2, timeAfterSuspend, 'node2'); + assert_equals(pong1.currentFrame, pong2.currentFrame, 'currentFrame matches'); }); </script> diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/capture_screenshot/frame.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/capture_screenshot/frame_tentative.py index bab97a31d20..bab97a31d20 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/capture_screenshot/frame.py +++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/capture_screenshot/frame_tentative.py diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/context.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/context.py index f8074b71b43..2530eedb1b3 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/context.py +++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/context.py @@ -3,7 +3,7 @@ import pytest pytestmark = pytest.mark.asyncio -async def test_context(bidi_session, top_context, inline, assert_pdf_content): +async def test_context_with_frame(bidi_session, top_context, inline, assert_pdf_content): text = "Test" url = inline(text) await bidi_session.browsing_context.navigate( @@ -13,49 +13,3 @@ async def test_context(bidi_session, top_context, inline, assert_pdf_content): value = await bidi_session.browsing_context.print(context=top_context["context"]) await assert_pdf_content(value, [{"type": "string", "value": text}]) - - -async def test_page_with_iframe( - bidi_session, top_context, inline, iframe, assert_pdf_content -): - text = "Test" - iframe_content = "Iframe" - url = inline(f"{text}<br/>{iframe(iframe_content)}") - await bidi_session.browsing_context.navigate( - context=top_context["context"], url=url, wait="complete" - ) - - whole_page_value = await bidi_session.browsing_context.print( - context=top_context["context"] - ) - - await assert_pdf_content( - whole_page_value, [{"type": "string", "value": text + iframe_content}] - ) - - contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"]) - frame_context = contexts[0]["children"][0] - - frame_value = await bidi_session.browsing_context.print( - context=frame_context["context"] - ) - - await assert_pdf_content(frame_value, [{"type": "string", "value": iframe_content}]) - - -@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"]) -async def test_context_origin( - bidi_session, top_context, inline, iframe, assert_pdf_content, domain -): - iframe_content = "Iframe" - url = inline(f"{iframe(iframe_content, domain=domain)}") - await bidi_session.browsing_context.navigate( - context=top_context["context"], url=url, wait="complete" - ) - - contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"]) - frame_context = contexts[0]["children"][0] - - value = await bidi_session.browsing_context.print(context=frame_context["context"]) - - await assert_pdf_content(value, [{"type": "string", "value": iframe_content}]) diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/frame_tentative.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/frame_tentative.py new file mode 100644 index 00000000000..98972d86245 --- /dev/null +++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/print/frame_tentative.py @@ -0,0 +1,49 @@ +import pytest + +pytestmark = pytest.mark.asyncio + + +async def test_iframe( + bidi_session, top_context, inline, iframe, assert_pdf_content +): + text = "Test" + iframe_content = "Iframe" + url = inline(f"{text}<br/>{iframe(iframe_content)}") + await bidi_session.browsing_context.navigate( + context=top_context["context"], url=url, wait="complete" + ) + + whole_page_value = await bidi_session.browsing_context.print( + context=top_context["context"] + ) + + await assert_pdf_content( + whole_page_value, [{"type": "string", "value": text + iframe_content}] + ) + + contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"]) + frame_context = contexts[0]["children"][0] + + frame_value = await bidi_session.browsing_context.print( + context=frame_context["context"] + ) + + await assert_pdf_content(frame_value, [{"type": "string", "value": iframe_content}]) + + +@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"]) +async def test_iframe_origin( + bidi_session, top_context, inline, iframe, assert_pdf_content, domain +): + iframe_content = "Iframe" + url = inline(f"{iframe(iframe_content, domain=domain)}") + await bidi_session.browsing_context.navigate( + context=top_context["context"], url=url, wait="complete" + ) + + contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"]) + frame_context = contexts[0]["children"][0] + + value = await bidi_session.browsing_context.print(context=frame_context["context"]) + + await assert_pdf_content(value, [{"type": "string", "value": iframe_content}]) diff --git a/tests/wpt/tests/webdriver/tests/bidi/network/__init__.py b/tests/wpt/tests/webdriver/tests/bidi/network/__init__.py index 0c3338362d3..5decb28a1a9 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/network/__init__.py +++ b/tests/wpt/tests/webdriver/tests/bidi/network/__init__.py @@ -1,3 +1,4 @@ +import base64 import random import urllib from datetime import datetime, timedelta, timezone @@ -388,6 +389,8 @@ PAGE_REDIRECT_HTTP_EQUIV = ( PAGE_REDIRECTED_HTML = "/webdriver/tests/bidi/network/support/redirected.html" PAGE_SERVICEWORKER_HTML = "/webdriver/tests/bidi/network/support/serviceworker.html" +IMAGE_RESPONSE_BODY = urllib.parse.quote_plus(base64.b64decode(b"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==")) + SCRIPT_CONSOLE_LOG = urllib.parse.quote_plus("console.log('test')") SCRIPT_CONSOLE_LOG_IN_MODULE = urllib.parse.quote_plus("export default function foo() { console.log('from module') }") diff --git a/tests/wpt/tests/webdriver/tests/bidi/network/before_request_sent/before_request_sent_cached.py b/tests/wpt/tests/webdriver/tests/bidi/network/before_request_sent/before_request_sent_cached.py index 4177d316c51..a042e7510b4 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/network/before_request_sent/before_request_sent_cached.py +++ b/tests/wpt/tests/webdriver/tests/bidi/network/before_request_sent/before_request_sent_cached.py @@ -7,6 +7,7 @@ from .. import ( assert_before_request_sent_event, get_cached_url, BEFORE_REQUEST_SENT_EVENT, + IMAGE_RESPONSE_BODY, SCRIPT_CONSOLE_LOG, SCRIPT_CONSOLE_LOG_IN_MODULE, STYLESHEET_GREY_BACKGROUND, @@ -496,3 +497,66 @@ async def tst_page_with_cached_javascript_module( cached_events[1], expected_request={"method": "GET", "url": cached_js_module_url}, ) + + +@pytest.mark.asyncio +async def test_page_with_cached_image( + bidi_session, + url, + inline, + setup_network_test, + top_context, +): + network_events = await setup_network_test( + events=[ + BEFORE_REQUEST_SENT_EVENT, + ] + ) + events = network_events[BEFORE_REQUEST_SENT_EVENT] + + cached_image_url = url(get_cached_url("img/png", IMAGE_RESPONSE_BODY)) + page_with_cached_image = inline( + f""" + <body> + test page with cached image + <img src="{cached_image_url}"> + </body> + """, + ) + + await bidi_session.browsing_context.navigate( + context=top_context["context"], + url=page_with_cached_image, + wait="complete", + ) + + # Expect two events, one for the document and one for the image. + wait = AsyncPoll(bidi_session, timeout=2) + await wait.until(lambda _: len(events) >= 2) + assert len(events) == 2 + + assert_before_request_sent_event( + events[0], + expected_request={"method": "GET", "url": page_with_cached_image}, + ) + assert_before_request_sent_event( + events[1], + expected_request={"method": "GET", "url": cached_image_url}, + ) + + # Reload the page. + await bidi_session.browsing_context.reload(context=top_context["context"]) + + # Expect two events, one for the document and one for the image. + wait = AsyncPoll(bidi_session, timeout=2) + await wait.until(lambda _: len(events) >= 4) + assert len(events) == 4 + + assert_before_request_sent_event( + events[2], + expected_request={"method": "GET", "url": page_with_cached_image}, + ) + assert_before_request_sent_event( + events[3], + expected_request={"method": "GET", "url": cached_image_url}, + ) diff --git a/tests/wpt/tests/webdriver/tests/bidi/network/response_completed/response_completed_cached.py b/tests/wpt/tests/webdriver/tests/bidi/network/response_completed/response_completed_cached.py index dac13abf61b..0a624dcfaed 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/network/response_completed/response_completed_cached.py +++ b/tests/wpt/tests/webdriver/tests/bidi/network/response_completed/response_completed_cached.py @@ -6,6 +6,7 @@ from tests.support.sync import AsyncPoll from .. import ( assert_response_event, get_cached_url, + IMAGE_RESPONSE_BODY, PAGE_EMPTY_TEXT, RESPONSE_COMPLETED_EVENT, SCRIPT_CONSOLE_LOG, @@ -665,3 +666,70 @@ async def test_page_with_cached_javascript_module( expected_request={"method": "GET", "url": cached_js_module_url}, expected_response={"url": cached_js_module_url, "fromCache": True}, ) + + +@pytest.mark.asyncio +async def test_page_with_cached_image( + bidi_session, + url, + inline, + setup_network_test, + top_context, +): + network_events = await setup_network_test( + events=[ + RESPONSE_COMPLETED_EVENT, + ] + ) + events = network_events[RESPONSE_COMPLETED_EVENT] + + cached_image_url = url(get_cached_url("img/png", IMAGE_RESPONSE_BODY)) + page_with_cached_image = inline( + f""" + <body> + test page with cached image + <img src="{cached_image_url}"> + </body> + """, + ) + + await bidi_session.browsing_context.navigate( + context=top_context["context"], + url=page_with_cached_image, + wait="complete", + ) + + # Expect two events, one for the document and one for the image. + wait = AsyncPoll(bidi_session, timeout=2) + await wait.until(lambda _: len(events) >= 2) + assert len(events) == 2 + + assert_response_event( + events[0], + expected_request={"method": "GET", "url": page_with_cached_image}, + expected_response={"url": page_with_cached_image, "fromCache": False}, + ) + assert_response_event( + events[1], + expected_request={"method": "GET", "url": cached_image_url}, + expected_response={"url": cached_image_url, "fromCache": False}, + ) + + # Reload the page. + await bidi_session.browsing_context.reload(context=top_context["context"]) + + # Expect two events, one for the document and one for the image. + wait = AsyncPoll(bidi_session, timeout=2) + await wait.until(lambda _: len(events) >= 4) + assert len(events) == 4 + + assert_response_event( + events[2], + expected_request={"method": "GET", "url": page_with_cached_image}, + expected_response={"url": page_with_cached_image, "fromCache": False}, + ) + assert_response_event( + events[3], + expected_request={"method": "GET", "url": cached_image_url}, + expected_response={"url": cached_image_url, "fromCache": True}, + ) diff --git a/tests/wpt/tests/webdriver/tests/bidi/network/response_started/response_started_cached.py b/tests/wpt/tests/webdriver/tests/bidi/network/response_started/response_started_cached.py index ccb7a97300d..db0a2514c93 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/network/response_started/response_started_cached.py +++ b/tests/wpt/tests/webdriver/tests/bidi/network/response_started/response_started_cached.py @@ -6,6 +6,7 @@ from tests.support.sync import AsyncPoll from .. import ( assert_response_event, get_cached_url, + IMAGE_RESPONSE_BODY, PAGE_EMPTY_TEXT, RESPONSE_STARTED_EVENT, SCRIPT_CONSOLE_LOG, @@ -677,3 +678,70 @@ async def test_page_with_cached_javascript_module( expected_request={"method": "GET", "url": cached_js_module_url}, expected_response={"url": cached_js_module_url, "fromCache": True}, ) + + +@pytest.mark.asyncio +async def test_page_with_cached_image( + bidi_session, + url, + inline, + setup_network_test, + top_context, +): + network_events = await setup_network_test( + events=[ + RESPONSE_STARTED_EVENT, + ] + ) + events = network_events[RESPONSE_STARTED_EVENT] + + cached_image_url = url(get_cached_url("img/png", IMAGE_RESPONSE_BODY)) + page_with_cached_image = inline( + f""" + <body> + test page with cached image + <img src="{cached_image_url}"> + </body> + """, + ) + + await bidi_session.browsing_context.navigate( + context=top_context["context"], + url=page_with_cached_image, + wait="complete", + ) + + # Expect two events, one for the document and one for the image. + wait = AsyncPoll(bidi_session, timeout=2) + await wait.until(lambda _: len(events) >= 2) + assert len(events) == 2 + + assert_response_event( + events[0], + expected_request={"method": "GET", "url": page_with_cached_image}, + expected_response={"url": page_with_cached_image, "fromCache": False}, + ) + assert_response_event( + events[1], + expected_request={"method": "GET", "url": cached_image_url}, + expected_response={"url": cached_image_url, "fromCache": False}, + ) + + # Reload the page. + await bidi_session.browsing_context.reload(context=top_context["context"]) + + # Expect two events, one for the document and one for the image. + wait = AsyncPoll(bidi_session, timeout=2) + await wait.until(lambda _: len(events) >= 4) + assert len(events) == 4 + + assert_response_event( + events[2], + expected_request={"method": "GET", "url": page_with_cached_image}, + expected_response={"url": page_with_cached_image, "fromCache": False}, + ) + assert_response_event( + events[3], + expected_request={"method": "GET", "url": cached_image_url}, + expected_response={"url": cached_image_url, "fromCache": True}, + ) diff --git a/tests/wpt/tests/webnn/conformance_tests/byob_readtensor.https.any.js b/tests/wpt/tests/webnn/conformance_tests/byob_readtensor.https.any.js index b99c8704d23..f43cca0ea4e 100644 --- a/tests/wpt/tests/webnn/conformance_tests/byob_readtensor.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/byob_readtensor.https.any.js @@ -32,7 +32,8 @@ promise_setup(async () => { mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [2, 4], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }); } catch (e) { throw new AssertionError( @@ -141,7 +142,7 @@ promise_test(async (t) => { const tensor = await mlContext.createTensor({ dataType: 'int32', shape: [2, 2], - usage: MLTensorUsage.READ, + readable: true, }); const arrayBufferView = new Int32Array(2 * 2); const arrayBuffer = arrayBufferView.buffer; @@ -159,7 +160,7 @@ promise_test(async (t) => { const tensor = await mlContext.createTensor({ dataType: 'int32', shape: [2, 2], - usage: MLTensorUsage.READ, + readable: true, }); const arrayBufferView = new Int32Array(2 * 2); const arrayBuffer = arrayBufferView.buffer; diff --git a/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js b/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js index c6acb042a24..8a04d0e6b8a 100644 --- a/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js @@ -147,6 +147,197 @@ const dequantizeLinearTests = [ } } } + }, + { + 'name': 'dequantizeLinear uint4 1D tensor with even input size', + 'graph': { + 'inputs': { + 'dequantizeLinearInput': { + 'data': [15, 0], + 'descriptor': {shape: [2], dataType: 'uint4'}, + 'constant': true + }, + 'dequantizeLinearScale': { + 'data': [1.1202747821807861, 1.1202747821807861], + 'descriptor': {shape: [2], dataType: 'float32'}, + 'constant': true + }, + 'dequantizeLinearZeroPoint': { + 'data': [0], + 'descriptor': {shape: [], dataType: 'uint4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'dequantizeLinearInput'}, + {'scale': 'dequantizeLinearScale'}, + {'zeroPoint': 'dequantizeLinearZeroPoint'} + ], + 'outputs': 'dequantizeLinearOutput' + }], + 'expectedOutputs': { + 'dequantizeLinearOutput': { + 'data': [16.804121017456055, 0], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'dequantizeLinear uint4 1D tensor with odd input size', + 'graph': { + 'inputs': { + 'dequantizeLinearInput': { + 'data': [10, 12, 14], + 'descriptor': {shape: [3], dataType: 'uint4'}, + 'constant': true + }, + 'dequantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'dequantizeLinearZeroPoint': { + 'data': [2, 1, 4], + 'descriptor': {shape: [3], dataType: 'uint4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'dequantizeLinearInput'}, + {'scale': 'dequantizeLinearScale'}, + {'zeroPoint': 'dequantizeLinearZeroPoint'} + ], + 'outputs': 'dequantizeLinearOutput' + }], + 'expectedOutputs': { + 'dequantizeLinearOutput': { + 'data': [8.962198257446289, 12.323022842407227, 11.202747344970703], + 'descriptor': {shape: [3], dataType: 'float32'} + } + } + } + }, + { + 'name': 'dequantizeLinear uint4 4D constant tensor broadcasting zeroPoint', + 'graph': { + 'inputs': { + 'dequantizeLinearInput': { + 'data': [0, 1, 10, 15], + 'descriptor': {shape: [1, 1, 2, 2], dataType: 'uint4'}, + 'constant': true + }, + 'dequantizeLinearScale': { + 'data': [ + 9.343092918395996, + -4.617084980010986, + ], + 'descriptor': {shape: [2, 1], dataType: 'float32'}, + 'constant': true + }, + 'dequantizeLinearZeroPoint': { + 'data': [2, 3], + 'descriptor': {shape: [2], dataType: 'uint4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'dequantizeLinearInput'}, + {'scale': 'dequantizeLinearScale'}, + {'zeroPoint': 'dequantizeLinearZeroPoint'} + ], + 'outputs': 'dequantizeLinearOutput' + }], + 'expectedOutputs': { + 'dequantizeLinearOutput': { + 'data': [ + -18.686185836791992, -18.686185836791992, -36.93667984008789, + -55.40502166748047 + ], + 'descriptor': {shape: [1, 1, 2, 2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'dequantizeLinear int4 1D tensor with even size', + 'graph': { + 'inputs': { + 'dequantizeLinearInput': { + 'data': [-8, -3], + 'descriptor': {shape: [2], dataType: 'int4'}, + 'constant': true + }, + 'dequantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'dequantizeLinearZeroPoint': { + 'data': [0, -2], + 'descriptor': {shape: [2], dataType: 'int4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'dequantizeLinearInput'}, + {'scale': 'dequantizeLinearScale'}, + {'zeroPoint': 'dequantizeLinearZeroPoint'} + ], + 'outputs': 'dequantizeLinearOutput' + }], + 'expectedOutputs': { + 'dequantizeLinearOutput': { + 'data': [-8.962198257446289, -1.1202747821807861], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'dequantizeLinear int4 1D tensor with odd size', + 'graph': { + 'inputs': { + 'dequantizeLinearInput': { + 'data': [-1, 7, 0], + 'descriptor': {shape: [3], dataType: 'int4'}, + 'constant': true + }, + 'dequantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'dequantizeLinearZeroPoint': { + 'data': [-3, 0, 0], + 'descriptor': {shape: [3], dataType: 'int4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'dequantizeLinearInput'}, + {'scale': 'dequantizeLinearScale'}, + {'zeroPoint': 'dequantizeLinearZeroPoint'} + ], + 'outputs': 'dequantizeLinearOutput' + }], + 'expectedOutputs': { + 'dequantizeLinearOutput': { + 'data': [2.2405495643615723, 7.841923713684082, 0], + 'descriptor': {shape: [3], dataType: 'float32'} + } + } + } } ]; diff --git a/tests/wpt/tests/webnn/conformance_tests/gather.https.any.js b/tests/wpt/tests/webnn/conformance_tests/gather.https.any.js index 3cdd411ecb3..17c31413758 100644 --- a/tests/wpt/tests/webnn/conformance_tests/gather.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/gather.https.any.js @@ -67,7 +67,7 @@ const gatherTests = [ }, { 'name': - 'gather float32 1D tensor and int32 0D scalar indices default options', + 'gather float32 1D tensor and int64 0D scalar indices default options', 'graph': { 'inputs': { 'gatherInput': { @@ -85,7 +85,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [4], - 'descriptor': {shape: [], dataType: 'int32'}, + 'descriptor': {shape: [], dataType: 'int64'}, 'constant': true } }, @@ -104,7 +104,7 @@ const gatherTests = [ }, { 'name': - 'gather float32 1D tensor and int64 0D scalar indices default options', + 'gather float32 1D tensor and int32 0D scalar indices default options', 'graph': { 'inputs': { 'gatherInput': { @@ -121,8 +121,8 @@ const gatherTests = [ 'descriptor': {shape: [24], dataType: 'float32'} }, 'gatherIndices': { - 'data': [0], - 'descriptor': {shape: [], dataType: 'int64'}, + 'data': [4], + 'descriptor': {shape: [], dataType: 'int32'}, 'constant': true } }, @@ -133,14 +133,14 @@ const gatherTests = [ }], 'expectedOutputs': { 'gatherOutput': { - 'data': [-66.05901336669922], + 'data': [89.0337142944336], 'descriptor': {shape: [], dataType: 'float32'} } } } }, { - 'name': 'gather float32 1D tensor and int64 1D indices default options', + 'name': 'gather float32 1D tensor and int32 1D indices default options', 'graph': { 'inputs': { 'gatherInput': { @@ -158,7 +158,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [16, 20, 6, 11, 17, 19, 13, 17], - 'descriptor': {shape: [8], dataType: 'int64'}, + 'descriptor': {shape: [8], dataType: 'int32'}, 'constant': true } }, @@ -180,7 +180,7 @@ const gatherTests = [ } }, { - 'name': 'gather float32 1D tensor and int64 2D indices default options', + 'name': 'gather float32 1D tensor and int32 2D indices default options', 'graph': { 'inputs': { 'gatherInput': { @@ -198,7 +198,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [14, 9, 21, 17], - 'descriptor': {shape: [2, 2], dataType: 'int64'}, + 'descriptor': {shape: [2, 2], dataType: 'int32'}, 'constant': true } }, @@ -219,7 +219,7 @@ const gatherTests = [ } }, { - 'name': 'gather float32 1D tensor and int64 3D indices default options', + 'name': 'gather float32 1D tensor and int32 3D indices default options', 'graph': { 'inputs': { 'gatherInput': { @@ -238,7 +238,7 @@ const gatherTests = [ 'gatherIndices': { 'data': [17, 19, 14, 16, 13, 0, 5, 15, 18, 18, 6, 20, 7, 22, 5, 1, 4, 19], - 'descriptor': {shape: [2, 3, 3], dataType: 'int64'}, + 'descriptor': {shape: [2, 3, 3], dataType: 'int32'}, 'constant': true } }, @@ -263,7 +263,7 @@ const gatherTests = [ } }, { - 'name': 'gather float32 1D tensor and int64 4D indices default options', + 'name': 'gather float32 1D tensor and int32 4D indices default options', 'graph': { 'inputs': { 'gatherInput': { @@ -281,7 +281,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [18, 18, 22, 11, 8, 15, 12, 11, 7, 13, 7, 7], - 'descriptor': {shape: [1, 2, 2, 3], dataType: 'int64'}, + 'descriptor': {shape: [1, 2, 2, 3], dataType: 'int32'}, 'constant': true } }, @@ -322,7 +322,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [11], - 'descriptor': {shape: [], dataType: 'int64'}, + 'descriptor': {shape: [], dataType: 'int32'}, 'constant': true } }, @@ -358,7 +358,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [1, 10, 9, 0, 3, 5, 3, 8], - 'descriptor': {shape: [8], dataType: 'int64'}, + 'descriptor': {shape: [8], dataType: 'int32'}, 'constant': true } }, @@ -401,7 +401,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [4, 8, 9, 10], - 'descriptor': {shape: [2, 2], dataType: 'int64'}, + 'descriptor': {shape: [2, 2], dataType: 'int32'}, 'constant': true } }, @@ -441,7 +441,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [8, 2, 2, 3, 4, 1, 2, 2, 7, 11, 4, 11, 6, 6, 7, 3, 11, 10], - 'descriptor': {shape: [2, 3, 3], dataType: 'int64'}, + 'descriptor': {shape: [2, 3, 3], dataType: 'int32'}, 'constant': true } }, @@ -490,7 +490,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [6, 9, 7, 3, 4, 7, 4, 3, 7, 7, 6, 0], - 'descriptor': {shape: [1, 2, 2, 3], dataType: 'int64'}, + 'descriptor': {shape: [1, 2, 2, 3], dataType: 'int32'}, 'constant': true } }, @@ -535,7 +535,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [2, 1, 1, 1], - 'descriptor': {shape: [2, 2], dataType: 'int64'}, + 'descriptor': {shape: [2, 2], dataType: 'int32'}, 'constant': true } }, @@ -583,7 +583,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [0, 0, 7, 4], - 'descriptor': {shape: [2, 2], dataType: 'int64'}, + 'descriptor': {shape: [2, 2], dataType: 'int32'}, 'constant': true } }, @@ -624,7 +624,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [3, 2, 2], - 'descriptor': {shape: [3], dataType: 'int64'}, + 'descriptor': {shape: [3], dataType: 'int32'}, 'constant': true } }, @@ -667,7 +667,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [1, 1, 2], - 'descriptor': {shape: [3], dataType: 'int64'}, + 'descriptor': {shape: [3], dataType: 'int32'}, 'constant': true } }, @@ -713,7 +713,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [0, 0, 0, 1], - 'descriptor': {shape: [2, 2], dataType: 'int64'}, + 'descriptor': {shape: [2, 2], dataType: 'int32'}, 'constant': true } }, @@ -769,7 +769,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [0, 0, 7, 4], - 'descriptor': {shape: [2, 2], dataType: 'int64'}, + 'descriptor': {shape: [2, 2], dataType: 'int32'}, 'constant': true } }, @@ -813,7 +813,7 @@ const gatherTests = [ }, 'gatherIndices': { 'data': [1], - 'descriptor': {shape: [], dataType: 'int64'}, + 'descriptor': {shape: [], dataType: 'int32'}, 'constant': true } }, diff --git a/tests/wpt/tests/webnn/conformance_tests/gatherND.https.any.js b/tests/wpt/tests/webnn/conformance_tests/gatherND.https.any.js index e8f31d5617b..b40507d2dce 100644 --- a/tests/wpt/tests/webnn/conformance_tests/gatherND.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/gatherND.https.any.js @@ -63,7 +63,7 @@ const gatherNDTests = [ } }, { - 'name': 'gatherND float32 4D input and 1D indices', + 'name': 'gatherND float32 4D input and 1D int32 indices', 'graph': { 'inputs': { 'gatherNDInput': { @@ -98,6 +98,146 @@ const gatherNDTests = [ } }, { + 'name': 'gatherND float32 4D input and 1D uint32 indices', + 'graph': { + 'inputs': { + 'gatherNDInput': { + 'data': [ + -66.05901336669922, -68.9197006225586, -77.02045440673828, + -26.158037185668945, 89.0337142944336, -45.89653396606445, + 43.84803771972656, 48.81806945800781, 51.79948425292969, + 41.94132614135742, -1.1303654909133911, -50.42131042480469, + 90.2870101928711, 55.620765686035156, 44.92119598388672, + 56.828636169433594 + ], + 'descriptor': {shape: [2, 2, 2, 2], dataType: 'float32'} + }, + 'gatherNDIndices': { + 'data': [1, 0, 0], + 'descriptor': {shape: [3], dataType: 'uint32'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'gatherND', + 'arguments': + [{'input': 'gatherNDInput'}, {'indices': 'gatherNDIndices'}], + 'outputs': 'gatherNDOutput' + }], + 'expectedOutputs': { + 'gatherNDOutput': { + 'data': [51.79948425292969, 41.94132614135742], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'gatherND float32 4D input and 1D int64 indices', + 'graph': { + 'inputs': { + 'gatherNDInput': { + 'data': [ + -66.05901336669922, -68.9197006225586, -77.02045440673828, + -26.158037185668945, 89.0337142944336, -45.89653396606445, + 43.84803771972656, 48.81806945800781, 51.79948425292969, + 41.94132614135742, -1.1303654909133911, -50.42131042480469, + 90.2870101928711, 55.620765686035156, 44.92119598388672, + 56.828636169433594 + ], + 'descriptor': {shape: [2, 2, 2, 2], dataType: 'float32'} + }, + 'gatherNDIndices': { + 'data': [1, 0, 0], + 'descriptor': {shape: [3], dataType: 'int64'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'gatherND', + 'arguments': + [{'input': 'gatherNDInput'}, {'indices': 'gatherNDIndices'}], + 'outputs': 'gatherNDOutput' + }], + 'expectedOutputs': { + 'gatherNDOutput': { + 'data': [51.79948425292969, 41.94132614135742], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'gatherND float32 4D input and 1D minimum indices', + 'graph': { + 'inputs': { + 'gatherNDInput': { + 'data': [ + -66.05901336669922, -68.9197006225586, -77.02045440673828, + -26.158037185668945, 89.0337142944336, -45.89653396606445, + 43.84803771972656, 48.81806945800781, 51.79948425292969, + 41.94132614135742, -1.1303654909133911, -50.42131042480469, + 90.2870101928711, 55.620765686035156, 44.92119598388672, + 56.828636169433594 + ], + 'descriptor': {shape: [2, 2, 2, 2], dataType: 'float32'} + }, + 'gatherNDIndices': { + 'data': [-2, -2, -2], + 'descriptor': {shape: [3], dataType: 'int64'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'gatherND', + 'arguments': + [{'input': 'gatherNDInput'}, {'indices': 'gatherNDIndices'}], + 'outputs': 'gatherNDOutput' + }], + 'expectedOutputs': { + 'gatherNDOutput': { + 'data': [-66.05901336669922, -68.9197006225586], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'gatherND float32 4D input and 1D maximum indices', + 'graph': { + 'inputs': { + 'gatherNDInput': { + 'data': [ + -66.05901336669922, -68.9197006225586, -77.02045440673828, + -26.158037185668945, 89.0337142944336, -45.89653396606445, + 43.84803771972656, 48.81806945800781, 51.79948425292969, + 41.94132614135742, -1.1303654909133911, -50.42131042480469, + 90.2870101928711, 55.620765686035156, 44.92119598388672, + 56.828636169433594 + ], + 'descriptor': {shape: [2, 2, 2, 2], dataType: 'float32'} + }, + 'gatherNDIndices': { + 'data': [1, 1, 1], + 'descriptor': {shape: [3], dataType: 'int64'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'gatherND', + 'arguments': + [{'input': 'gatherNDInput'}, {'indices': 'gatherNDIndices'}], + 'outputs': 'gatherNDOutput' + }], + 'expectedOutputs': { + 'gatherNDOutput': { + 'data': [44.92119598388672, 56.828636169433594], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { 'name': 'gatherND float32 2D input and 2D negative indices', 'graph': { 'inputs': { @@ -169,6 +309,41 @@ const gatherNDTests = [ } } } + }, + { + 'name': 'gatherND float32 2D input and 2D out-of-bounds indices', + 'graph': { + 'inputs': { + 'gatherNDInput': { + 'data': [ + -66.05901336669922, -68.9197006225586, -77.02045440673828, + -26.158037185668945, 89.0337142944336, -45.89653396606445, + 43.84803771972656, 48.81806945800781, 51.79948425292969, + 41.94132614135742, -1.1303654909133911, -50.42131042480469, + 90.2870101928711, 55.620765686035156, 44.92119598388672, + 56.828636169433594 + ], + 'descriptor': {shape: [16, 1], dataType: 'float32'} + }, + 'gatherNDIndices': { + 'data': [16, 20], + 'descriptor': {shape: [2, 1], dataType: 'int32'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'gatherND', + 'arguments': + [{'input': 'gatherNDInput'}, {'indices': 'gatherNDIndices'}], + 'outputs': 'gatherNDOutput' + }], + 'expectedOutputs': { + 'gatherNDOutput': { + 'data': [56.828636169433594, 56.828636169433594], + 'descriptor': {shape: [2, 1], dataType: 'float32'} + } + } + } } ]; diff --git a/tests/wpt/tests/webnn/conformance_tests/inputs-are-not-modified.https.any.js b/tests/wpt/tests/webnn/conformance_tests/inputs-are-not-modified.https.any.js index ffd2d93a557..730941fbd8b 100644 --- a/tests/wpt/tests/webnn/conformance_tests/inputs-are-not-modified.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/inputs-are-not-modified.https.any.js @@ -31,10 +31,10 @@ promise_test(async () => { mlContext.createTensor({ dataType: 'float32', shape: [4], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ + readable: true, + writable: true, }), - mlContext.createTensor( - {dataType: 'float32', shape: [4], usage: MLTensorUsage.READ}), + mlContext.createTensor({dataType: 'float32', shape: [4], readable: true}), builder.build({'output': outputOperand}) ]); @@ -66,10 +66,10 @@ promise_test(async () => { mlContext.createTensor({ dataType: 'float32', shape: [4], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ + readable: true, + writable: true, }), - mlContext.createTensor( - {dataType: 'float32', shape: [4], usage: MLTensorUsage.READ}), + mlContext.createTensor({dataType: 'float32', shape: [4], readable: true}), builder.build({'output': outputOperand}) ]); diff --git a/tests/wpt/tests/webnn/conformance_tests/logical_and.https.any.js b/tests/wpt/tests/webnn/conformance_tests/logical_and.https.any.js index be379de157c..3d46c0b2406 100644 --- a/tests/wpt/tests/webnn/conformance_tests/logical_and.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/logical_and.https.any.js @@ -370,8 +370,8 @@ const logicalAndTests = [ 'expectedOutputs': { 'output': { 'data': [ - 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, - 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1 ], 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} } diff --git a/tests/wpt/tests/webnn/conformance_tests/logical_or.https.any.js b/tests/wpt/tests/webnn/conformance_tests/logical_or.https.any.js index f5eb21de729..3be3b0090f2 100644 --- a/tests/wpt/tests/webnn/conformance_tests/logical_or.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/logical_or.https.any.js @@ -370,8 +370,8 @@ const logicalOrTests = [ 'expectedOutputs': { 'output': { 'data': [ - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 ], 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} } diff --git a/tests/wpt/tests/webnn/conformance_tests/logical_xor.https.any.js b/tests/wpt/tests/webnn/conformance_tests/logical_xor.https.any.js index b678b04065b..cab96c27237 100644 --- a/tests/wpt/tests/webnn/conformance_tests/logical_xor.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/logical_xor.https.any.js @@ -20,7 +20,7 @@ const logicalXorTests = [ 'descriptor': {shape: [], dataType: 'uint8'} }, 'inputB': { - 'data': [1], + 'data': [0], 'descriptor': {shape: [], dataType: 'uint8'} } }, @@ -370,8 +370,8 @@ const logicalXorTests = [ 'expectedOutputs': { 'output': { 'data': [ - 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0 ], 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} } diff --git a/tests/wpt/tests/webnn/conformance_tests/parallel-dispatch.https.any.js b/tests/wpt/tests/webnn/conformance_tests/parallel-dispatch.https.any.js index dfdf70a6aa4..4051645771f 100644 --- a/tests/wpt/tests/webnn/conformance_tests/parallel-dispatch.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/parallel-dispatch.https.any.js @@ -33,7 +33,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const [mlGraph, inputTensor1, inputTensor2, outputTensor] = @@ -73,7 +74,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const mlGraph = await buildMulGraph(mlContext, operandDescriptor, 3); @@ -101,7 +103,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const mlGraph = await buildMulGraph(mlContext, operandDescriptor, 10); @@ -140,7 +143,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const mlGraph = await buildMulGraph(mlContext, operandDescriptor, 9); @@ -178,7 +182,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const mlGraph = await buildMulGraph(mlContext, operandDescriptor, 2); @@ -211,7 +216,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; // write/write... @@ -250,7 +256,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; // write/write... @@ -288,7 +295,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const graphs = await Promise.all([3, 2].map(async (multiplier) => { @@ -324,7 +332,8 @@ promise_test(async () => { const operandDescriptor = { dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const graphs = await Promise.all([2, 3].map(async (multiplier) => { diff --git a/tests/wpt/tests/webnn/conformance_tests/quantizeLinear.https.any.js b/tests/wpt/tests/webnn/conformance_tests/quantizeLinear.https.any.js index 0871c881b71..8aa9d7f3bcc 100644 --- a/tests/wpt/tests/webnn/conformance_tests/quantizeLinear.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/quantizeLinear.https.any.js @@ -18,7 +18,7 @@ const getQuantizeLinearPrecisionTolerance = (graphResources) => { - const toleranceValueDict = {int8: 1, uint8: 1}; + const toleranceValueDict = {int8: 1, uint8: 1, int4: 1, uint4: 1}; const expectedDataType = getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs); return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]}; @@ -143,6 +143,191 @@ const quantizeLinearTests = [ } } } + }, + { + 'name': + 'quantizeLinear float32 tensor with int4 zeroPoint which has odd size', + 'graph': { + 'inputs': { + 'quantizeLinearInput': { + 'data': [4.794857501983643], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearZeroPoint': { + 'data': [-4], + 'descriptor': {shape: [], dataType: 'int4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, + {'zeroPoint': 'quantizeLinearZeroPoint'} + ], + 'outputs': 'quantizeLinearOutput' + }], + 'expectedOutputs': { + 'quantizeLinearOutput': + {'data': [-1], 'descriptor': {shape: [], dataType: 'int4'}} + } + } + }, + { + 'name': + 'quantizeLinear float32 tensor with int4 zeroPoint which has even size', + 'graph': { + 'inputs': { + 'quantizeLinearInput': { + 'data': [4.794857501983643, 3.23434354545], + 'descriptor': {shape: [2], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearZeroPoint': { + 'data': [-6, -5], + 'descriptor': {shape: [2], dataType: 'int4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, + {'zeroPoint': 'quantizeLinearZeroPoint'} + ], + 'outputs': 'quantizeLinearOutput' + }], + 'expectedOutputs': { + 'quantizeLinearOutput': + {'data': [-2, -2], 'descriptor': {shape: [2], dataType: 'int4'}} + } + } + }, + { + 'name': + 'quantizeLinear float32 2D tensor with int4 zeroPoint which has even size', + 'graph': { + 'inputs': { + 'quantizeLinearInput': { + 'data': [ + 4.794857501983643, 3.23434354545, 2.794857501983643, + 5.794857501983643, 0, 7.23434354545 + ], + 'descriptor': {shape: [3, 2], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearScale': { + 'data': [1.1202747821807861, 2.1202747821807861], + 'descriptor': {shape: [2], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearZeroPoint': { + 'data': [-6, -5], + 'descriptor': {shape: [2], dataType: 'int4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, + {'zeroPoint': 'quantizeLinearZeroPoint'} + ], + 'outputs': 'quantizeLinearOutput' + }], + 'expectedOutputs': { + 'quantizeLinearOutput': { + 'data': [-2, -3, -4, -3, -5, -2], + 'descriptor': {shape: [3, 2], dataType: 'int4'} + } + } + } + }, + { + 'name': + 'quantizeLinear float32 tensor with uint4 zeroPoint which has odd size', + 'graph': { + 'inputs': { + 'quantizeLinearInput': { + 'data': [ + 4.794857501983643, 2.794857501983643, 1.794857501983643, 0, + 3.794857501983643 + ], + 'descriptor': {shape: [5], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearZeroPoint': { + 'data': [12], + 'descriptor': {shape: [], dataType: 'uint4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, + {'zeroPoint': 'quantizeLinearZeroPoint'} + ], + 'outputs': 'quantizeLinearOutput' + }], + 'expectedOutputs': { + 'quantizeLinearOutput': { + 'data': [16, 14, 13, 12, 15], + 'descriptor': {shape: [5], dataType: 'uint4'} + } + } + } + }, + { + 'name': + 'quantizeLinear float32 tensor with uint4 zeroPoint which has even size', + 'graph': { + 'inputs': { + 'quantizeLinearInput': { + 'data': [4.794857501983643, 3.23434354545], + 'descriptor': {shape: [2], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearScale': { + 'data': [1.1202747821807861], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + }, + 'quantizeLinearZeroPoint': { + 'data': [1, 5], + 'descriptor': {shape: [2], dataType: 'uint4'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, + {'zeroPoint': 'quantizeLinearZeroPoint'} + ], + 'outputs': 'quantizeLinearOutput' + }], + 'expectedOutputs': { + 'quantizeLinearOutput': + {'data': [5, 8], 'descriptor': {shape: [2], dataType: 'uint4'}} + } + } } ]; diff --git a/tests/wpt/tests/webnn/conformance_tests/scatterElements.https.any.js b/tests/wpt/tests/webnn/conformance_tests/scatterElements.https.any.js new file mode 100644 index 00000000000..561260d47ec --- /dev/null +++ b/tests/wpt/tests/webnn/conformance_tests/scatterElements.https.any.js @@ -0,0 +1,91 @@ +// META: title=test WebNN API scatterElements operation +// META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu +// META: variant=?npu +// META: script=../resources/utils.js +// META: timeout=long + +'use strict'; + +const getScatterElementsPrecisionTolerance = () => { + return {metricType: 'ULP', value: 0}; +}; + +const scatterElementsTests = [ + { + 'name': 'Scatter elements along axis 0', + 'graph': { + 'inputs': { + 'input': { + 'data': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + 'descriptor': {shape: [3, 3], dataType: 'float32'} + }, + 'indices': { + 'data': [1, 0, 2, 0, 2, 1], + 'descriptor': {shape: [2, 3], dataType: 'int32'}, + }, + 'updates': { + 'data': [1.0, 1.1, 1.2, 2.0, 2.1, 2.2], + 'descriptor': {shape: [2, 3], dataType: 'float32'} + } + }, + 'operators': [{ + 'name': 'scatterElements', + 'arguments': [ + {'input': 'input'}, {'indices': 'indices'}, {'updates': 'updates'}, + {'options': {'axis': 0}} + ], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [2.0, 1.1, 0.0, 1.0, 0.0, 2.2, 0.0, 2.1, 1.2], + 'descriptor': {shape: [3, 3], dataType: 'float32'} + } + } + } + }, + { + 'name': 'Scatter elements along axis 1', + 'graph': { + 'inputs': { + 'input': { + 'data': [1.0, 2.0, 3.0, 4.0, 5.0], + 'descriptor': {shape: [1, 5], dataType: 'float32'} + }, + 'indices': { + 'data': [1, 3], + 'descriptor': {shape: [1, 2], dataType: 'int32'}, + }, + 'updates': { + 'data': [1.1, 2.1], + 'descriptor': {shape: [1, 2], dataType: 'float32'} + } + }, + 'operators': [{ + 'name': 'scatterElements', + 'arguments': [ + {'input': 'input'}, {'indices': 'indices'}, {'updates': 'updates'}, + {'options': {'axis': 1}} + ], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [1.0, 1.1, 3.0, 2.1, 5.0], + 'descriptor': {shape: [1, 5], dataType: 'float32'} + } + } + } + } +]; + +if (navigator.ml) { + scatterElementsTests.forEach((test) => { + webnn_conformance_test( + buildGraphAndCompute, getScatterElementsPrecisionTolerance, test); + }); +} else { + test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/tests/wpt/tests/webnn/conformance_tests/tensor.https.any.js b/tests/wpt/tests/webnn/conformance_tests/tensor.https.any.js index 51905bbaf3c..0bc51614608 100644 --- a/tests/wpt/tests/webnn/conformance_tests/tensor.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/tensor.https.any.js @@ -33,7 +33,13 @@ const sizeOfDescriptor = (descriptor) => { }; const getDescriptorFromTensor = (tensor) => { - return {dataType: tensor.dataType, shape: tensor.shape, usage: tensor.usage}; + return { + dataType: tensor.dataType, + shape: tensor.shape, + readable: tensor.readable, + writable: tensor.writable, + importableToWebGPU: tensor.importableToWebGPU, + }; }; @@ -162,7 +168,7 @@ const testWriteTensor = (testName) => { const tensorDescriptor = { dataType: 'int32', shape: [1], - usage: MLTensorUsage.WRITE, + writable: true, }; let mlTensor = await mlContext.createTensor(tensorDescriptor); @@ -211,7 +217,7 @@ const testWriteTensor = (testName) => { const tensorDescriptor = { dataType: 'int32', shape: [2, 2], - usage: MLTensorUsage.WRITE, + writable: true, }; let mlTensor = await mlContext.createTensor(tensorDescriptor); @@ -228,7 +234,7 @@ const testWriteTensor = (testName) => { const tensorDescriptor = { dataType: 'int32', shape: [2, 3], - usage: MLTensorUsage.WRITE, + writable: true, }; let mlTensor = await mlContext.createTensor(tensorDescriptor); @@ -247,7 +253,8 @@ const testWriteTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }); // Initialize the tensor. @@ -270,7 +277,8 @@ const testWriteTensor = (testName) => { const tensorDescriptor = { dataType: 'int32', shape: [2, 2], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; let mlTensor = await mlContext.createTensor(tensorDescriptor); @@ -321,7 +329,7 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [2, 2], - usage: MLTensorUsage.READ, + readable: true, }); // Reading a destroyed MLTensor should reject. @@ -335,7 +343,7 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [2, 3], - usage: MLTensorUsage.READ, + readable: true, }); let promise = mlContext.readTensor(mlTensor); @@ -351,7 +359,7 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1024], - usage: MLTensorUsage.READ, + readable: true, }); await assert_tensor_data_equals(mlContext, mlTensor, new Uint32Array(1024)); @@ -361,7 +369,8 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1], - usage: MLTensorUsage.READ | MLTensorUsage.WRITE, + readable: true, + writable: true, }); // Initialize the tensor. @@ -377,7 +386,8 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }); // Initialize the tensor. @@ -395,7 +405,8 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }); // Initialize the tensor. @@ -413,7 +424,8 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }); // Initialize the tensor. @@ -431,7 +443,8 @@ const testReadTensor = (testName) => { let mlTensor = await mlContext.createTensor({ dataType: 'int32', shape: [1], - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }); const inputData = [0xAA, 0xAA, 0xAA, 0xAA]; @@ -448,7 +461,7 @@ const testReadTensor = (testName) => { const tensorDescriptor = { dataType: 'int32', shape: [2, 3], - usage: MLTensorUsage.READ, + readable: true, }; let mlTensor = await mlContext.createTensor(tensorDescriptor); @@ -484,7 +497,8 @@ const testDispatchTensor = (testName) => { const tensorDescriptor = { dataType: 'float32', shape: shape, - usage: MLTensorUsage.WRITE | MLTensorUsage.READ, + readable: true, + writable: true, }; const lhsOperand = builder.input('lhs', tensorDescriptor); const rhsOperand = builder.input('rhs', tensorDescriptor); diff --git a/tests/wpt/tests/webnn/resources/utils.js b/tests/wpt/tests/webnn/resources/utils.js index 460fe461154..973c16baca7 100644 --- a/tests/wpt/tests/webnn/resources/utils.js +++ b/tests/wpt/tests/webnn/resources/utils.js @@ -85,9 +85,12 @@ const TypedArrayDict = { uint32: Uint32Array, int8: Int8Array, uint8: Uint8Array, + int4: Uint8Array, + uint4: Uint8Array, }; -const kIntTypes = ['uint8', 'int8', 'uint32', 'int32', 'uint64', 'int64']; +const kIntTypes = + ['uint4', 'int4', 'uint8', 'int8', 'uint32', 'int32', 'uint64', 'int64']; const kFloatTypes = ['float16', 'float32']; const findCompatibleType = (dataType, supportedTypes) => { @@ -204,6 +207,27 @@ const getTypedArrayData = (type, size, data) => { for (let i = 0; i < data.length; i++) { outData[i] = BigInt(data[i]); } + } else if (type === 'uint4' || type === 'int4') { + // The first nybble is stored in the first bits 0-3, and later bits 4-7 + // store the later nybble. The data is packed, without any padding between + // dimensions. For example: an array of uint4: + // size = [2,5] + // values = [1,2,3,4,5,6,7,8,9,10] + // Would yield 5 hex bytes: + // Uint8Array.of(0x21, 0x43, 0x65, 0x87, 0xA9); + const array = new TypedArrayDict[type](Math.ceil(size / 2)); + let i = 0; + while (i < size - 1) { + const packedByte = ((data[i + 1] & 0xF) << 4) | (data[i] & 0xF); + array[Math.floor(i / 2)] = packedByte; + i = i + 2; + } + // Handle the odd size. + if (i === size - 1) { + const packedByte = data[i] & 0xF; + array[Math.floor(i / 2)] = packedByte; + } + return array; } else { if (typeof (data) === 'number' && size > 1) { return new TypedArrayDict[type](size).fill(data); @@ -282,7 +306,8 @@ const assert_array_approx_equals_ulp = (actual, expected, nulp, dataType, descri expectedBitwise = BigUint64Array(expected[i]); } else if ( dataType === 'int8' || dataType === 'uint8' || dataType === 'int32' || - dataType === 'uint32') { + dataType === 'uint32' || dataType === 'int4' || + dataType === 'uint4') { actualBitwise = actual[i]; expectedBitwise = expected[i]; } @@ -365,6 +390,44 @@ const assertResultsEquals = kMaximumIndexToValidate, sizeOfShape(expectedDescriptor.shape)); expectedData = new Array(size).fill(expectedData); outputData = outputData.subarray(0, kMaximumIndexToValidate); + } else if ( + expectedDescriptor.dataType === 'uint4' || + expectedDescriptor.dataType === 'int4') { + // The int4/uint4 data were packed in Uint8Array. + // The first nybble and later nybble of one int8/uint8 value store two + // consecutive 4-bits values separately. After unpacking each 4-bits + // value, the unpacked int4 value is stored in an element of + // Int8Array, and the unpacked uint4 value is stored in an element of + // Uint8Array. For example: an array of uint4: + // size = [1, 5] + // Uint8Array.of(0x21, 0x43, 0x65, 0x87, 0xA9) + // Would yield 5 * 2 uint4 data: + // Uint8Array.of(1,2,3,4,5,6,7,8,9,10); + // Another example: an array of int4: + // size = [1, 5] + // Uint8Array.of(0xA9, 0xCB, 0xED, 0x0F, 0x21) + // Would yield 5 * 2 int4 data: + // Int8Array.of(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2); + let newOutputData; + if (expectedDescriptor.dataType === 'uint4') { + newOutputData = + new Uint8Array(sizeOfShape(expectedDescriptor.shape)); + } else { + newOutputData = + new Int8Array(sizeOfShape(expectedDescriptor.shape)); + } + const signMask = + (expectedDescriptor.dataType === 'int4') ? 0x08 : 0x00; + for (let i = 0; i < sizeOfShape(expectedDescriptor.shape); i++) { + const byteIndex = Math.floor(i / 2); + let value = (outputData[byteIndex] >> ((i & 1) << 2)) & 0xF; + // Handle the negative numbers. + if (value & signMask) { + value |= 0xF0; + } + newOutputData[i] = value; + } + outputData = newOutputData; } doAssert( operatorName, outputData, expectedData, metricType, toleranceValue, @@ -422,8 +485,13 @@ const prepareOutputsForGraph = (outputs, resources) => { const descriptor = resources[operandName].descriptor; const dataType = descriptor.castedType ? descriptor.castedType : descriptor.dataType; - outputs[operandName] = - new TypedArrayDict[dataType](sizeOfShape(descriptor.shape)); + if (dataType === 'int4' || dataType === 'uint4') { + outputs[operandName] = new TypedArrayDict[dataType]( + Math.ceil(sizeOfShape(descriptor.shape) / 2)); + } else { + outputs[operandName] = + new TypedArrayDict[dataType](sizeOfShape(descriptor.shape)); + } } }; diff --git a/tests/wpt/tests/webnn/validation_tests/constant.https.any.js b/tests/wpt/tests/webnn/validation_tests/constant.https.any.js index b9b75e372b0..fc0243197db 100644 --- a/tests/wpt/tests/webnn/validation_tests/constant.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/constant.https.any.js @@ -11,13 +11,6 @@ const tests = [ // Tests for constant(descriptor, bufferView) { name: - '[constant] Test building a 0-D scalar constant without presenting dimensions', - descriptor: {dataType: 'float32'}, - bufferView: {type: Float32Array, byteLength: 1 * 4}, - output: {dataType: 'float32', shape: []} - }, - { - name: '[constant] Test building a 0-D scalar constant with empty dimensions', descriptor: {dataType: 'float32', shape: []}, bufferView: {type: Float32Array, byteLength: 1 * 4}, diff --git a/tests/wpt/tests/webnn/validation_tests/destroyContext.https.any.js b/tests/wpt/tests/webnn/validation_tests/destroyContext.https.any.js index b4027e23dba..abed6b09bde 100644 --- a/tests/wpt/tests/webnn/validation_tests/destroyContext.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/destroyContext.https.any.js @@ -135,7 +135,7 @@ promise_test(async t => { const tensor = await context.createTensor({ dataType: 'float32', shape: [1], - usage: MLTensorUsage.READ, + readable: true, }); context.destroy(); promise_rejects_dom(t, 'InvalidStateError', context.readTensor(tensor)); @@ -146,7 +146,7 @@ promise_test(async t => { const tensor = await context.createTensor({ dataType: 'float32', shape: [1], - usage: MLTensorUsage.READ, + readable: true, }); let promise = context.readTensor(tensor); context.destroy(); @@ -161,7 +161,7 @@ promise_test(async t => { const tensor = await context.createTensor({ dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE, + writable: true, }); let arrayBuffer = new ArrayBuffer(4); context.destroy(); diff --git a/tests/wpt/tests/webnn/validation_tests/destroyGraph.https.any.js b/tests/wpt/tests/webnn/validation_tests/destroyGraph.https.any.js index f7eb01eafef..4d883e9f3c3 100644 --- a/tests/wpt/tests/webnn/validation_tests/destroyGraph.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/destroyGraph.https.any.js @@ -110,17 +110,17 @@ promise_test(async t => { const lhsTensor = await context.createTensor({ dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE, + writable: true, }); const rhsTensor = await context.createTensor({ dataType: 'float32', shape: [1], - usage: MLTensorUsage.WRITE, + writable: true, }); const outputTensor = await context.createTensor({ dataType: 'float32', shape: [1], - usage: MLTensorUsage.READ, + readable: true, }); // Initialize inputs const inputData = new Float32Array(1).fill(2.0); diff --git a/tests/wpt/tests/webnn/validation_tests/input.https.any.js b/tests/wpt/tests/webnn/validation_tests/input.https.any.js index 0649c67f086..b5b257d8bb0 100644 --- a/tests/wpt/tests/webnn/validation_tests/input.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/input.https.any.js @@ -10,14 +10,7 @@ // Tests for input(name, descriptor) const tests = [ { - testName: - '[input] Test building a 0-D scalar input without presenting dimensions', - name: 'input', - descriptor: {dataType: 'float32'}, - output: {dataType: 'float32', shape: []}, - }, - { - testName: '[input] Test building a 0-D scalar input with empty dimensions', + testName: '[input] Test building a 0-D scalar input with empty shape', name: 'input', descriptor: {dataType: 'float32', shape: []}, output: {dataType: 'float32', shape: []}, diff --git a/tests/wpt/tests/webnn/validation_tests/scatterElements.https.any.js b/tests/wpt/tests/webnn/validation_tests/scatterElements.https.any.js new file mode 100644 index 00000000000..15551b2bbe5 --- /dev/null +++ b/tests/wpt/tests/webnn/validation_tests/scatterElements.https.any.js @@ -0,0 +1,150 @@ +// META: title=validation tests for WebNN API scatterElements operation +// META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu +// META: variant=?npu +// META: script=../resources/utils_validation.js + +'use strict'; + +const tests = [ + { + name: '[scatterElements] Test scatterElements with default options', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3]}, + updates: {dataType: 'float32', shape: [2, 3]}, + output: {dataType: 'float32', shape: [3, 3]} + }, + { + name: '[scatterElements] Test scatterElements with axis = 0', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3]}, + updates: {dataType: 'float32', shape: [2, 3]}, + axis: 0, + output: {dataType: 'float32', shape: [3, 3]} + }, + { + name: '[scatterElements] Test scatterElements with axis = 1', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [3, 2]}, + updates: {dataType: 'float32', shape: [3, 2]}, + axis: 1, + output: {dataType: 'float32', shape: [3, 3]} + }, + { + name: '[scatterElements] Throw if axis is greater than input rank', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3]}, + updates: {dataType: 'float32', shape: [2, 3]}, + axis: 2 + }, + { + name: + '[scatterElements] Throw if updates tensor data type is not the same as input data type', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3]}, + updates: {dataType: 'float16', shape: [2, 3]}, + }, + { + name: '[scatterElements] Throw if input, indices and updates are scalar', + input: {dataType: 'float32', shape: []}, + indices: {dataType: 'int32', shape: []}, + updates: {dataType: 'float32', shape: []}, + }, + { + name: + '[scatterElements] Throw if indices rank is not the same as input rank', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3, 3]}, + updates: {dataType: 'float32', shape: [2, 3, 3]}, + }, + { + name: + '[scatterElements] Throw if indices size is not the same as input size along axis 1', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 4]}, + updates: {dataType: 'float32', shape: [2, 4]}, + axis: 0 + }, + { + name: + '[scatterElements] Throw if indices size is not the same as input size along axis 0', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 2]}, + updates: {dataType: 'float32', shape: [2, 2]}, + axis: 1 + }, + { + name: + '[scatterElements] Throw if indices rank is not the same as updates rank', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3]}, + updates: {dataType: 'float32', shape: [2, 3, 3]}, + }, + { + name: + '[scatterElements] Throw if indices shape is not the same as updates shape', + input: {dataType: 'float32', shape: [3, 3]}, + indices: {dataType: 'int32', shape: [2, 3]}, + updates: {dataType: 'float32', shape: [2, 4]}, + } +]; + +tests.forEach( + test => promise_test(async t => { + const builder = new MLGraphBuilder(context); + const input = builder.input('input', test.input); + const indices = builder.input('indices', test.indices); + const updates = builder.input('updates', test.updates); + + const options = {}; + if (test.axis) { + options.axis = test.axis; + } + + if (test.output) { + const output = + builder.scatterElements(input, indices, updates, options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.shape); + } else { + const label = 'a_scatter_elements' + options.label = label; + const regexp = new RegExp('\\[' + label + '\\]'); + assert_throws_with_label( + () => builder.scatterElements(input, indices, updates, options), + regexp); + } + }, test.name)); + +multi_builder_test(async (t, builder, otherBuilder) => { + const input = + otherBuilder.input('input', {dataType: 'float32', shape: [3, 3]}); + const indices = builder.input('indices', {dataType: 'int32', shape: [2, 3]}); + const updates = + builder.input('updates', {dataType: 'float32', shape: [2, 3]}); + + assert_throws_js( + TypeError, () => builder.scatterElements(input, indices, updates)); +}, '[scatterElements] Throw if input is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const input = builder.input('input', {dataType: 'float32', shape: [3, 3]}); + const indices = + otherBuilder.input('indices', {dataType: 'int32', shape: [2, 3]}); + const updates = + builder.input('updates', {dataType: 'float32', shape: [2, 3]}); + + assert_throws_js( + TypeError, () => builder.scatterElements(input, indices, updates)); +}, '[scatterElements] Throw if indices is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const input = builder.input('input', {dataType: 'float32', shape: [3, 3]}); + const indices = builder.input('indices', {dataType: 'int32', shape: [2, 3]}); + const updates = + otherBuilder.input('updates', {dataType: 'float32', shape: [2, 3]}); + + assert_throws_js( + TypeError, () => builder.scatterElements(input, indices, updates)); +}, '[scatterElements] Throw if updates is from another builder'); diff --git a/tests/wpt/tests/webrtc/RTCPeerConnection-getStats-timestamp.https.html b/tests/wpt/tests/webrtc/RTCPeerConnection-getStats-timestamp.https.html index 9345d5838d1..af975219018 100644 --- a/tests/wpt/tests/webrtc/RTCPeerConnection-getStats-timestamp.https.html +++ b/tests/wpt/tests/webrtc/RTCPeerConnection-getStats-timestamp.https.html @@ -11,6 +11,11 @@ // performance.now()` diverge inside of WPTs, so implementers beware that these // tests may give FALSE positives if `timestamp` is implemented as Wall Clock. +// TODO: crbug.com/372749742 - Timestamps from RTCStats differs slightly from +// performance.timeOrigin + performance.now(). We add an epsilon to the +// timestamp checks as a workaround to avoid making the tests flaky. +const kTimeEpsilon = 0.2; + promise_test(async t => { const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); @@ -25,8 +30,10 @@ promise_test(async t => { const peerConnectionStats = report.values().find(stats => stats.type == 'peer-connection'); - assert_less_than_equal(t0, peerConnectionStats.timestamp); - assert_less_than_equal(peerConnectionStats.timestamp, t1); + assert_less_than_equal(t0, peerConnectionStats.timestamp + kTimeEpsilon, + 't0 < timestamp'); + assert_less_than_equal(peerConnectionStats.timestamp, t1 + kTimeEpsilon, + 'timestamp < t1'); }, 'RTCStats.timestamp is expressed as Performance time'); promise_test(async t => { @@ -63,7 +70,9 @@ promise_test(async t => { } const t1 = performance.timeOrigin + performance.now(); - assert_less_than_equal(t0, remoteInboundRtp.timestamp); - assert_less_than_equal(remoteInboundRtp.timestamp, t1); + assert_less_than_equal(t0, remoteInboundRtp.timestamp + kTimeEpsilon, + 't0 < timestamp'); + assert_less_than_equal(remoteInboundRtp.timestamp, t1 + kTimeEpsilon, + 'timestamp < t1'); }, 'RTCRemoteInboundRtpStats.timestamp is expressed as Performance time'); </script> diff --git a/tests/wpt/tests/webrtc/RTCRtpEncodingParameters-codec-opus-stereo.https.html b/tests/wpt/tests/webrtc/RTCRtpEncodingParameters-codec-opus-stereo.https.html new file mode 100644 index 00000000000..49335eada4f --- /dev/null +++ b/tests/wpt/tests/webrtc/RTCRtpEncodingParameters-codec-opus-stereo.https.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>RTCRtpEncodingParameters codec opus stereo</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +'use strict'; + +const kNumChannelsMono = 1; +const kNumChannelsStereo = 2; +const kAudioProcessingEnabled = true; +const kAudioProcessingDisabled = false; + +// In some implementations (e.g. Chrome), whether or not audio processing is +// used may affect the number of channels we get. +// To isolate this factor from the test, we constrain both channels and APM. +function getAudioConstraints(numChannels, audioProcessing) { + return { + channelCount: {exact: numChannels}, + autoGainControl: audioProcessing, + echoCancellation: audioProcessing, + noiseSuppression: audioProcessing + }; +} + +// Polls getSettings() until `channelCount` is known. +// Remote tracks don't populate their `channelCount` until media is received. +async function pollChannelCount(t, track) { + while (true) { + if (track.getSettings().channelCount != undefined) { + break; + } + await new Promise(r => t.step_timeout(r, 50)); + } + return track.getSettings().channelCount; +} + +promise_test(async t => { + const pc1 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc2.close()); + pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate); + pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate); + + // Open microphone as mono. + const stream = await navigator.mediaDevices.getUserMedia( + {audio: getAudioConstraints(kNumChannelsMono, kAudioProcessingEnabled)}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + // Prerequisite of the test. + assert_equals(track.getSettings().channelCount, 1, + 'Can open track in mono'); + + // Negotiate opus. + const transceiver = pc1.addTransceiver(track); + transceiver.setCodecPreferences( + RTCRtpSender.getCapabilities('audio').codecs.filter( + codec => codec.mimeType == 'audio/opus')); + await pc1.setLocalDescription(); + await pc2.setRemoteDescription(pc1.localDescription); + await pc2.setLocalDescription(); + await pc1.setRemoteDescription(pc2.localDescription); + + const [receiver] = pc2.getReceivers(); + const remoteTrack = receiver.track; + // Attaching the track to an audio element is needed for media to flow, + // otherwise the `channelCount` is never known. + const audio = document.createElement('audio'); + audio.srcObject = new MediaStream(); + audio.srcObject.addTrack(remoteTrack); + assert_equals(await pollChannelCount(t, remoteTrack), 1, + 'Remote track is also mono'); +}, 'Sending and receiving a mono track with opus'); + +promise_test(async t => { + const pc1 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc2.close()); + pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate); + pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate); + + // Open microphone as stereo. + const stream = await navigator.mediaDevices.getUserMedia( + {audio: getAudioConstraints(kNumChannelsStereo, kAudioProcessingDisabled)}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + // Prerequisite of the test. + assert_equals(track.getSettings().channelCount, 2, + 'Can open track in stereo'); + + // Negotiate opus. + const transceiver = pc1.addTransceiver(track); + transceiver.setCodecPreferences( + RTCRtpSender.getCapabilities('audio').codecs.filter( + codec => codec.mimeType == 'audio/opus')); + await pc1.setLocalDescription(); + await pc2.setRemoteDescription(pc1.localDescription); + await pc2.setLocalDescription(); + await pc1.setRemoteDescription(pc2.localDescription); + + const [receiver] = pc2.getReceivers(); + const remoteTrack = receiver.track; + // Attaching the track to an audio element is needed for media to flow, + // otherwise the `channelCount` is never known. + const audio = document.createElement('audio'); + audio.srcObject = new MediaStream(); + audio.srcObject.addTrack(remoteTrack); + assert_equals(await pollChannelCount(t, remoteTrack), 2, + 'Remote track is also stereo'); +}, 'Sending and receiving a stereo track with opus'); +</script> diff --git a/tests/wpt/tests/xhr/formdata/constructor-submitter-coordinate.html b/tests/wpt/tests/xhr/formdata/constructor-submitter-coordinate.html index 992f64b7217..b7bf128bd12 100644 --- a/tests/wpt/tests/xhr/formdata/constructor-submitter-coordinate.html +++ b/tests/wpt/tests/xhr/formdata/constructor-submitter-coordinate.html @@ -1,18 +1,21 @@ <!DOCTYPE html> <meta charset='utf-8'> +<meta name=viewport content='width=device-width,initial-scale=1'> <link rel='help' href='https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set'> <link ref='help' href='https://xhr.spec.whatwg.org/#dom-formdata'> <script src='/resources/testharness.js'></script> <script src='/resources/testharnessreport.js'></script> <form> - <input type=image src='/media/1x1-green.png'></button> + <input type=image src='/images/100px-green-rect.svg'> </form> <script> "use strict"; -test(() => { +promise_test(async () => { + await new Promise(r => window.addEventListener("load", r)); + const form = document.querySelector("form"); const submitter = form.querySelector("input[type=image]"); @@ -23,14 +26,14 @@ test(() => { }); const domRect = submitter.getBoundingClientRect(); + const clientX = Math.round((domRect.left + domRect.right) / 7); + const clientY = Math.round((domRect.top + domRect.bottom) / 4); + submitter.dispatchEvent( - new MouseEvent("click", { - clientX: Math.round(domRect.x) + 1, - clientY: Math.round(domRect.y) + 2 - }) + new MouseEvent("click", {clientX, clientY}) ); - assert_equals(formData?.get("x"), "1"); - assert_equals(formData?.get("y"), "2"); + assert_equals(formData?.get("x"), "23"); + assert_equals(formData?.get("y"), "46"); }, "The constructed FormData object should contain correct entries for Image Button submitter's dispatched coordinate"); </script> diff --git a/tests/wpt/tests/xhr/formdata/submitter-coordinate-value.html b/tests/wpt/tests/xhr/formdata/submitter-coordinate-value.html new file mode 100644 index 00000000000..69bea0ac3f9 --- /dev/null +++ b/tests/wpt/tests/xhr/formdata/submitter-coordinate-value.html @@ -0,0 +1,55 @@ +<!doctype html> +<meta charset="utf-8"> +<meta name=viewport content="width=device-width,initial-scale=1"> +<title>Test image button coordinates</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/input.html#image-button-state-(type=image)"> +<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=282266"> +<link rel="author" title="Zach Hoffman" href="mailto:zach@zrhoffman.net"> +<form id="myForm" onsubmit="return false;"> + <input id="myImage" name="myImage" type="image" src="/images/100px-green-rect.svg"> +</form> +<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> +promise_test(async t => { + await new Promise(r => window.addEventListener("load", r)); + + const xCoordinates = []; + const yCoordinates = []; + + let formData; + myForm.addEventListener("submit", t.step_func(e => { + e.preventDefault(); + formData = new FormData(myForm, myImage); + xCoordinates.push(formData.get("myImage.x")); + yCoordinates.push(formData.get("myImage.y")); + })); + + await test_driver.click(myImage); + + const [clientX, clientY] = getInViewCenterPoint(myImage.getBoundingClientRect()); + const mouseEvent = new MouseEvent("click", {clientX, clientY}); + myImage.dispatchEvent(mouseEvent); + + assert_equals(xCoordinates.length, 2, "there should be 2 X coordinates"); + assert_equals(yCoordinates.length, 2, "there should be 2 Y coordinates"); + assert_equals(xCoordinates[1], xCoordinates[0], "dispatched event X coordinate should match user intention X coordinate"); + assert_equals(yCoordinates[1], yCoordinates[0], "dispatched event Y coordinate should match user intention Y coordinate"); +}, "dispatched event coordinates should match user intention coordinates") + +// Private function from testdriver.js. +function getInViewCenterPoint(rect) { + var left = Math.max(0, rect.left); + var right = Math.min(window.innerWidth, rect.right); + var top = Math.max(0, rect.top); + var bottom = Math.min(window.innerHeight, rect.bottom); + + var x = 0.5 * (left + right); + var y = 0.5 * (top + bottom); + + return [x, y]; +} +</script> |