From eb040b49117ce357cf93ff7b8a66067f764b3569 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 22 Mar 2026 00:28:21 +0000 Subject: [PATCH] test: update WPT resources, interfaces and WebCryptoAPI --- test/fixtures/wpt/README.md | 6 +- .../WebCryptoAPI/derive_bits_keys/argon2.js | 18 - .../argon2.tentative.https.any.js | 1 + .../derive_bits_keys/argon2_vectors.js | 1 - .../derive_bits_keys/cfrg_curves_bits.js | 33 - .../cfrg_curves_bits_curve25519.https.any.js | 1 + ...urves_bits_curve448.tentative.https.any.js | 1 + .../derive_bits_keys/cfrg_curves_keys.js | 33 - .../cfrg_curves_keys_curve25519.https.any.js | 1 + ...urves_keys_curve448.tentative.https.any.js | 1 + .../derived_bits_length.https.any.js | 1 + .../derive_bits_keys/ecdh_bits.https.any.js | 1 + .../derive_bits_keys/ecdh_bits.js | 33 - .../derive_bits_keys/ecdh_keys.https.any.js | 1 + .../derive_bits_keys/ecdh_keys.js | 33 - .../derive_bits_keys/hkdf.https.any.js | 1 + .../wpt/WebCryptoAPI/derive_bits_keys/hkdf.js | 17 - .../derive_bits_keys/pbkdf2.https.any.js | 1 + .../WebCryptoAPI/derive_bits_keys/pbkdf2.js | 17 - .../digest/cshake.tentative.https.any.js | 15 +- .../WebCryptoAPI/digest/digest.https.any.js | 31 +- .../kangarootwelve.tentative.https.any.js | 324 ++++++++ .../digest/sha3.tentative.https.any.js | 15 +- .../digest/turboshake.tentative.https.any.js | 297 ++++++++ .../encap_decap_bits.tentative.https.any.js | 41 +- .../encap_decap_keys.tentative.https.any.js | 614 ++++++++------- .../encap_decap/ml_kem_encap_decap.js | 410 ---------- .../wpt/WebCryptoAPI/encrypt_decrypt/aes.js | 29 - .../encrypt_decrypt/aes_cbc.https.any.js | 1 + .../encrypt_decrypt/aes_ctr.https.any.js | 1 + .../encrypt_decrypt/aes_gcm.https.any.js | 1 + .../aes_gcm_256_iv.https.any.js | 1 + .../encrypt_decrypt/aes_gcm_vectors.js | 1 - .../aes_ocb.tentative.https.any.js | 1 + .../chacha20_poly1305.tentative.https.any.js | 15 +- .../wpt/WebCryptoAPI/encrypt_decrypt/rsa.js | 42 +- .../encrypt_decrypt/rsa_oaep.https.any.js | 1 + .../getPublicKey.tentative.https.any.js | 12 - .../idlharness.tentative.https.any.js | 17 + .../import_export/ML-DSA_importKey.js | 92 --- .../import_export/ML-KEM_importKey.js | 92 --- .../import_export/ec_importKey.https.any.js | 84 -- .../import_export/okp_importKey.js | 84 -- .../import_export/rsa_importKey.https.any.js | 84 -- .../import_export/symmetric_importKey.js | 84 -- .../sign_verify/ecdsa.https.any.js | 1 + .../wpt/WebCryptoAPI/sign_verify/ecdsa.js | 29 - .../wpt/WebCryptoAPI/sign_verify/eddsa.js | 12 - .../sign_verify/eddsa_curve25519.https.any.js | 1 + .../eddsa_curve448.tentative.https.any.js | 1 + .../eddsa_small_order_points.https.any.js | 1 + .../sign_verify/hmac.https.any.js | 1 + .../wpt/WebCryptoAPI/sign_verify/hmac.js | 29 - .../wpt/WebCryptoAPI/sign_verify/kmac.js | 29 - .../sign_verify/kmac.tentative.https.any.js | 1 + .../wpt/WebCryptoAPI/sign_verify/mldsa.js | 29 - .../sign_verify/mldsa.tentative.https.any.js | 1 + .../wpt/WebCryptoAPI/sign_verify/rsa.js | 29 - .../sign_verify/rsa_pkcs.https.any.js | 1 + .../sign_verify/rsa_pss.https.any.js | 1 + .../fixtures/wpt/WebCryptoAPI/util/helpers.js | 93 ++- .../wrapKey_unwrapKey.https.any.js | 73 -- test/fixtures/wpt/interfaces/dom.idl | 10 +- test/fixtures/wpt/interfaces/html.idl | 717 ++++++++++-------- .../wpt/interfaces/performance-timeline.idl | 4 +- .../wpt/interfaces/resource-timing.idl | 8 +- test/fixtures/wpt/interfaces/streams.idl | 2 +- test/fixtures/wpt/interfaces/web-locks.idl | 9 +- .../wpt/interfaces/webcrypto-modern-algos.idl | 118 +++ .../interfaces/webcrypto-secure-curves.idl | 8 + test/fixtures/wpt/interfaces/webcrypto.idl | 6 +- test/fixtures/wpt/interfaces/webidl.idl | 13 + test/fixtures/wpt/resources/example.pdf | Bin 0 -> 618 bytes test/fixtures/wpt/resources/idlharness.js | 2 +- .../wpt/resources/testdriver-actions.js | 14 +- test/fixtures/wpt/resources/testdriver.js | 269 ++++++- test/fixtures/wpt/resources/testharness.js | 2 +- .../wpt/resources/web-extensions-helper.js | 40 + .../wpt/resources/webidl2/lib/VERSION.md | 2 +- .../wpt/resources/webidl2/lib/webidl2.js | 588 +++++++++----- test/fixtures/wpt/versions.json | 6 +- test/wpt/status/WebCryptoAPI.cjs | 6 + test/wpt/status/resource-timing.json | 12 +- 83 files changed, 2316 insertions(+), 2442 deletions(-) create mode 100644 test/fixtures/wpt/WebCryptoAPI/digest/kangarootwelve.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/digest/turboshake.tentative.https.any.js delete mode 100644 test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/idlharness.tentative.https.any.js create mode 100644 test/fixtures/wpt/interfaces/webcrypto-modern-algos.idl create mode 100644 test/fixtures/wpt/interfaces/webcrypto-secure-curves.idl create mode 100644 test/fixtures/wpt/resources/example.pdf create mode 100644 test/fixtures/wpt/resources/web-extensions-helper.js diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index cba3d03b9038fd..a577304b0d35a0 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -23,10 +23,10 @@ Last update: - html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing - html/webappapis/structured-clone: https://github.com/web-platform-tests/wpt/tree/47d3fb280c/html/webappapis/structured-clone - html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/5873f2d8f1/html/webappapis/timers -- interfaces: https://github.com/web-platform-tests/wpt/tree/e1b27be06b/interfaces +- interfaces: https://github.com/web-platform-tests/wpt/tree/a8392bd021/interfaces - performance-timeline: https://github.com/web-platform-tests/wpt/tree/94caab7038/performance-timeline - resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing -- resources: https://github.com/web-platform-tests/wpt/tree/1d2c5fb36a/resources +- resources: https://github.com/web-platform-tests/wpt/tree/6a2f322376/resources - streams: https://github.com/web-platform-tests/wpt/tree/bc9dcbbf1a/streams - url: https://github.com/web-platform-tests/wpt/tree/c928b19ab0/url - urlpattern: https://github.com/web-platform-tests/wpt/tree/a2e15ad405/urlpattern @@ -34,7 +34,7 @@ Last update: - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi - web-locks: https://github.com/web-platform-tests/wpt/tree/10a122a6bc/web-locks -- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/0acea989ac/WebCryptoAPI +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/caebe89c3b/WebCryptoAPI - webidl: https://github.com/web-platform-tests/wpt/tree/63ca529a02/webidl - webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/2f96fa1996/webidl/ecmascript-binding/es-exceptions - webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/6495c91853/webmessaging/broadcastchannel diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js index f1609403d623fa..de3b4b5920df27 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js @@ -51,7 +51,6 @@ function define_tests() { var algorithmName = vector.algorithm; var password = vector.password; - // Key for normal operations promises.push( subtle .importKey('raw-secret', password, algorithmName, false, [ @@ -70,20 +69,3 @@ function define_tests() { }); } } - -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aView = new Uint8Array(a); - var bView = new Uint8Array(b); - - for (var i = 0; i < aView.length; i++) { - if (aView[i] !== bView[i]) { - return false; - } - } - - return true; -} diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js index 55fb11c995653e..9422c39c958a06 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: deriveBits() Using Argon2 // META: timeout=long +// META: script=../util/helpers.js // META: script=/common/subset-tests.js // META: script=argon2_vectors.js // META: script=argon2.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js index 9b9acda5f42d3a..93d26b5eb96980 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js @@ -2,7 +2,6 @@ function getTestData() { // Test vectors from RFC 9106 // https://www.rfc-editor.org/rfc/rfc9106 - // Test vectors from RFC 9106 var testVectors = [ // Argon2d test vector { diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js index 8ab9db7bf71318..1406e8bf0a1928 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js @@ -224,37 +224,4 @@ function define_tests(algorithmName) { .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys, ecdhKeys: ecdhPublicKeys}}); } - // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is - // omitted, the two values must be the same length and have the same contents - // in every byte. If bitCount is included, only that leading number of bits - // have to match. - function equalBuffers(a, b, bitCount) { - var remainder; - - if (typeof bitCount === "undefined" && a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - var length = a.byteLength; - if (typeof bitCount !== "undefined") { - length = Math.floor(bitCount / 8); - } - - for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); - } - - return true; - } - } diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js index 866192e0193bc1..5684d7624076c7 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_bits.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js index 32485c68107e5c..5e482ef0b9d804 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_bits.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js index 62f9e00aa33846..cefc45ac692903 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js @@ -221,37 +221,4 @@ function define_tests(algorithmName) { .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveKeyKeys: noDeriveKeyKeys, ecdhKeys: ecdhPublicKeys}}); } - // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is - // omitted, the two values must be the same length and have the same contents - // in every byte. If bitCount is included, only that leading number of bits - // have to match. - function equalBuffers(a, b, bitCount) { - var remainder; - - if (typeof bitCount === "undefined" && a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - var length = a.byteLength; - if (typeof bitCount !== "undefined") { - length = Math.floor(bitCount / 8); - } - - for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); - } - - return true; - } - } diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js index 91390ba5c2a17a..8bcc201d4e95ec 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_keys.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js index b34e366376a70f..0ed3954ac200b5 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_keys.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.js index 0aee2e3c172d30..862945c6a316c6 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveBits() tests for the 'length' parameter +// META: script=../util/helpers.js // META: script=derived_bits_length.js // META: script=derived_bits_length_vectors.js // META: script=derived_bits_length_testcases.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js index 37e3eb4324200c..58a0cecd5efed6 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveBits() Using ECDH +// META: script=../util/helpers.js // META: script=ecdh_bits.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js index 36b29c20a282ab..8e79909020d398 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js @@ -230,37 +230,4 @@ function define_tests() { .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, ecdsaKeyPairs: ecdsaKeyPairs, noDeriveBitsKeys: noDeriveBitsKeys}}); } - // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is - // omitted, the two values must be the same length and have the same contents - // in every byte. If bitCount is included, only that leading number of bits - // have to match. - function equalBuffers(a, b, bitCount) { - var remainder; - - if (typeof bitCount === "undefined" && a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - var length = a.byteLength; - if (typeof bitCount !== "undefined") { - length = Math.floor(bitCount / 8); - } - - for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); - } - - return true; - } - } diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js index d8235fce5a7412..6464dacfe3aa81 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH +// META: script=../util/helpers.js // META: script=ecdh_keys.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js index fce76f185530ac..8c3d2aeb5a4976 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js @@ -209,37 +209,4 @@ function define_tests() { .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, ecdsaKeyPairs: ecdsaKeyPairs, noDeriveKeyKeys: noDeriveKeyKeys}}); } - // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is - // omitted, the two values must be the same length and have the same contents - // in every byte. If bitCount is included, only that leading number of bits - // have to match. - function equalBuffers(a, b, bitCount) { - var remainder; - - if (typeof bitCount === "undefined" && a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - var length = a.byteLength; - if (typeof bitCount !== "undefined") { - length = Math.floor(bitCount / 8); - } - - for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); - } - - return true; - } - } diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js index 02492c3741c7d1..3879ddb14b903a 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js @@ -3,6 +3,7 @@ // META: variant=?1001-2000 // META: variant=?2001-3000 // META: variant=?3001-last +// META: script=../util/helpers.js // META: script=/common/subset-tests.js // META: script=hkdf_vectors.js // META: script=hkdf.js diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js index 0384f88ec73e43..08e8c0c8974617 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js @@ -275,21 +275,4 @@ function define_tests() { }); } - function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - for (var i=0; i 0) { + promise_test(function (test) { + var buffer = new Uint8Array(input); + // Alter the buffer before calling digest + buffer[0] = ~buffer[0]; + return subtle + .digest({ + get name() { + // Alter the buffer back while calling digest + buffer[0] = input[0]; + return alg; + }, + outputLength: outputLength, + customization: customization, + }, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + }, label + ' and altered buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var promise = subtle + .digest(algorithmParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + // Alter the buffer after calling digest + buffer[0] = ~buffer[0]; + return promise; + }, label + ' and altered buffer after call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + return subtle + .digest({ + get name() { + // Transfer the buffer while calling digest + buffer.buffer.transfer(); + return alg; + }, + outputLength: outputLength, + customization: customization, + }, buffer) + .then(function (result) { + if (customizationEqual(emptyDataVector, customization) && outputLengthLessOrEqual(emptyDataVector, outputLength)) { + assert_true( + equalBuffers(result, Uint8Array.fromHex(emptyDataVector[2]).subarray(0, outputLength / 8)), + 'digest on transferred buffer should match result for empty buffer' + ); + } else { + assert_equals(result.byteLength, outputLength / 8, + 'digest on transferred buffer should have correct output length'); + } + }); + }, label + ' and transferred buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var promise = subtle + .digest(algorithmParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + // Transfer the buffer after calling digest + buffer.buffer.transfer(); + return promise; + }, label + ' and transferred buffer after call'); + } + }); +}); diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js index 4ae99791b8c95f..f9f38eadc2c39a 100644 --- a/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js @@ -1,4 +1,5 @@ // META: title=WebCryptoAPI: digest() SHA-3 algorithms +// META: script=../util/helpers.js // META: timeout=long var subtle = crypto.subtle; // Change to test prefixed implementations @@ -176,17 +177,3 @@ Object.keys(sourceData).forEach(function (size) { } }); }); - -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - for (var i = 0; i < a.byteLength; i++) { - if (aBytes[i] !== bBytes[i]) { - return false; - } - } - return true; -} diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/turboshake.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/turboshake.tentative.https.any.js new file mode 100644 index 00000000000000..243931cd119802 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/digest/turboshake.tentative.https.any.js @@ -0,0 +1,297 @@ +// META: title=WebCryptoAPI: digest() TurboSHAKE algorithms +// META: script=../util/helpers.js +// META: timeout=long + +var subtle = crypto.subtle; // Change to test prefixed implementations + +// Generates a Uint8Array of length n by repeating the pattern 00 01 02 .. F9 FA. +function ptn(n) { + var buf = new Uint8Array(n); + for (var i = 0; i < n; i++) + buf[i] = i % 251; + return buf; +} + +function hexToBytes(hex) { + var bytes = new Uint8Array(hex.length / 2); + for (var i = 0; i < hex.length; i += 2) + bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); + return bytes; +} + +// RFC 9861 Section 5 test vectors +// [input, outputLengthBits, expected hex(, domainSeparation)] +var turboSHAKE128Vectors = [ + [new Uint8Array(0), 256, + '1e415f1c5983aff2169217277d17bb53' + + '8cd945a397ddec541f1ce41af2c1b74c'], + [new Uint8Array(0), 512, + '1e415f1c5983aff2169217277d17bb53' + + '8cd945a397ddec541f1ce41af2c1b74c' + + '3e8ccae2a4dae56c84a04c2385c03c15' + + 'e8193bdf58737363321691c05462c8df'], + [ptn(1), 256, + '55cedd6f60af7bb29a4042ae832ef3f5' + + '8db7299f893ebb9247247d856958daa9'], + [ptn(17), 256, + '9c97d036a3bac819db70ede0ca554ec6' + + 'e4c2a1a4ffbfd9ec269ca6a111161233'], + [ptn(Math.pow(17, 2)), 256, + '96c77c279e0126f7fc07c9b07f5cdae1' + + 'e0be60bdbe10620040e75d7223a624d2'], + [ptn(Math.pow(17, 3)), 256, + 'd4976eb56bcf118520582b709f73e1d6' + + '853e001fdaf80e1b13e0d0599d5fb372'], + [ptn(Math.pow(17, 4)), 256, + 'da67c7039e98bf530cf7a37830c6664e' + + '14cbab7f540f58403b1b82951318ee5c'], + [ptn(Math.pow(17, 5)), 256, + 'b97a906fbf83ef7c812517abf3b2d0ae' + + 'a0c4f60318ce11cf103925127f59eecd'], + [ptn(Math.pow(17, 6)), 256, + '35cd494adeded2f25239af09a7b8ef0c' + + '4d1ca4fe2d1ac370fa63216fe7b4c2b1'], + [new Uint8Array([0xff, 0xff, 0xff]), 256, + 'bf323f940494e88ee1c540fe660be8a0' + + 'c93f43d15ec006998462fa994eed5dab', 0x01], + [new Uint8Array([0xff]), 256, + '8ec9c66465ed0d4a6c35d13506718d68' + + '7a25cb05c74cca1e42501abd83874a67', 0x06], + [new Uint8Array([0xff, 0xff, 0xff]), 256, + 'b658576001cad9b1e5f399a9f77723bb' + + 'a05458042d68206f7252682dba3663ed', 0x07], + [new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), 256, + '8deeaa1aec47ccee569f659c21dfa8e1' + + '12db3cee37b18178b2acd805b799cc37', 0x0b], + [new Uint8Array([0xff]), 256, + '553122e2135e363c3292bed2c6421fa2' + + '32bab03daa07c7d6636603286506325b', 0x30], + [new Uint8Array([0xff, 0xff, 0xff]), 256, + '16274cc656d44cefd422395d0f9053bd' + + 'a6d28e122aba15c765e5ad0e6eaf26f9', 0x7f], +]; + +var turboSHAKE256Vectors = [ + [new Uint8Array(0), 512, + '367a329dafea871c7802ec67f905ae13' + + 'c57695dc2c6663c61035f59a18f8e7db' + + '11edc0e12e91ea60eb6b32df06dd7f00' + + '2fbafabb6e13ec1cc20d995547600db0'], + [ptn(1), 512, + '3e1712f928f8eaf1054632b2aa0a246e' + + 'd8b0c378728f60bc970410155c28820e' + + '90cc90d8a3006aa2372c5c5ea176b068' + + '2bf22bae7467ac94f74d43d39b0482e2'], + [ptn(17), 512, + 'b3bab0300e6a191fbe61379398359235' + + '78794ea54843f5011090fa2f3780a9e5' + + 'cb22c59d78b40a0fbff9e672c0fbe097' + + '0bd2c845091c6044d687054da5d8e9c7'], + [ptn(Math.pow(17, 2)), 512, + '66b810db8e90780424c0847372fdc957' + + '10882fde31c6df75beb9d4cd9305cfca' + + 'e35e7b83e8b7e6eb4b78605880116316' + + 'fe2c078a09b94ad7b8213c0a738b65c0'], + [ptn(Math.pow(17, 3)), 512, + 'c74ebc919a5b3b0dd1228185ba02d29e' + + 'f442d69d3d4276a93efe0bf9a16a7dc0' + + 'cd4eabadab8cd7a5edd96695f5d360ab' + + 'e09e2c6511a3ec397da3b76b9e1674fb'], + [ptn(Math.pow(17, 4)), 512, + '02cc3a8897e6f4f6ccb6fd46631b1f52' + + '07b66c6de9c7b55b2d1a23134a170afd' + + 'ac234eaba9a77cff88c1f020b7372461' + + '8c5687b362c430b248cd38647f848a1d'], + [ptn(Math.pow(17, 5)), 512, + 'add53b06543e584b5823f626996aee50' + + 'fe45ed15f20243a7165485acb4aa76b4' + + 'ffda75cedf6d8cdc95c332bd56f4b986' + + 'b58bb17d1778bfc1b1a97545cdf4ec9f'], + [ptn(Math.pow(17, 6)), 512, + '9e11bc59c24e73993c1484ec66358ef7' + + '1db74aefd84e123f7800ba9c4853e02c' + + 'fe701d9e6bb765a304f0dc34a4ee3ba8' + + '2c410f0da70e86bfbd90ea877c2d6104'], + [new Uint8Array([0xff, 0xff, 0xff]), 512, + 'd21c6fbbf587fa2282f29aea620175fb' + + '0257413af78a0b1b2a87419ce031d933' + + 'ae7a4d383327a8a17641a34f8a1d1003' + + 'ad7da6b72dba84bb62fef28f62f12424', 0x01], + [new Uint8Array([0xff]), 512, + '738d7b4e37d18b7f22ad1b5313e357e3' + + 'dd7d07056a26a303c433fa3533455280' + + 'f4f5a7d4f700efb437fe6d281405e07b' + + 'e32a0a972e22e63adc1b090daefe004b', 0x06], + [new Uint8Array([0xff, 0xff, 0xff]), 512, + '18b3b5b7061c2e67c1753a00e6ad7ed7' + + 'ba1c906cf93efb7092eaf27fbeebb755' + + 'ae6e292493c110e48d260028492b8e09' + + 'b5500612b8f2578985ded5357d00ec67', 0x07], + [new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), 512, + 'bb36764951ec97e9d85f7ee9a67a7718' + + 'fc005cf42556be79ce12c0bde50e5736' + + 'd6632b0d0dfb202d1bbb8ffe3dd74cb0' + + '0834fa756cb03471bab13a1e2c16b3c0', 0x0b], + [new Uint8Array([0xff]), 512, + 'f3fe12873d34bcbb2e608779d6b70e7f' + + '86bec7e90bf113cbd4fdd0c4e2f4625e' + + '148dd7ee1a52776cf77f240514d9ccfc' + + '3b5ddab8ee255e39ee389072962c111a', 0x30], + [new Uint8Array([0xff, 0xff, 0xff]), 512, + 'abe569c1f77ec340f02705e7d37c9ab7' + + 'e155516e4a6a150021d70b6fac0bb40c' + + '069f9a9828a0d575cd99f9bae435ab1a' + + 'cf7ed9110ba97ce0388d074bac768776', 0x7f], +]; + +// Large output tests: verify last 32 bytes of extended output +var largeOutputTests = [ + // [algorithm, outputLengthBits, lastNBytes, expectedLastBytes] + ['TurboSHAKE128', 10032 * 8, 32, + 'a3b9b0385900ce761f22aed548e754da' + + '10a5242d62e8c658e3f3a923a7555607'], + ['TurboSHAKE256', 10032 * 8, 32, + 'abefa11630c661269249742685ec082f' + + '207265dccf2f43534e9c61ba0c9d1d75'], +]; + +largeOutputTests.forEach(function (entry) { + var alg = entry[0]; + var outputLength = entry[1]; + var lastN = entry[2]; + var expected = entry[3]; + + promise_test(function (test) { + return subtle + .digest({ name: alg, outputLength: outputLength }, new Uint8Array(0)) + .then(function (result) { + var full = new Uint8Array(result); + var last = full.slice(full.length - lastN); + assert_true( + equalBuffers(last.buffer, hexToBytes(expected)), + 'last ' + lastN + ' bytes of digest match expected' + ); + }); + }, alg + ' with ' + outputLength + ' bit output, verify last ' + lastN + ' bytes'); +}); + +function domainSeparationEqual(emptyDataVector, domainSeparation) { + return (domainSeparation ?? 0x1f) === (emptyDataVector[3] ?? 0x1f); +} + +function outputLengthLessOrEqual(emptyDataVector, outputLength) { + return outputLength <= emptyDataVector[1]; +} + +var allVectors = { + TurboSHAKE128: turboSHAKE128Vectors, + TurboSHAKE256: turboSHAKE256Vectors, +}; + +Object.keys(allVectors).forEach(function (alg) { + var emptyDataVector = allVectors[alg][0]; + allVectors[alg].forEach(function (vector, i) { + var input = vector[0]; + var outputLength = vector[1]; + var expected = vector[2]; + var domainSeparation = vector[3]; + + var algorithmParams = { name: alg, outputLength: outputLength }; + if (domainSeparation !== undefined) + algorithmParams.domainSeparation = domainSeparation; + + var label = alg + ' vector #' + (i + 1) + + ' (' + outputLength + ' bit output, ' + input.length + ' byte input' + + (domainSeparation !== undefined ? ', D=0x' + domainSeparation.toString(16) : '') + ')'; + + promise_test(function (test) { + return subtle + .digest(algorithmParams, input) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + }, label); + + if (input.length > 0) { + promise_test(function (test) { + var buffer = new Uint8Array(input); + // Alter the buffer before calling digest + buffer[0] = ~buffer[0]; + return subtle + .digest({ + get name() { + // Alter the buffer back while calling digest + buffer[0] = input[0]; + return alg; + }, + outputLength: outputLength, + domainSeparation: domainSeparation, + }, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + }, label + ' and altered buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var promise = subtle + .digest(algorithmParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + // Alter the buffer after calling digest + buffer[0] = ~buffer[0]; + return promise; + }, label + ' and altered buffer after call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + return subtle + .digest({ + get name() { + // Transfer the buffer while calling digest + buffer.buffer.transfer(); + return alg; + }, + outputLength: outputLength, + domainSeparation: domainSeparation, + }, buffer) + .then(function (result) { + if (domainSeparationEqual(emptyDataVector, domainSeparation) && outputLengthLessOrEqual(emptyDataVector, outputLength)) { + assert_true( + equalBuffers(result, Uint8Array.fromHex(emptyDataVector[2]).subarray(0, outputLength / 8)), + 'digest on transferred buffer should match result for empty buffer' + ); + } else { + assert_equals(result.byteLength, outputLength / 8, + 'digest on transferred buffer should have correct output length'); + } + }); + }, label + ' and transferred buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var promise = subtle + .digest(algorithmParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexToBytes(expected)), + 'digest matches expected' + ); + }); + // Transfer the buffer after calling digest + buffer.buffer.transfer(); + return promise; + }, label + ' and transferred buffer after call'); + } + }); +}); diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js index ab112e4d497676..5a669753cd2701 100644 --- a/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js @@ -73,7 +73,7 @@ function define_bits_tests() { ); }, algorithmName + ' encapsulateBits basic functionality'); - // Test decapsulateBits operation + // Test encapsulateBits/decapsulateBits round-trip compatibility promise_test(async function (test) { // Generate a key pair for testing var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ @@ -109,30 +109,6 @@ function define_bits_tests() { equalBuffers(decapsulatedBits, encapsulatedBits.sharedKey), 'Decapsulated shared secret should match original' ); - }, algorithmName + ' decapsulateBits basic functionality'); - - // Test round-trip compatibility - promise_test(async function (test) { - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateBits', - 'decapsulateBits', - ]); - - var encapsulatedBits = await subtle.encapsulateBits( - { name: algorithmName }, - keyPair.publicKey - ); - - var decapsulatedBits = await subtle.decapsulateBits( - { name: algorithmName }, - keyPair.privateKey, - encapsulatedBits.ciphertext - ); - - assert_true( - equalBuffers(encapsulatedBits.sharedKey, decapsulatedBits), - 'Encapsulated and decapsulated shared secrets should match' - ); }, algorithmName + ' encapsulateBits/decapsulateBits round-trip compatibility'); @@ -175,19 +151,4 @@ function define_bits_tests() { }); } -// Helper function to compare two ArrayBuffers -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - for (var i = 0; i < a.byteLength; i++) { - if (aBytes[i] !== bBytes[i]) { - return false; - } - } - return true; -} - define_bits_tests(); diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js index 4ccb0585b84f87..0a45c1fc4e9f6f 100644 --- a/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js @@ -38,313 +38,318 @@ function define_key_tests() { variants.forEach(function (algorithmName) { sharedKeyConfigs.forEach(function (config) { - // Test encapsulateKey operation - promise_test(async function (test) { - // Generate a key pair for testing - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - // Test encapsulateKey - var encapsulatedKey = await subtle.encapsulateKey( - { name: algorithmName }, - keyPair.publicKey, - config.algorithm, - true, - config.usages - ); - - assert_true( - encapsulatedKey instanceof Object, - 'encapsulateKey should return an object' - ); - assert_true( - encapsulatedKey.hasOwnProperty('sharedKey'), - 'Result should have sharedKey property' - ); - assert_true( - encapsulatedKey.hasOwnProperty('ciphertext'), - 'Result should have ciphertext property' - ); - assert_true( - encapsulatedKey.sharedKey instanceof CryptoKey, - 'sharedKey should be a CryptoKey' - ); - assert_true( - encapsulatedKey.ciphertext instanceof ArrayBuffer, - 'ciphertext should be ArrayBuffer' - ); - - // Verify the shared key properties - assert_equals( - encapsulatedKey.sharedKey.type, - 'secret', - 'Shared key should be secret type' - ); - assert_equals( - encapsulatedKey.sharedKey.algorithm.name, - config.algorithm.name, - 'Shared key algorithm should match' - ); - assert_true( - encapsulatedKey.sharedKey.extractable, - 'Shared key should be extractable as specified' - ); - assert_array_equals( - encapsulatedKey.sharedKey.usages, - config.usages, - 'Shared key should have correct usages' - ); - - // Verify algorithm-specific properties - if (config.algorithm.length) { + [true, false].forEach(function (extractable) { + // Test encapsulateKey operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // Test encapsulateKey + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + config.algorithm, + extractable, + config.usages + ); + + assert_true( + encapsulatedKey instanceof Object, + 'encapsulateKey should return an object' + ); + assert_true( + encapsulatedKey.hasOwnProperty('sharedKey'), + 'Result should have sharedKey property' + ); + assert_true( + encapsulatedKey.hasOwnProperty('ciphertext'), + 'Result should have ciphertext property' + ); + assert_true( + encapsulatedKey.sharedKey instanceof CryptoKey, + 'sharedKey should be a CryptoKey' + ); + assert_true( + encapsulatedKey.ciphertext instanceof ArrayBuffer, + 'ciphertext should be ArrayBuffer' + ); + + // Verify the shared key properties assert_equals( - encapsulatedKey.sharedKey.algorithm.length, - config.algorithm.length, - 'Key length should be 256' + encapsulatedKey.sharedKey.type, + 'secret', + 'Shared key should be secret type' ); - } - if (config.algorithm.hash) { assert_equals( - encapsulatedKey.sharedKey.algorithm.hash.name, - config.algorithm.hash, - 'Hash algorithm should match' + encapsulatedKey.sharedKey.algorithm.name, + config.algorithm.name, + 'Shared key algorithm should match' ); - } - - // Verify ciphertext length based on algorithm variant - var expectedCiphertextLength; - switch (algorithmName) { - case 'ML-KEM-512': - expectedCiphertextLength = 768; - break; - case 'ML-KEM-768': - expectedCiphertextLength = 1088; - break; - case 'ML-KEM-1024': - expectedCiphertextLength = 1568; - break; - } - assert_equals( - encapsulatedKey.ciphertext.byteLength, - expectedCiphertextLength, - 'Ciphertext should be ' + - expectedCiphertextLength + - ' bytes for ' + - algorithmName - ); - }, algorithmName + ' encapsulateKey with ' + config.description); - - // Test decapsulateKey operation - promise_test(async function (test) { - // Generate a key pair for testing - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - // First encapsulate to get ciphertext - var encapsulatedKey = await subtle.encapsulateKey( - { name: algorithmName }, - keyPair.publicKey, - config.algorithm, - true, - config.usages - ); - - // Then decapsulate using the private key - var decapsulatedKey = await subtle.decapsulateKey( - { name: algorithmName }, - keyPair.privateKey, - encapsulatedKey.ciphertext, - config.algorithm, - true, - config.usages - ); - - assert_true( - decapsulatedKey instanceof CryptoKey, - 'decapsulateKey should return a CryptoKey' - ); - assert_equals( - decapsulatedKey.type, - 'secret', - 'Decapsulated key should be secret type' - ); - assert_equals( - decapsulatedKey.algorithm.name, - config.algorithm.name, - 'Decapsulated key algorithm should match' - ); - assert_true( - decapsulatedKey.extractable, - 'Decapsulated key should be extractable as specified' - ); - assert_array_equals( - decapsulatedKey.usages, - config.usages, - 'Decapsulated key should have correct usages' - ); - - // Extract both keys and verify they are identical - var originalKeyMaterial = await subtle.exportKey( - 'raw', - encapsulatedKey.sharedKey - ); - var decapsulatedKeyMaterial = await subtle.exportKey( - 'raw', - decapsulatedKey - ); - - assert_true( - equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), - 'Decapsulated key material should match original' - ); - - // Verify the key material is 32 bytes (256 bits) - assert_equals( - originalKeyMaterial.byteLength, - 32, - 'Shared key material should be 32 bytes' - ); - }, algorithmName + ' decapsulateKey with ' + config.description); - - // Test round-trip compatibility - promise_test(async function (test) { - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - var encapsulatedKey = await subtle.encapsulateKey( - { name: algorithmName }, - keyPair.publicKey, - config.algorithm, - true, - config.usages - ); - - var decapsulatedKey = await subtle.decapsulateKey( - { name: algorithmName }, - keyPair.privateKey, - encapsulatedKey.ciphertext, - config.algorithm, - true, - config.usages - ); - - // Verify keys have the same material - var originalKeyMaterial = await subtle.exportKey( - 'raw', - encapsulatedKey.sharedKey - ); - var decapsulatedKeyMaterial = await subtle.exportKey( - 'raw', - decapsulatedKey - ); - - assert_true( - equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), - 'Encapsulated and decapsulated keys should have the same material' - ); - - // Test that the derived keys can actually be used for their intended purpose - if ( - config.algorithm.name.startsWith('AES') && - config.usages.includes('encrypt') - ) { - await testAESOperation( - encapsulatedKey.sharedKey, - decapsulatedKey, - config.algorithm + assert_equals( + encapsulatedKey.sharedKey.extractable, + extractable, + 'Shared key should have correct extractable property' + ); + assert_array_equals( + encapsulatedKey.sharedKey.usages, + config.usages, + 'Shared key should have correct usages' ); - } else if (config.algorithm.name === 'HMAC') { - await testHMACOperation(encapsulatedKey.sharedKey, decapsulatedKey); - } - }, algorithmName + - ' encapsulateKey/decapsulateKey round-trip with ' + - config.description); - }); - // Test vector-based decapsulation for each shared key config - sharedKeyConfigs.forEach(function (config) { - promise_test(async function (test) { - var vectors = ml_kem_vectors[algorithmName]; - - // Import the private key from the vector's privateSeed - var privateKey = await subtle.importKey( - 'raw-seed', - vectors.privateSeed, - { name: algorithmName }, - false, - ['decapsulateKey'] - ); - - // Decapsulate the sample ciphertext from the vectors to get a shared key - var decapsulatedKey = await subtle.decapsulateKey( - { name: algorithmName }, - privateKey, - vectors.sampleCiphertext, - config.algorithm, - true, - config.usages - ); - - assert_true( - decapsulatedKey instanceof CryptoKey, - 'decapsulateKey should return a CryptoKey' - ); - assert_equals( - decapsulatedKey.type, - 'secret', - 'Decapsulated key should be secret type' - ); - assert_equals( - decapsulatedKey.algorithm.name, - config.algorithm.name, - 'Decapsulated key algorithm should match' - ); - assert_true( - decapsulatedKey.extractable, - 'Decapsulated key should be extractable as specified' - ); - assert_array_equals( - decapsulatedKey.usages, - config.usages, - 'Decapsulated key should have correct usages' - ); - - // Extract the key material and verify it matches the expected shared secret - var keyMaterial = await subtle.exportKey('raw', decapsulatedKey); - assert_equals( - keyMaterial.byteLength, - 32, - 'Shared key material should be 32 bytes' - ); - assert_true( - equalBuffers(keyMaterial, vectors.expectedSharedSecret), - "Decapsulated key material should match vector's expectedSharedSecret" - ); - - // Verify algorithm-specific properties - if (config.algorithm.length) { + // Verify algorithm-specific properties + if (config.algorithm.length) { + assert_equals( + encapsulatedKey.sharedKey.algorithm.length, + config.algorithm.length, + 'Key length should be 256' + ); + } + if (config.algorithm.hash) { + assert_equals( + encapsulatedKey.sharedKey.algorithm.hash.name, + config.algorithm.hash, + 'Hash algorithm should match' + ); + } + + // Verify ciphertext length based on algorithm variant + var expectedCiphertextLength; + switch (algorithmName) { + case 'ML-KEM-512': + expectedCiphertextLength = 768; + break; + case 'ML-KEM-768': + expectedCiphertextLength = 1088; + break; + case 'ML-KEM-1024': + expectedCiphertextLength = 1568; + break; + } + assert_equals( + encapsulatedKey.ciphertext.byteLength, + expectedCiphertextLength, + 'Ciphertext should be ' + + expectedCiphertextLength + + ' bytes for ' + + algorithmName + ); + }, `${algorithmName} encapsulateKey with ${config.description} (extractable=${extractable})`); + + // Test decapsulateKey operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // First encapsulate to get ciphertext + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + config.algorithm, + extractable, + config.usages + ); + + // Then decapsulate using the private key + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedKey.ciphertext, + config.algorithm, + extractable, + config.usages + ); + + assert_true( + decapsulatedKey instanceof CryptoKey, + 'decapsulateKey should return a CryptoKey' + ); + assert_equals( + decapsulatedKey.type, + 'secret', + 'Decapsulated key should be secret type' + ); + assert_equals( + decapsulatedKey.algorithm.name, + config.algorithm.name, + 'Decapsulated key algorithm should match' + ); + assert_equals( + decapsulatedKey.extractable, + extractable, + 'Decapsulated key should have correct extractable property' + ); + assert_array_equals( + decapsulatedKey.usages, + config.usages, + 'Decapsulated key should have correct usages' + ); + + if (extractable) { + // Extract both keys and verify they are identical + var originalKeyMaterial = await subtle.exportKey( + 'raw', + encapsulatedKey.sharedKey + ); + var decapsulatedKeyMaterial = await subtle.exportKey( + 'raw', + decapsulatedKey + ); + + assert_true( + equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), + 'Decapsulated key material should match original' + ); + + // Verify the key material is 32 bytes (256 bits) + assert_equals( + originalKeyMaterial.byteLength, + 32, + 'Shared key material should be 32 bytes' + ); + } + }, `${algorithmName} decapsulateKey with ${config.description} (extractable=${extractable})`); + + // Test round-trip compatibility + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + config.algorithm, + extractable, + config.usages + ); + + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedKey.ciphertext, + config.algorithm, + extractable, + config.usages + ); + + if (extractable) { + // Verify keys have the same material + var originalKeyMaterial = await subtle.exportKey( + 'raw', + encapsulatedKey.sharedKey + ); + var decapsulatedKeyMaterial = await subtle.exportKey( + 'raw', + decapsulatedKey + ); + + assert_true( + equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), + 'Encapsulated and decapsulated keys should have the same material' + ); + } + + // Test that the derived keys can actually be used for their intended purpose + if ( + config.algorithm.name.startsWith('AES') && + config.usages.includes('encrypt') + ) { + await testAESOperation( + encapsulatedKey.sharedKey, + decapsulatedKey, + config.algorithm + ); + } else if (config.algorithm.name === 'HMAC') { + await testHMACOperation(encapsulatedKey.sharedKey, decapsulatedKey); + } + }, `${algorithmName} encapsulateKey/decapsulateKey round-trip with ${config.description} (extractable=${extractable})`); + + // Test vector-based decapsulation + promise_test(async function (test) { + var vectors = ml_kem_vectors[algorithmName]; + + // Import the private key from the vector's privateSeed + var privateKey = await subtle.importKey( + 'raw-seed', + vectors.privateSeed, + { name: algorithmName }, + false, + ['decapsulateKey'] + ); + + // Decapsulate the sample ciphertext from the vectors to get a shared key + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + privateKey, + vectors.sampleCiphertext, + config.algorithm, + extractable, + config.usages + ); + + assert_true( + decapsulatedKey instanceof CryptoKey, + 'decapsulateKey should return a CryptoKey' + ); assert_equals( - decapsulatedKey.algorithm.length, - config.algorithm.length, - 'Key length should be 256' + decapsulatedKey.type, + 'secret', + 'Decapsulated key should be secret type' ); - } - if (config.algorithm.hash) { assert_equals( - decapsulatedKey.algorithm.hash.name, - config.algorithm.hash, - 'Hash algorithm should match' + decapsulatedKey.algorithm.name, + config.algorithm.name, + 'Decapsulated key algorithm should match' + ); + assert_equals( + decapsulatedKey.extractable, + extractable, + 'Decapsulated key should have correct extractable property' + ); + assert_array_equals( + decapsulatedKey.usages, + config.usages, + 'Decapsulated key should have correct usages' ); - } - }, algorithmName + - ' vector-based sampleCiphertext decapsulation with ' + - config.description); + + if (extractable) { + // Extract the key material and verify it matches the expected shared secret + var keyMaterial = await subtle.exportKey('raw', decapsulatedKey); + assert_equals( + keyMaterial.byteLength, + 32, + 'Shared key material should be 32 bytes' + ); + assert_true( + equalBuffers(keyMaterial, vectors.expectedSharedSecret), + "Decapsulated key material should match vector's expectedSharedSecret" + ); + } + + // Verify algorithm-specific properties + if (config.algorithm.length) { + assert_equals( + decapsulatedKey.algorithm.length, + config.algorithm.length, + 'Key length should be 256' + ); + } + if (config.algorithm.hash) { + assert_equals( + decapsulatedKey.algorithm.hash.name, + config.algorithm.hash, + 'Hash algorithm should match' + ); + } + }, `${algorithmName} vector-based sampleCiphertext decapsulation with ${config.description} (extractable=${extractable})`); + }); }); }); } @@ -430,19 +435,4 @@ async function testHMACOperation(key1, key2) { assert_true(verified2, 'HMAC verification should succeed with key2'); } -// Helper function to compare two ArrayBuffers -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - for (var i = 0; i < a.byteLength; i++) { - if (aBytes[i] !== bBytes[i]) { - return false; - } - } - return true; -} - define_key_tests(); diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js deleted file mode 100644 index 9167efa63f0ca3..00000000000000 --- a/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js +++ /dev/null @@ -1,410 +0,0 @@ -// Test implementation for ML-KEM encapsulate and decapsulate operations - -function define_tests() { - var subtle = self.crypto.subtle; - - // Test data for all ML-KEM variants - var variants = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']; - - variants.forEach(function (algorithmName) { - var testVector = ml_kem_vectors[algorithmName]; - - // Test encapsulateBits operation - promise_test(async function (test) { - // Generate a key pair for testing - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateBits', - 'decapsulateBits', - ]); - - // Test encapsulateBits - var encapsulatedBits = await subtle.encapsulateBits( - { name: algorithmName }, - keyPair.publicKey - ); - - assert_true( - encapsulatedBits instanceof Object, - 'encapsulateBits should return an object' - ); - assert_true( - encapsulatedBits.hasOwnProperty('sharedKey'), - 'Result should have sharedKey property' - ); - assert_true( - encapsulatedBits.hasOwnProperty('ciphertext'), - 'Result should have ciphertext property' - ); - assert_true( - encapsulatedBits.sharedKey instanceof ArrayBuffer, - 'sharedKey should be ArrayBuffer' - ); - assert_true( - encapsulatedBits.ciphertext instanceof ArrayBuffer, - 'ciphertext should be ArrayBuffer' - ); - - // Verify sharedKey length (should be 32 bytes for all ML-KEM variants) - assert_equals( - encapsulatedBits.sharedKey.byteLength, - 32, - 'Shared key should be 32 bytes' - ); - - // Verify ciphertext length based on algorithm variant - var expectedCiphertextLength; - switch (algorithmName) { - case 'ML-KEM-512': - expectedCiphertextLength = 768; - break; - case 'ML-KEM-768': - expectedCiphertextLength = 1088; - break; - case 'ML-KEM-1024': - expectedCiphertextLength = 1568; - break; - } - assert_equals( - encapsulatedBits.ciphertext.byteLength, - expectedCiphertextLength, - 'Ciphertext should be ' + - expectedCiphertextLength + - ' bytes for ' + - algorithmName - ); - }, algorithmName + ' encapsulateBits basic functionality'); - - // Test decapsulateBits operation - promise_test(async function (test) { - // Generate a key pair for testing - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateBits', - 'decapsulateBits', - ]); - - // First encapsulate to get ciphertext - var encapsulatedBits = await subtle.encapsulateBits( - { name: algorithmName }, - keyPair.publicKey - ); - - // Then decapsulate using the private key - var decapsulatedBits = await subtle.decapsulateBits( - { name: algorithmName }, - keyPair.privateKey, - encapsulatedBits.ciphertext - ); - - assert_true( - decapsulatedBits instanceof ArrayBuffer, - 'decapsulateBits should return ArrayBuffer' - ); - assert_equals( - decapsulatedBits.byteLength, - 32, - 'Decapsulated bits should be 32 bytes' - ); - - // The decapsulated shared secret should match the original - assert_true( - equalBuffers(decapsulatedBits, encapsulatedBits.sharedKey), - 'Decapsulated shared secret should match original' - ); - }, algorithmName + ' decapsulateBits basic functionality'); - - // Test encapsulateKey operation - promise_test(async function (test) { - // Generate a key pair for testing - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - // Test encapsulateKey with AES-GCM as the shared key algorithm - var encapsulatedKey = await subtle.encapsulateKey( - { name: algorithmName }, - keyPair.publicKey, - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ); - - assert_true( - encapsulatedKey instanceof Object, - 'encapsulateKey should return an object' - ); - assert_true( - encapsulatedKey.hasOwnProperty('sharedKey'), - 'Result should have sharedKey property' - ); - assert_true( - encapsulatedKey.hasOwnProperty('ciphertext'), - 'Result should have ciphertext property' - ); - assert_true( - encapsulatedKey.sharedKey instanceof CryptoKey, - 'sharedKey should be a CryptoKey' - ); - assert_true( - encapsulatedKey.ciphertext instanceof ArrayBuffer, - 'ciphertext should be ArrayBuffer' - ); - - // Verify the shared key properties - assert_equals( - encapsulatedKey.sharedKey.type, - 'secret', - 'Shared key should be secret type' - ); - assert_equals( - encapsulatedKey.sharedKey.algorithm.name, - 'AES-GCM', - 'Shared key algorithm should be AES-GCM' - ); - assert_equals( - encapsulatedKey.sharedKey.algorithm.length, - 256, - 'Shared key length should be 256' - ); - assert_true( - encapsulatedKey.sharedKey.extractable, - 'Shared key should be extractable as specified' - ); - assert_array_equals( - encapsulatedKey.sharedKey.usages, - ['encrypt', 'decrypt'], - 'Shared key should have correct usages' - ); - }, algorithmName + ' encapsulateKey basic functionality'); - - // Test decapsulateKey operation - promise_test(async function (test) { - // Generate a key pair for testing - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - // First encapsulate to get ciphertext - var encapsulatedKey = await subtle.encapsulateKey( - { name: algorithmName }, - keyPair.publicKey, - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ); - - // Then decapsulate using the private key - var decapsulatedKey = await subtle.decapsulateKey( - { name: algorithmName }, - keyPair.privateKey, - encapsulatedKey.ciphertext, - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ); - - assert_true( - decapsulatedKey instanceof CryptoKey, - 'decapsulateKey should return a CryptoKey' - ); - assert_equals( - decapsulatedKey.type, - 'secret', - 'Decapsulated key should be secret type' - ); - assert_equals( - decapsulatedKey.algorithm.name, - 'AES-GCM', - 'Decapsulated key algorithm should be AES-GCM' - ); - assert_equals( - decapsulatedKey.algorithm.length, - 256, - 'Decapsulated key length should be 256' - ); - assert_true( - decapsulatedKey.extractable, - 'Decapsulated key should be extractable as specified' - ); - assert_array_equals( - decapsulatedKey.usages, - ['encrypt', 'decrypt'], - 'Decapsulated key should have correct usages' - ); - - // Extract both keys and verify they are identical - var originalKeyMaterial = await subtle.exportKey( - 'raw', - encapsulatedKey.sharedKey - ); - var decapsulatedKeyMaterial = await subtle.exportKey( - 'raw', - decapsulatedKey - ); - - assert_true( - equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), - 'Decapsulated key material should match original' - ); - }, algorithmName + ' decapsulateKey basic functionality'); - - // Test error cases for encapsulateBits - promise_test(async function (test) { - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateBits', - 'decapsulateBits', - ]); - - // Test with wrong key type (private key instead of public) - await promise_rejects_dom( - test, - 'InvalidAccessError', - subtle.encapsulateBits({ name: algorithmName }, keyPair.privateKey), - 'encapsulateBits should reject private key' - ); - - // Test with wrong algorithm name - await promise_rejects_dom( - test, - 'InvalidAccessError', - subtle.encapsulateBits({ name: 'AES-GCM' }, keyPair.publicKey), - 'encapsulateBits should reject mismatched algorithm' - ); - }, algorithmName + ' encapsulateBits error cases'); - - // Test error cases for decapsulateBits - promise_test(async function (test) { - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateBits', - 'decapsulateBits', - ]); - - var encapsulatedBits = await subtle.encapsulateBits( - { name: algorithmName }, - keyPair.publicKey - ); - - // Test with wrong key type (public key instead of private) - await promise_rejects_dom( - test, - 'InvalidAccessError', - subtle.decapsulateBits( - { name: algorithmName }, - keyPair.publicKey, - encapsulatedBits.ciphertext - ), - 'decapsulateBits should reject public key' - ); - - // Test with wrong algorithm name - await promise_rejects_dom( - test, - 'InvalidAccessError', - subtle.decapsulateBits( - { name: 'AES-GCM' }, - keyPair.privateKey, - encapsulatedBits.ciphertext - ), - 'decapsulateBits should reject mismatched algorithm' - ); - - // Test with invalid ciphertext - var invalidCiphertext = new Uint8Array(10); // Wrong size - await promise_rejects_dom( - test, - 'OperationError', - subtle.decapsulateBits( - { name: algorithmName }, - keyPair.privateKey, - invalidCiphertext - ), - 'decapsulateBits should reject invalid ciphertext' - ); - }, algorithmName + ' decapsulateBits error cases'); - - // Test error cases for encapsulateKey - promise_test(async function (test) { - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - // Test with key without encapsulateKey usage - var wrongKeyPair = await subtle.generateKey( - { name: algorithmName }, - false, - ['decapsulateKey'] // Missing encapsulateKey usage - ); - - await promise_rejects_dom( - test, - 'InvalidAccessError', - subtle.encapsulateKey( - { name: algorithmName }, - wrongKeyPair.publicKey, - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ), - 'encapsulateKey should reject key without encapsulateKey usage' - ); - }, algorithmName + ' encapsulateKey error cases'); - - // Test error cases for decapsulateKey - promise_test(async function (test) { - var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ - 'encapsulateKey', - 'decapsulateKey', - ]); - - var encapsulatedKey = await subtle.encapsulateKey( - { name: algorithmName }, - keyPair.publicKey, - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ); - - // Test with key without decapsulateKey usage - var wrongKeyPair = await subtle.generateKey( - { name: algorithmName }, - false, - ['encapsulateKey'] // Missing decapsulateKey usage - ); - - await promise_rejects_dom( - test, - 'InvalidAccessError', - subtle.decapsulateKey( - { name: algorithmName }, - wrongKeyPair.privateKey, - encapsulatedKey.ciphertext, - { name: 'AES-GCM', length: 256 }, - true, - ['encrypt', 'decrypt'] - ), - 'decapsulateKey should reject key without decapsulateKey usage' - ); - }, algorithmName + ' decapsulateKey error cases'); - }); -} - -// Helper function to compare two ArrayBuffers -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - for (var i = 0; i < a.byteLength; i++) { - if (aBytes[i] !== bBytes[i]) { - return false; - } - } - return true; -} - -function run_test() { - define_tests(); -} diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js index 456f66423419c8..879a6efe257e49 100644 --- a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js @@ -482,34 +482,5 @@ function run_test() { } } - // Returns a copy of the sourceBuffer it is sent. - function copyBuffer(sourceBuffer) { - var source = new Uint8Array(sourceBuffer); - var copy = new Uint8Array(sourceBuffer.byteLength) - - for (var i=0; i { + idl_array.add_objects({ + Crypto: ['crypto'], + SubtleCrypto: ['crypto.subtle'] + }); + } +); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js index 3723b321e542d5..d9257ac6982505 100644 --- a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js @@ -106,44 +106,6 @@ function testFormat(format, algorithm, keyData, keySize, usages, extractable) { // Helper methods follow: -// Are two array buffers the same? -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - for (var i = 0; i < a.byteLength; i++) { - if (aBytes[i] !== bBytes[i]) { - return false; - } - } - - return true; -} - -// Are two Jwk objects "the same"? That is, does the object returned include -// matching values for each property that was expected? It's okay if the -// returned object has extra methods; they aren't checked. -function equalJwk(expected, got) { - var fields = Object.keys(expected); - var fieldName; - - for (var i = 0; i < fields.length; i++) { - fieldName = fields[i]; - if (!(fieldName in got)) { - return false; - } - if (expected[fieldName] !== got[fieldName]) { - return false; - } - } - - return true; -} - // Convert method parameters to a string to uniquely name each test function parameterString(format, data, algorithm, extractable, usages) { if ('byteLength' in data) { @@ -166,57 +128,3 @@ function parameterString(format, data, algorithm, extractable, usages) { return result; } - -// Character representation of any object we may use as a parameter. -function objectToString(obj) { - var keyValuePairs = []; - - if (Array.isArray(obj)) { - return ( - '[' + - obj - .map(function (elem) { - return objectToString(elem); - }) - .join(', ') + - ']' - ); - } else if (typeof obj === 'object') { - Object.keys(obj) - .sort() - .forEach(function (keyName) { - keyValuePairs.push(keyName + ': ' + objectToString(obj[keyName])); - }); - return '{' + keyValuePairs.join(', ') + '}'; - } else if (typeof obj === 'undefined') { - return 'undefined'; - } else { - return obj.toString(); - } - - var keyValuePairs = []; - - Object.keys(obj) - .sort() - .forEach(function (keyName) { - var value = obj[keyName]; - if (typeof value === 'object') { - value = objectToString(value); - } else if (typeof value === 'array') { - value = - '[' + - value - .map(function (elem) { - return objectToString(elem); - }) - .join(', ') + - ']'; - } else { - value = value.toString(); - } - - keyValuePairs.push(keyName + ': ' + value); - }); - - return '{' + keyValuePairs.join(', ') + '}'; -} diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js index c264a163148438..ad2f75048556e4 100644 --- a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js @@ -106,44 +106,6 @@ function testFormat(format, algorithm, keyData, keySize, usages, extractable) { // Helper methods follow: -// Are two array buffers the same? -function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - for (var i = 0; i < a.byteLength; i++) { - if (aBytes[i] !== bBytes[i]) { - return false; - } - } - - return true; -} - -// Are two Jwk objects "the same"? That is, does the object returned include -// matching values for each property that was expected? It's okay if the -// returned object has extra methods; they aren't checked. -function equalJwk(expected, got) { - var fields = Object.keys(expected); - var fieldName; - - for (var i = 0; i < fields.length; i++) { - fieldName = fields[i]; - if (!(fieldName in got)) { - return false; - } - if (expected[fieldName] !== got[fieldName]) { - return false; - } - } - - return true; -} - // Convert method parameters to a string to uniquely name each test function parameterString(format, data, algorithm, extractable, usages) { if ('byteLength' in data) { @@ -166,57 +128,3 @@ function parameterString(format, data, algorithm, extractable, usages) { return result; } - -// Character representation of any object we may use as a parameter. -function objectToString(obj) { - var keyValuePairs = []; - - if (Array.isArray(obj)) { - return ( - '[' + - obj - .map(function (elem) { - return objectToString(elem); - }) - .join(', ') + - ']' - ); - } else if (typeof obj === 'object') { - Object.keys(obj) - .sort() - .forEach(function (keyName) { - keyValuePairs.push(keyName + ': ' + objectToString(obj[keyName])); - }); - return '{' + keyValuePairs.join(', ') + '}'; - } else if (typeof obj === 'undefined') { - return 'undefined'; - } else { - return obj.toString(); - } - - var keyValuePairs = []; - - Object.keys(obj) - .sort() - .forEach(function (keyName) { - var value = obj[keyName]; - if (typeof value === 'object') { - value = objectToString(value); - } else if (typeof value === 'array') { - value = - '[' + - value - .map(function (elem) { - return objectToString(elem); - }) - .join(', ') + - ']'; - } else { - value = value.toString(); - } - - keyValuePairs.push(keyName + ': ' + value); - }); - - return '{' + keyValuePairs.join(', ') + '}'; -} diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js index 6a5cc8d4724b57..3b78bab4e74132 100644 --- a/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js @@ -220,44 +220,6 @@ // Helper methods follow: - // Are two array buffers the same? - function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); + } + + return true; +} + +// Returns a copy of the sourceBuffer it is sent. +function copyBuffer(sourceBuffer) { + var source = new Uint8Array(sourceBuffer); + var copy = new Uint8Array(sourceBuffer.byteLength) + + for (var i=0; i getAttributeNames(); DOMString? getAttribute(DOMString qualifiedName); DOMString? getAttributeNS(DOMString? namespace, DOMString localName); - [CEReactions] undefined setAttribute(DOMString qualifiedName, DOMString value); - [CEReactions] undefined setAttributeNS(DOMString? namespace, DOMString qualifiedName, DOMString value); + [CEReactions] undefined setAttribute(DOMString qualifiedName, (TrustedType or DOMString) value); + [CEReactions] undefined setAttributeNS(DOMString? namespace, DOMString qualifiedName, (TrustedType or DOMString) value); [CEReactions] undefined removeAttribute(DOMString qualifiedName); [CEReactions] undefined removeAttributeNS(DOMString? namespace, DOMString localName); [CEReactions] boolean toggleAttribute(DOMString qualifiedName, optional boolean force); @@ -412,7 +412,7 @@ dictionary ShadowRootInit { SlotAssignmentMode slotAssignment = "named"; boolean clonable = false; boolean serializable = false; - CustomElementRegistry customElementRegistry; + CustomElementRegistry? customElementRegistry; }; [Exposed=Window, diff --git a/test/fixtures/wpt/interfaces/html.idl b/test/fixtures/wpt/interfaces/html.idl index 9c84e6a67efa4f..567e5a79a36ab8 100644 --- a/test/fixtures/wpt/interfaces/html.idl +++ b/test/fixtures/wpt/interfaces/html.idl @@ -110,21 +110,21 @@ interface HTMLElement : Element { [HTMLConstructor] constructor(); // metadata attributes - [CEReactions] attribute DOMString title; - [CEReactions] attribute DOMString lang; + [CEReactions, Reflect] attribute DOMString title; + [CEReactions, Reflect] attribute DOMString lang; [CEReactions] attribute boolean translate; [CEReactions] attribute DOMString dir; // user interaction [CEReactions] attribute (boolean or unrestricted double or DOMString)? hidden; - [CEReactions] attribute boolean inert; + [CEReactions, Reflect] attribute boolean inert; undefined click(); - [CEReactions] attribute DOMString accessKey; + [CEReactions, Reflect] attribute DOMString accessKey; readonly attribute DOMString accessKeyLabel; [CEReactions] attribute boolean draggable; [CEReactions] attribute boolean spellcheck; - [CEReactions] attribute DOMString writingSuggestions; - [CEReactions] attribute DOMString autocapitalize; + [CEReactions, ReflectSetter] attribute DOMString writingSuggestions; + [CEReactions, ReflectSetter] attribute DOMString autocapitalize; [CEReactions] attribute boolean autocorrect; [CEReactions] attribute [LegacyNullToEmptyString] DOMString innerText; @@ -137,6 +137,9 @@ interface HTMLElement : Element { undefined hidePopover(); boolean togglePopover(optional (TogglePopoverOptions or boolean) options = {}); [CEReactions] attribute DOMString? popover; + + [CEReactions, Reflect, ReflectRange=(0, 8)] attribute unsigned long headingOffset; + [CEReactions, Reflect] attribute boolean headingReset; }; dictionary ShowPopoverOptions { @@ -160,8 +163,8 @@ interface mixin HTMLOrSVGElement { [SameObject] readonly attribute DOMStringMap dataset; attribute DOMString nonce; // intentionally no [CEReactions] - [CEReactions] attribute boolean autofocus; - [CEReactions] attribute long tabIndex; + [CEReactions, Reflect] attribute boolean autofocus; + [CEReactions, ReflectSetter] attribute long tabIndex; undefined focus(optional FocusOptions options = {}); undefined blur(); }; @@ -197,29 +200,29 @@ interface HTMLTitleElement : HTMLElement { interface HTMLBaseElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString href; - [CEReactions] attribute DOMString target; + [CEReactions, ReflectSetter] attribute USVString href; + [CEReactions, Reflect] attribute DOMString target; }; [Exposed=Window] interface HTMLLinkElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString href; + [CEReactions, ReflectURL] attribute USVString href; [CEReactions] attribute DOMString? crossOrigin; - [CEReactions] attribute DOMString rel; + [CEReactions, Reflect] attribute DOMString rel; [CEReactions] attribute DOMString as; - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; - [CEReactions] attribute DOMString media; - [CEReactions] attribute DOMString integrity; - [CEReactions] attribute DOMString hreflang; - [CEReactions] attribute DOMString type; - [SameObject, PutForwards=value] readonly attribute DOMTokenList sizes; - [CEReactions] attribute USVString imageSrcset; - [CEReactions] attribute DOMString imageSizes; + [SameObject, PutForwards=value, Reflect="rel"] readonly attribute DOMTokenList relList; + [CEReactions, Reflect] attribute DOMString media; + [CEReactions, Reflect] attribute DOMString integrity; + [CEReactions, Reflect] attribute DOMString hreflang; + [CEReactions, Reflect] attribute DOMString type; + [SameObject, PutForwards=value, Reflect] readonly attribute DOMTokenList sizes; + [CEReactions, Reflect] attribute USVString imageSrcset; + [CEReactions, Reflect] attribute DOMString imageSizes; [CEReactions] attribute DOMString referrerPolicy; - [SameObject, PutForwards=value] readonly attribute DOMTokenList blocking; - [CEReactions] attribute boolean disabled; + [SameObject, PutForwards=value, Reflect] readonly attribute DOMTokenList blocking; + [CEReactions, Reflect] attribute boolean disabled; [CEReactions] attribute DOMString fetchPriority; // also has obsolete members @@ -230,10 +233,10 @@ HTMLLinkElement includes LinkStyle; interface HTMLMetaElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString httpEquiv; - [CEReactions] attribute DOMString content; - [CEReactions] attribute DOMString media; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect="http-equiv"] attribute DOMString httpEquiv; + [CEReactions, Reflect] attribute DOMString content; + [CEReactions, Reflect] attribute DOMString media; // also has obsolete members }; @@ -243,8 +246,8 @@ interface HTMLStyleElement : HTMLElement { [HTMLConstructor] constructor(); attribute boolean disabled; - [CEReactions] attribute DOMString media; - [SameObject, PutForwards=value] readonly attribute DOMTokenList blocking; + [CEReactions, Reflect] attribute DOMString media; + [SameObject, PutForwards=value, Reflect] readonly attribute DOMTokenList blocking; // also has obsolete members }; @@ -291,16 +294,16 @@ interface HTMLPreElement : HTMLElement { interface HTMLQuoteElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString cite; + [CEReactions, ReflectURL] attribute USVString cite; }; [Exposed=Window] interface HTMLOListElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute boolean reversed; - [CEReactions] attribute long start; - [CEReactions] attribute DOMString type; + [CEReactions, Reflect] attribute boolean reversed; + [CEReactions, Reflect, ReflectDefault=1] attribute long start; + [CEReactions, Reflect] attribute DOMString type; // also has obsolete members }; @@ -323,7 +326,7 @@ interface HTMLMenuElement : HTMLElement { interface HTMLLIElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute long value; + [CEReactions, Reflect] attribute long value; // also has obsolete members }; @@ -346,13 +349,13 @@ interface HTMLDivElement : HTMLElement { interface HTMLAnchorElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString target; - [CEReactions] attribute DOMString download; - [CEReactions] attribute USVString ping; - [CEReactions] attribute DOMString rel; - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; - [CEReactions] attribute DOMString hreflang; - [CEReactions] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString target; + [CEReactions, Reflect] attribute DOMString download; + [CEReactions, Reflect] attribute USVString ping; + [CEReactions, Reflect] attribute DOMString rel; + [SameObject, PutForwards=value, Reflect="rel"] readonly attribute DOMTokenList relList; + [CEReactions, Reflect] attribute DOMString hreflang; + [CEReactions, Reflect] attribute DOMString type; [CEReactions] attribute DOMString text; @@ -360,20 +363,21 @@ interface HTMLAnchorElement : HTMLElement { // also has obsolete members }; +HTMLAnchorElement includes HyperlinkElementUtils; HTMLAnchorElement includes HTMLHyperlinkElementUtils; [Exposed=Window] interface HTMLDataElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString value; + [CEReactions, Reflect] attribute DOMString value; }; [Exposed=Window] interface HTMLTimeElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString dateTime; + [CEReactions, Reflect] attribute DOMString dateTime; }; [Exposed=Window] @@ -388,8 +392,7 @@ interface HTMLBRElement : HTMLElement { // also has obsolete members }; -interface mixin HTMLHyperlinkElementUtils { - [CEReactions] stringifier attribute USVString href; +interface mixin HyperlinkElementUtils { readonly attribute USVString origin; [CEReactions] attribute USVString protocol; [CEReactions] attribute USVString username; @@ -402,12 +405,16 @@ interface mixin HTMLHyperlinkElementUtils { [CEReactions] attribute USVString hash; }; +interface mixin HTMLHyperlinkElementUtils { + [CEReactions, ReflectSetter] stringifier attribute USVString href; +}; + [Exposed=Window] interface HTMLModElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString cite; - [CEReactions] attribute DOMString dateTime; + [CEReactions, ReflectURL] attribute USVString cite; + [CEReactions, Reflect] attribute DOMString dateTime; }; [Exposed=Window] @@ -419,13 +426,13 @@ interface HTMLPictureElement : HTMLElement { interface HTMLSourceElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString type; - [CEReactions] attribute USVString srcset; - [CEReactions] attribute DOMString sizes; - [CEReactions] attribute DOMString media; - [CEReactions] attribute unsigned long width; - [CEReactions] attribute unsigned long height; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute DOMString type; + [CEReactions, Reflect] attribute USVString srcset; + [CEReactions, Reflect] attribute DOMString sizes; + [CEReactions, Reflect] attribute DOMString media; + [CEReactions, Reflect] attribute unsigned long width; + [CEReactions, Reflect] attribute unsigned long height; }; [Exposed=Window, @@ -433,15 +440,15 @@ interface HTMLSourceElement : HTMLElement { interface HTMLImageElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString alt; - [CEReactions] attribute USVString src; - [CEReactions] attribute USVString srcset; - [CEReactions] attribute DOMString sizes; + [CEReactions, Reflect] attribute DOMString alt; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute USVString srcset; + [CEReactions, Reflect] attribute DOMString sizes; [CEReactions] attribute DOMString? crossOrigin; - [CEReactions] attribute DOMString useMap; - [CEReactions] attribute boolean isMap; - [CEReactions] attribute unsigned long width; - [CEReactions] attribute unsigned long height; + [CEReactions, Reflect] attribute DOMString useMap; + [CEReactions, Reflect] attribute boolean isMap; + [CEReactions, ReflectSetter] attribute unsigned long width; + [CEReactions, ReflectSetter] attribute unsigned long height; readonly attribute unsigned long naturalWidth; readonly attribute unsigned long naturalHeight; readonly attribute boolean complete; @@ -460,14 +467,14 @@ interface HTMLImageElement : HTMLElement { interface HTMLIFrameElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString src; + [CEReactions, ReflectURL] attribute USVString src; [CEReactions] attribute (TrustedHTML or DOMString) srcdoc; - [CEReactions] attribute DOMString name; - [SameObject, PutForwards=value] readonly attribute DOMTokenList sandbox; - [CEReactions] attribute DOMString allow; - [CEReactions] attribute boolean allowFullscreen; - [CEReactions] attribute DOMString width; - [CEReactions] attribute DOMString height; + [CEReactions, Reflect] attribute DOMString name; + [SameObject, PutForwards=value, Reflect] readonly attribute DOMTokenList sandbox; + [CEReactions, Reflect] attribute DOMString allow; + [CEReactions, Reflect] attribute boolean allowFullscreen; + [CEReactions, Reflect] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString height; [CEReactions] attribute DOMString referrerPolicy; [CEReactions] attribute DOMString loading; readonly attribute Document? contentDocument; @@ -481,10 +488,10 @@ interface HTMLIFrameElement : HTMLElement { interface HTMLEmbedElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString width; - [CEReactions] attribute DOMString height; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString height; Document? getSVGDocument(); // also has obsolete members @@ -494,12 +501,12 @@ interface HTMLEmbedElement : HTMLElement { interface HTMLObjectElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString data; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString name; + [CEReactions, ReflectURL] attribute USVString data; + [CEReactions, Reflect] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString name; readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString width; - [CEReactions] attribute DOMString height; + [CEReactions, Reflect] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString height; readonly attribute Document? contentDocument; readonly attribute WindowProxy? contentWindow; Document? getSVGDocument(); @@ -518,12 +525,12 @@ interface HTMLObjectElement : HTMLElement { interface HTMLVideoElement : HTMLMediaElement { [HTMLConstructor] constructor(); - [CEReactions] attribute unsigned long width; - [CEReactions] attribute unsigned long height; + [CEReactions, Reflect] attribute unsigned long width; + [CEReactions, Reflect] attribute unsigned long height; readonly attribute unsigned long videoWidth; readonly attribute unsigned long videoHeight; - [CEReactions] attribute USVString poster; - [CEReactions] attribute boolean playsInline; + [CEReactions, ReflectURL] attribute USVString poster; + [CEReactions, Reflect] attribute boolean playsInline; }; [Exposed=Window, @@ -537,10 +544,10 @@ interface HTMLTrackElement : HTMLElement { [HTMLConstructor] constructor(); [CEReactions] attribute DOMString kind; - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString srclang; - [CEReactions] attribute DOMString label; - [CEReactions] attribute boolean default; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute DOMString srclang; + [CEReactions, Reflect] attribute DOMString label; + [CEReactions, Reflect] attribute boolean default; const unsigned short NONE = 0; const unsigned short LOADING = 1; @@ -561,7 +568,7 @@ interface HTMLMediaElement : HTMLElement { readonly attribute MediaError? error; // network state - [CEReactions] attribute USVString src; + [CEReactions, ReflectURL] attribute USVString src; attribute MediaProvider? srcObject; readonly attribute USVString currentSrc; [CEReactions] attribute DOMString? crossOrigin; @@ -596,16 +603,16 @@ interface HTMLMediaElement : HTMLElement { readonly attribute TimeRanges played; readonly attribute TimeRanges seekable; readonly attribute boolean ended; - [CEReactions] attribute boolean autoplay; - [CEReactions] attribute boolean loop; + [CEReactions, Reflect] attribute boolean autoplay; + [CEReactions, Reflect] attribute boolean loop; Promise play(); undefined pause(); // controls - [CEReactions] attribute boolean controls; + [CEReactions, Reflect] attribute boolean controls; attribute double volume; attribute boolean muted; - [CEReactions] attribute boolean defaultMuted; + [CEReactions, Reflect="muted"] attribute boolean defaultMuted; // tracks [SameObject] readonly attribute AudioTrackList audioTracks; @@ -742,7 +749,7 @@ dictionary TrackEventInit : EventInit { interface HTMLMapElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString name; [SameObject] readonly attribute HTMLCollection areas; }; @@ -750,18 +757,19 @@ interface HTMLMapElement : HTMLElement { interface HTMLAreaElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString alt; - [CEReactions] attribute DOMString coords; - [CEReactions] attribute DOMString shape; - [CEReactions] attribute DOMString target; - [CEReactions] attribute DOMString download; - [CEReactions] attribute USVString ping; - [CEReactions] attribute DOMString rel; - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; + [CEReactions, Reflect] attribute DOMString alt; + [CEReactions, Reflect] attribute DOMString coords; + [CEReactions, Reflect] attribute DOMString shape; + [CEReactions, Reflect] attribute DOMString target; + [CEReactions, Reflect] attribute DOMString download; + [CEReactions, Reflect] attribute USVString ping; + [CEReactions, Reflect] attribute DOMString rel; + [SameObject, PutForwards=value, Reflect="rel"] readonly attribute DOMTokenList relList; [CEReactions] attribute DOMString referrerPolicy; // also has obsolete members }; +HTMLAreaElement includes HyperlinkElementUtils; HTMLAreaElement includes HTMLHyperlinkElementUtils; [Exposed=Window] @@ -801,7 +809,7 @@ interface HTMLTableCaptionElement : HTMLElement { interface HTMLTableColElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute unsigned long span; + [CEReactions, Reflect, ReflectDefault=1, ReflectRange=(1, 1000)] attribute unsigned long span; // also has obsolete members }; @@ -834,13 +842,13 @@ interface HTMLTableRowElement : HTMLElement { interface HTMLTableCellElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute unsigned long colSpan; - [CEReactions] attribute unsigned long rowSpan; - [CEReactions] attribute DOMString headers; + [CEReactions, Reflect, ReflectDefault=1, ReflectRange=(1, 1000)] attribute unsigned long colSpan; + [CEReactions, Reflect, ReflectDefault=1, ReflectRange=(0, 65534)] attribute unsigned long rowSpan; + [CEReactions, Reflect] attribute DOMString headers; readonly attribute long cellIndex; [CEReactions] attribute DOMString scope; // only conforming for th elements - [CEReactions] attribute DOMString abbr; // only conforming for th elements + [CEReactions, Reflect] attribute DOMString abbr; // only conforming for th elements // also has obsolete members }; @@ -851,17 +859,17 @@ interface HTMLTableCellElement : HTMLElement { interface HTMLFormElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString acceptCharset; - [CEReactions] attribute USVString action; + [CEReactions, Reflect="accept-charset"] attribute DOMString acceptCharset; + [CEReactions, ReflectSetter] attribute USVString action; [CEReactions] attribute DOMString autocomplete; [CEReactions] attribute DOMString enctype; [CEReactions] attribute DOMString encoding; [CEReactions] attribute DOMString method; - [CEReactions] attribute DOMString name; - [CEReactions] attribute boolean noValidate; - [CEReactions] attribute DOMString target; - [CEReactions] attribute DOMString rel; - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute boolean noValidate; + [CEReactions, Reflect] attribute DOMString target; + [CEReactions, Reflect] attribute DOMString rel; + [SameObject, PutForwards=value, Reflect="rel"] readonly attribute DOMTokenList relList; [SameObject] readonly attribute HTMLFormControlsCollection elements; readonly attribute unsigned long length; @@ -880,7 +888,7 @@ interface HTMLLabelElement : HTMLElement { [HTMLConstructor] constructor(); readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString htmlFor; + [CEReactions, Reflect="for"] attribute DOMString htmlFor; readonly attribute HTMLElement? control; }; @@ -888,44 +896,44 @@ interface HTMLLabelElement : HTMLElement { interface HTMLInputElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString accept; - [CEReactions] attribute boolean alpha; - [CEReactions] attribute DOMString alt; - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute boolean defaultChecked; + [CEReactions, Reflect] attribute DOMString accept; + [CEReactions, Reflect] attribute boolean alpha; + [CEReactions, Reflect] attribute DOMString alt; + [CEReactions, ReflectSetter] attribute DOMString autocomplete; + [CEReactions, Reflect="checked"] attribute boolean defaultChecked; attribute boolean checked; [CEReactions] attribute DOMString colorSpace; - [CEReactions] attribute DOMString dirName; - [CEReactions] attribute boolean disabled; + [CEReactions, Reflect] attribute DOMString dirName; + [CEReactions, Reflect] attribute boolean disabled; readonly attribute HTMLFormElement? form; attribute FileList? files; - [CEReactions] attribute USVString formAction; + [CEReactions, ReflectSetter] attribute USVString formAction; [CEReactions] attribute DOMString formEnctype; [CEReactions] attribute DOMString formMethod; - [CEReactions] attribute boolean formNoValidate; - [CEReactions] attribute DOMString formTarget; - [CEReactions] attribute unsigned long height; + [CEReactions, Reflect] attribute boolean formNoValidate; + [CEReactions, Reflect] attribute DOMString formTarget; + [CEReactions, ReflectSetter] attribute unsigned long height; attribute boolean indeterminate; readonly attribute HTMLDataListElement? list; - [CEReactions] attribute DOMString max; - [CEReactions] attribute long maxLength; - [CEReactions] attribute DOMString min; - [CEReactions] attribute long minLength; - [CEReactions] attribute boolean multiple; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString pattern; - [CEReactions] attribute DOMString placeholder; - [CEReactions] attribute boolean readOnly; - [CEReactions] attribute boolean required; - [CEReactions] attribute unsigned long size; - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString step; + [CEReactions, Reflect] attribute DOMString max; + [CEReactions, ReflectNonNegative] attribute long maxLength; + [CEReactions, Reflect] attribute DOMString min; + [CEReactions, ReflectNonNegative] attribute long minLength; + [CEReactions, Reflect] attribute boolean multiple; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString pattern; + [CEReactions, Reflect] attribute DOMString placeholder; + [CEReactions, Reflect] attribute boolean readOnly; + [CEReactions, Reflect] attribute boolean required; + [CEReactions, Reflect] attribute unsigned long size; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute DOMString step; [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString defaultValue; + [CEReactions, Reflect="value"] attribute DOMString defaultValue; [CEReactions] attribute [LegacyNullToEmptyString] DOMString value; attribute object? valueAsDate; attribute unrestricted double valueAsNumber; - [CEReactions] attribute unsigned long width; + [CEReactions, ReflectSetter] attribute unsigned long width; undefined stepUp(optional long n = 1); undefined stepDown(optional long n = 1); @@ -951,24 +959,24 @@ interface HTMLInputElement : HTMLElement { // also has obsolete members }; -HTMLInputElement includes PopoverInvokerElement; +HTMLInputElement includes PopoverTargetAttributes; [Exposed=Window] interface HTMLButtonElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString command; - [CEReactions] attribute Element? commandForElement; - [CEReactions] attribute boolean disabled; + [CEReactions, ReflectSetter] attribute DOMString command; + [CEReactions, Reflect] attribute Element? commandForElement; + [CEReactions, Reflect] attribute boolean disabled; readonly attribute HTMLFormElement? form; - [CEReactions] attribute USVString formAction; + [CEReactions, ReflectSetter] attribute USVString formAction; [CEReactions] attribute DOMString formEnctype; [CEReactions] attribute DOMString formMethod; - [CEReactions] attribute boolean formNoValidate; - [CEReactions] attribute DOMString formTarget; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString value; + [CEReactions, Reflect] attribute boolean formNoValidate; + [CEReactions, Reflect] attribute DOMString formTarget; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, ReflectSetter] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString value; readonly attribute boolean willValidate; readonly attribute ValidityState validity; @@ -979,19 +987,19 @@ interface HTMLButtonElement : HTMLElement { readonly attribute NodeList labels; }; -HTMLButtonElement includes PopoverInvokerElement; +HTMLButtonElement includes PopoverTargetAttributes; [Exposed=Window] interface HTMLSelectElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute boolean disabled; + [CEReactions, ReflectSetter] attribute DOMString autocomplete; + [CEReactions, Reflect] attribute boolean disabled; readonly attribute HTMLFormElement? form; - [CEReactions] attribute boolean multiple; - [CEReactions] attribute DOMString name; - [CEReactions] attribute boolean required; - [CEReactions] attribute unsigned long size; + [CEReactions, Reflect] attribute boolean multiple; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute boolean required; + [CEReactions, Reflect, ReflectDefault=0] attribute unsigned long size; readonly attribute DOMString type; @@ -1031,8 +1039,8 @@ interface HTMLDataListElement : HTMLElement { interface HTMLOptGroupElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute boolean disabled; - [CEReactions] attribute DOMString label; + [CEReactions, Reflect] attribute boolean disabled; + [CEReactions, Reflect] attribute DOMString label; }; [Exposed=Window, @@ -1040,12 +1048,12 @@ interface HTMLOptGroupElement : HTMLElement { interface HTMLOptionElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute boolean disabled; + [CEReactions, Reflect] attribute boolean disabled; readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString label; - [CEReactions] attribute boolean defaultSelected; + [CEReactions, ReflectSetter] attribute DOMString label; + [CEReactions, Reflect="selected"] attribute boolean defaultSelected; attribute boolean selected; - [CEReactions] attribute DOMString value; + [CEReactions, ReflectSetter] attribute DOMString value; [CEReactions] attribute DOMString text; readonly attribute long index; @@ -1055,19 +1063,19 @@ interface HTMLOptionElement : HTMLElement { interface HTMLTextAreaElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute unsigned long cols; - [CEReactions] attribute DOMString dirName; - [CEReactions] attribute boolean disabled; + [CEReactions, ReflectSetter] attribute DOMString autocomplete; + [CEReactions, ReflectPositiveWithFallback, ReflectDefault=20] attribute unsigned long cols; + [CEReactions, Reflect] attribute DOMString dirName; + [CEReactions, Reflect] attribute boolean disabled; readonly attribute HTMLFormElement? form; - [CEReactions] attribute long maxLength; - [CEReactions] attribute long minLength; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString placeholder; - [CEReactions] attribute boolean readOnly; - [CEReactions] attribute boolean required; - [CEReactions] attribute unsigned long rows; - [CEReactions] attribute DOMString wrap; + [CEReactions, ReflectNonNegative] attribute long maxLength; + [CEReactions, ReflectNonNegative] attribute long minLength; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString placeholder; + [CEReactions, Reflect] attribute boolean readOnly; + [CEReactions, Reflect] attribute boolean required; + [CEReactions, ReflectPositiveWithFallback, ReflectDefault=2] attribute unsigned long rows; + [CEReactions, Reflect] attribute DOMString wrap; readonly attribute DOMString type; [CEReactions] attribute DOMString defaultValue; @@ -1096,9 +1104,9 @@ interface HTMLTextAreaElement : HTMLElement { interface HTMLOutputElement : HTMLElement { [HTMLConstructor] constructor(); - [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor; + [SameObject, PutForwards=value, Reflect="for"] readonly attribute DOMTokenList htmlFor; readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString name; readonly attribute DOMString type; [CEReactions] attribute DOMString defaultValue; @@ -1118,8 +1126,8 @@ interface HTMLOutputElement : HTMLElement { interface HTMLProgressElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute double value; - [CEReactions] attribute double max; + [CEReactions, ReflectSetter] attribute double value; + [CEReactions, ReflectPositive, ReflectDefault=1.0] attribute double max; readonly attribute double position; readonly attribute NodeList labels; }; @@ -1128,12 +1136,12 @@ interface HTMLProgressElement : HTMLElement { interface HTMLMeterElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute double value; - [CEReactions] attribute double min; - [CEReactions] attribute double max; - [CEReactions] attribute double low; - [CEReactions] attribute double high; - [CEReactions] attribute double optimum; + [CEReactions, ReflectSetter] attribute double value; + [CEReactions, ReflectSetter] attribute double min; + [CEReactions, ReflectSetter] attribute double max; + [CEReactions, ReflectSetter] attribute double low; + [CEReactions, ReflectSetter] attribute double high; + [CEReactions, ReflectSetter] attribute double optimum; readonly attribute NodeList labels; }; @@ -1141,9 +1149,9 @@ interface HTMLMeterElement : HTMLElement { interface HTMLFieldSetElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute boolean disabled; + [CEReactions, Reflect] attribute boolean disabled; readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString name; readonly attribute DOMString type; @@ -1166,6 +1174,11 @@ interface HTMLLegendElement : HTMLElement { // also has obsolete members }; +[Exposed=Window] +interface HTMLSelectedContentElement : HTMLElement { + [HTMLConstructor] constructor(); +}; + enum SelectionMode { "select", "start", @@ -1214,17 +1227,17 @@ dictionary FormDataEventInit : EventInit { interface HTMLDetailsElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString name; - [CEReactions] attribute boolean open; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute boolean open; }; [Exposed=Window] interface HTMLDialogElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute boolean open; + [CEReactions, Reflect] attribute boolean open; attribute DOMString returnValue; - [CEReactions] attribute DOMString closedBy; + [CEReactions, ReflectSetter] attribute DOMString closedBy; [CEReactions] undefined show(); [CEReactions] undefined showModal(); [CEReactions] undefined close(optional DOMString returnValue); @@ -1235,18 +1248,19 @@ interface HTMLDialogElement : HTMLElement { interface HTMLScriptElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString type; - [CEReactions] attribute boolean noModule; + [CEReactions, Reflect] attribute DOMString type; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute boolean noModule; [CEReactions] attribute boolean async; - [CEReactions] attribute boolean defer; + [CEReactions, Reflect] attribute boolean defer; + [SameObject, PutForwards=value, Reflect] readonly attribute DOMTokenList blocking; [CEReactions] attribute DOMString? crossOrigin; - [CEReactions] attribute DOMString text; - [CEReactions] attribute DOMString integrity; [CEReactions] attribute DOMString referrerPolicy; - [SameObject, PutForwards=value] readonly attribute DOMTokenList blocking; + [CEReactions, Reflect] attribute DOMString integrity; [CEReactions] attribute DOMString fetchPriority; + [CEReactions] attribute DOMString text; + static boolean supports(DOMString type); // also has obsolete members @@ -1258,17 +1272,17 @@ interface HTMLTemplateElement : HTMLElement { readonly attribute DocumentFragment content; [CEReactions] attribute DOMString shadowRootMode; - [CEReactions] attribute boolean shadowRootDelegatesFocus; - [CEReactions] attribute boolean shadowRootClonable; - [CEReactions] attribute boolean shadowRootSerializable; - [CEReactions] attribute DOMString shadowRootCustomElementRegistry; + [CEReactions, Reflect] attribute boolean shadowRootDelegatesFocus; + [CEReactions, Reflect] attribute boolean shadowRootClonable; + [CEReactions, Reflect] attribute boolean shadowRootSerializable; + [CEReactions, Reflect] attribute DOMString shadowRootCustomElementRegistry; }; [Exposed=Window] interface HTMLSlotElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString name; sequence assignedNodes(optional AssignedNodesOptions options = {}); sequence assignedElements(optional AssignedNodesOptions options = {}); undefined assign((Element or Text)... nodes); @@ -1306,8 +1320,6 @@ typedef (HTMLOrSVGImageElement or OffscreenCanvas or VideoFrame) CanvasImageSource; -enum PredefinedColorSpace { "srgb", "display-p3" }; - enum CanvasColorType { "unorm8", "float16" }; enum CanvasFillRule { "nonzero", "evenodd" }; @@ -1606,6 +1618,8 @@ OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles; OffscreenCanvasRenderingContext2D includes CanvasTextDrawingStyles; OffscreenCanvasRenderingContext2D includes CanvasPath; +enum PredefinedColorSpace { "srgb", "srgb-linear", "display-p3", "display-p3-linear" }; + [Exposed=Window] interface CustomElementRegistry { constructor(); @@ -1615,7 +1629,7 @@ interface CustomElementRegistry { DOMString? getName(CustomElementConstructor constructor); Promise whenDefined(DOMString name); [CEReactions] undefined upgrade(Node root); - undefined initialize(Node root); + [CEReactions] undefined initialize(Node root); }; callback CustomElementConstructor = HTMLElement (); @@ -1694,11 +1708,13 @@ interface ToggleEvent : Event { constructor(DOMString type, optional ToggleEventInit eventInitDict = {}); readonly attribute DOMString oldState; readonly attribute DOMString newState; + readonly attribute Element? source; }; dictionary ToggleEventInit : EventInit { DOMString oldState = ""; DOMString newState = ""; + Element? source = null; }; [Exposed=Window] @@ -1791,11 +1807,23 @@ dictionary DragEventInit : MouseEventInit { DataTransfer? dataTransfer = null; }; -interface mixin PopoverInvokerElement { - [CEReactions] attribute Element? popoverTargetElement; +interface mixin PopoverTargetAttributes { + [CEReactions, Reflect] attribute Element? popoverTargetElement; [CEReactions] attribute DOMString popoverTargetAction; }; +[Exposed=*] +interface Origin { + constructor(); + + static Origin from(any value); + + readonly attribute boolean opaque; + + boolean isSameOrigin(Origin other); + boolean isSameSite(Origin other); +}; + [Global=Window, Exposed=Window, LegacyUnenumerableNamedProperties] @@ -1807,7 +1835,7 @@ interface Window : EventTarget { attribute DOMString name; [PutForwards=href, LegacyUnforgeable] readonly attribute Location location; readonly attribute History history; - readonly attribute Navigation navigation; + [Replaceable] readonly attribute Navigation navigation; readonly attribute CustomElementRegistry customElements; [Replaceable] readonly attribute BarProp locationbar; [Replaceable] readonly attribute BarProp menubar; @@ -1881,7 +1909,7 @@ interface Location { // but see also additional creation steps and overridden in [LegacyUnforgeable] undefined replace(USVString url); [LegacyUnforgeable] undefined reload(); - [LegacyUnforgeable, SameObject] readonly attribute DOMStringList ancestorOrigins; + [LegacyUnforgeable] readonly attribute DOMStringList ancestorOrigins; }; enum ScrollRestoration { "auto", "manual" }; @@ -1974,6 +2002,8 @@ interface NavigationHistoryEntry : EventTarget { interface NavigationTransition { readonly attribute NavigationType navigationType; readonly attribute NavigationHistoryEntry from; + readonly attribute NavigationDestination to; + readonly attribute Promise committed; readonly attribute Promise finished; }; @@ -2019,6 +2049,7 @@ dictionary NavigateEventInit : EventInit { }; dictionary NavigationInterceptOptions { + NavigationPrecommitHandler precommitHandler; NavigationInterceptHandler handler; NavigationFocusReset focusReset; NavigationScrollBehavior scroll; @@ -2036,6 +2067,14 @@ enum NavigationScrollBehavior { callback NavigationInterceptHandler = Promise (); +[Exposed=Window] +interface NavigationPrecommitController { + undefined redirect(USVString url, optional NavigationNavigateOptions options = {}); + undefined addHandler(NavigationInterceptHandler handler); +}; + +callback NavigationPrecommitHandler = Promise (NavigationPrecommitController controller); + [Exposed=Window] interface NavigationDestination { readonly attribute USVString url; @@ -2649,9 +2688,9 @@ interface Worker : EventTarget { }; dictionary WorkerOptions { + DOMString name = ""; WorkerType type = "classic"; RequestCredentials credentials = "same-origin"; // credentials is only used if type is "module" - DOMString name = ""; }; enum WorkerType { "classic", "module" }; @@ -2661,12 +2700,16 @@ Worker includes MessageEventTarget; [Exposed=Window] interface SharedWorker : EventTarget { - constructor((TrustedScriptURL or USVString) scriptURL, optional (DOMString or WorkerOptions) options = {}); + constructor((TrustedScriptURL or USVString) scriptURL, optional (DOMString or SharedWorkerOptions) options = {}); readonly attribute MessagePort port; }; SharedWorker includes AbstractWorker; +dictionary SharedWorkerOptions : WorkerOptions { + boolean extendedLifetime = false; +}; + interface mixin NavigatorConcurrentHardware { readonly attribute unsigned long long hardwareConcurrency; }; @@ -2748,17 +2791,17 @@ dictionary StorageEventInit : EventInit { interface HTMLMarqueeElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString behavior; - [CEReactions] attribute DOMString bgColor; - [CEReactions] attribute DOMString direction; - [CEReactions] attribute DOMString height; - [CEReactions] attribute unsigned long hspace; + [CEReactions, Reflect] attribute DOMString behavior; + [CEReactions, Reflect] attribute DOMString bgColor; + [CEReactions, Reflect] attribute DOMString direction; + [CEReactions, Reflect] attribute DOMString height; + [CEReactions, Reflect] attribute unsigned long hspace; [CEReactions] attribute long loop; - [CEReactions] attribute unsigned long scrollAmount; - [CEReactions] attribute unsigned long scrollDelay; - [CEReactions] attribute boolean trueSpeed; - [CEReactions] attribute unsigned long vspace; - [CEReactions] attribute DOMString width; + [CEReactions, Reflect, ReflectDefault=6] attribute unsigned long scrollAmount; + [CEReactions, Reflect, ReflectDefault=85] attribute unsigned long scrollDelay; + [CEReactions, Reflect] attribute boolean trueSpeed; + [CEReactions, Reflect] attribute unsigned long vspace; + [CEReactions, Reflect] attribute DOMString width; undefined start(); undefined stop(); @@ -2768,8 +2811,8 @@ interface HTMLMarqueeElement : HTMLElement { interface HTMLFrameSetElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString cols; - [CEReactions] attribute DOMString rows; + [CEReactions, Reflect] attribute DOMString cols; + [CEReactions, Reflect] attribute DOMString rows; }; HTMLFrameSetElement includes WindowEventHandlers; @@ -2777,242 +2820,242 @@ HTMLFrameSetElement includes WindowEventHandlers; interface HTMLFrameElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString scrolling; - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString frameBorder; - [CEReactions] attribute USVString longDesc; - [CEReactions] attribute boolean noResize; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString scrolling; + [CEReactions, ReflectURL] attribute USVString src; + [CEReactions, Reflect] attribute DOMString frameBorder; + [CEReactions, ReflectURL] attribute USVString longDesc; + [CEReactions, Reflect] attribute boolean noResize; readonly attribute Document? contentDocument; readonly attribute WindowProxy? contentWindow; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString marginHeight; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString marginWidth; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString marginHeight; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString marginWidth; }; partial interface HTMLAnchorElement { - [CEReactions] attribute DOMString coords; - [CEReactions] attribute DOMString charset; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString rev; - [CEReactions] attribute DOMString shape; + [CEReactions, Reflect] attribute DOMString coords; + [CEReactions, Reflect] attribute DOMString charset; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString rev; + [CEReactions, Reflect] attribute DOMString shape; }; partial interface HTMLAreaElement { - [CEReactions] attribute boolean noHref; + [CEReactions, Reflect] attribute boolean noHref; }; partial interface HTMLBodyElement { - [CEReactions] attribute [LegacyNullToEmptyString] DOMString text; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString link; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString vLink; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString aLink; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString bgColor; - [CEReactions] attribute DOMString background; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString text; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString link; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString vLink; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString aLink; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString bgColor; + [CEReactions, Reflect] attribute DOMString background; }; partial interface HTMLBRElement { - [CEReactions] attribute DOMString clear; + [CEReactions, Reflect] attribute DOMString clear; }; partial interface HTMLTableCaptionElement { - [CEReactions] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString align; }; partial interface HTMLTableColElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute DOMString vAlign; - [CEReactions] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect="char"] attribute DOMString ch; + [CEReactions, Reflect="charoff"] attribute DOMString chOff; + [CEReactions, Reflect] attribute DOMString vAlign; + [CEReactions, Reflect] attribute DOMString width; }; [Exposed=Window] interface HTMLDirectoryElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute boolean compact; + [CEReactions, Reflect] attribute boolean compact; }; partial interface HTMLDivElement { - [CEReactions] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString align; }; partial interface HTMLDListElement { - [CEReactions] attribute boolean compact; + [CEReactions, Reflect] attribute boolean compact; }; partial interface HTMLEmbedElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString name; }; [Exposed=Window] interface HTMLFontElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute [LegacyNullToEmptyString] DOMString color; - [CEReactions] attribute DOMString face; - [CEReactions] attribute DOMString size; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString color; + [CEReactions, Reflect] attribute DOMString face; + [CEReactions, Reflect] attribute DOMString size; }; partial interface HTMLHeadingElement { - [CEReactions] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString align; }; partial interface HTMLHRElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString color; - [CEReactions] attribute boolean noShade; - [CEReactions] attribute DOMString size; - [CEReactions] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString color; + [CEReactions, Reflect] attribute boolean noShade; + [CEReactions, Reflect] attribute DOMString size; + [CEReactions, Reflect] attribute DOMString width; }; partial interface HTMLHtmlElement { - [CEReactions] attribute DOMString version; + [CEReactions, Reflect] attribute DOMString version; }; partial interface HTMLIFrameElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString scrolling; - [CEReactions] attribute DOMString frameBorder; - [CEReactions] attribute USVString longDesc; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString scrolling; + [CEReactions, Reflect] attribute DOMString frameBorder; + [CEReactions, ReflectURL] attribute USVString longDesc; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString marginHeight; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString marginWidth; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString marginHeight; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString marginWidth; }; partial interface HTMLImageElement { - [CEReactions] attribute DOMString name; - [CEReactions] attribute USVString lowsrc; - [CEReactions] attribute DOMString align; - [CEReactions] attribute unsigned long hspace; - [CEReactions] attribute unsigned long vspace; - [CEReactions] attribute USVString longDesc; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, ReflectURL] attribute USVString lowsrc; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute unsigned long hspace; + [CEReactions, Reflect] attribute unsigned long vspace; + [CEReactions, ReflectURL] attribute USVString longDesc; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString border; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString border; }; partial interface HTMLInputElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString useMap; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString useMap; }; partial interface HTMLLegendElement { - [CEReactions] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString align; }; partial interface HTMLLIElement { - [CEReactions] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString type; }; partial interface HTMLLinkElement { - [CEReactions] attribute DOMString charset; - [CEReactions] attribute DOMString rev; - [CEReactions] attribute DOMString target; + [CEReactions, Reflect] attribute DOMString charset; + [CEReactions, Reflect] attribute DOMString rev; + [CEReactions, Reflect] attribute DOMString target; }; partial interface HTMLMenuElement { - [CEReactions] attribute boolean compact; + [CEReactions, Reflect] attribute boolean compact; }; partial interface HTMLMetaElement { - [CEReactions] attribute DOMString scheme; + [CEReactions, Reflect] attribute DOMString scheme; }; partial interface HTMLObjectElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString archive; - [CEReactions] attribute DOMString code; - [CEReactions] attribute boolean declare; - [CEReactions] attribute unsigned long hspace; - [CEReactions] attribute DOMString standby; - [CEReactions] attribute unsigned long vspace; - [CEReactions] attribute DOMString codeBase; - [CEReactions] attribute DOMString codeType; - [CEReactions] attribute DOMString useMap; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString archive; + [CEReactions, Reflect] attribute DOMString code; + [CEReactions, Reflect] attribute boolean declare; + [CEReactions, Reflect] attribute unsigned long hspace; + [CEReactions, Reflect] attribute DOMString standby; + [CEReactions, Reflect] attribute unsigned long vspace; + [CEReactions, ReflectURL] attribute DOMString codeBase; + [CEReactions, Reflect] attribute DOMString codeType; + [CEReactions, Reflect] attribute DOMString useMap; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString border; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString border; }; partial interface HTMLOListElement { - [CEReactions] attribute boolean compact; + [CEReactions, Reflect] attribute boolean compact; }; partial interface HTMLParagraphElement { - [CEReactions] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString align; }; [Exposed=Window] interface HTMLParamElement : HTMLElement { [HTMLConstructor] constructor(); - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString value; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString valueType; + [CEReactions, Reflect] attribute DOMString name; + [CEReactions, Reflect] attribute DOMString value; + [CEReactions, Reflect] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString valueType; }; partial interface HTMLPreElement { - [CEReactions] attribute long width; + [CEReactions, Reflect] attribute long width; }; partial interface HTMLStyleElement { - [CEReactions] attribute DOMString type; + [CEReactions, Reflect] attribute DOMString type; }; partial interface HTMLScriptElement { - [CEReactions] attribute DOMString charset; - [CEReactions] attribute DOMString event; - [CEReactions] attribute DOMString htmlFor; + [CEReactions, Reflect] attribute DOMString charset; + [CEReactions, Reflect] attribute DOMString event; + [CEReactions, Reflect="for"] attribute DOMString htmlFor; }; partial interface HTMLTableElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString border; - [CEReactions] attribute DOMString frame; - [CEReactions] attribute DOMString rules; - [CEReactions] attribute DOMString summary; - [CEReactions] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString border; + [CEReactions, Reflect] attribute DOMString frame; + [CEReactions, Reflect] attribute DOMString rules; + [CEReactions, Reflect] attribute DOMString summary; + [CEReactions, Reflect] attribute DOMString width; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString bgColor; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString cellPadding; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString cellSpacing; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString bgColor; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString cellPadding; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString cellSpacing; }; partial interface HTMLTableSectionElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute DOMString vAlign; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect="char"] attribute DOMString ch; + [CEReactions, Reflect="charoff"] attribute DOMString chOff; + [CEReactions, Reflect] attribute DOMString vAlign; }; partial interface HTMLTableCellElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString axis; - [CEReactions] attribute DOMString height; - [CEReactions] attribute DOMString width; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect] attribute DOMString axis; + [CEReactions, Reflect] attribute DOMString height; + [CEReactions, Reflect] attribute DOMString width; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute boolean noWrap; - [CEReactions] attribute DOMString vAlign; + [CEReactions, Reflect="char"] attribute DOMString ch; + [CEReactions, Reflect="charoff"] attribute DOMString chOff; + [CEReactions, Reflect] attribute boolean noWrap; + [CEReactions, Reflect] attribute DOMString vAlign; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString bgColor; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString bgColor; }; partial interface HTMLTableRowElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute DOMString vAlign; + [CEReactions, Reflect] attribute DOMString align; + [CEReactions, Reflect="char"] attribute DOMString ch; + [CEReactions, Reflect="charoff"] attribute DOMString chOff; + [CEReactions, Reflect] attribute DOMString vAlign; - [CEReactions] attribute [LegacyNullToEmptyString] DOMString bgColor; + [CEReactions, Reflect] attribute [LegacyNullToEmptyString] DOMString bgColor; }; partial interface HTMLUListElement { - [CEReactions] attribute boolean compact; - [CEReactions] attribute DOMString type; + [CEReactions, Reflect] attribute boolean compact; + [CEReactions, Reflect] attribute DOMString type; }; partial interface Document { diff --git a/test/fixtures/wpt/interfaces/performance-timeline.idl b/test/fixtures/wpt/interfaces/performance-timeline.idl index 6ef84b6cbb8e60..f06ed9adb6c649 100644 --- a/test/fixtures/wpt/interfaces/performance-timeline.idl +++ b/test/fixtures/wpt/interfaces/performance-timeline.idl @@ -22,8 +22,8 @@ interface PerformanceEntry { }; callback PerformanceObserverCallback = undefined (PerformanceObserverEntryList entries, - PerformanceObserver observer, - optional PerformanceObserverCallbackOptions options = {}); + PerformanceObserver observer, + optional PerformanceObserverCallbackOptions options = {}); [Exposed=(Window,Worker)] interface PerformanceObserver { constructor(PerformanceObserverCallback callback); diff --git a/test/fixtures/wpt/interfaces/resource-timing.idl b/test/fixtures/wpt/interfaces/resource-timing.idl index 66f2841d744af3..ba8e3953b49705 100644 --- a/test/fixtures/wpt/interfaces/resource-timing.idl +++ b/test/fixtures/wpt/interfaces/resource-timing.idl @@ -22,12 +22,17 @@ interface PerformanceResourceTiming : PerformanceEntry { readonly attribute DOMHighResTimeStamp firstInterimResponseStart; readonly attribute DOMHighResTimeStamp responseStart; readonly attribute DOMHighResTimeStamp responseEnd; + readonly attribute DOMHighResTimeStamp workerRouterEvaluationStart; + readonly attribute DOMHighResTimeStamp workerCacheLookupStart; + readonly attribute DOMString workerMatchedRouterSource; + readonly attribute DOMString workerFinalRouterSource; readonly attribute unsigned long long transferSize; readonly attribute unsigned long long encodedBodySize; readonly attribute unsigned long long decodedBodySize; readonly attribute unsigned short responseStatus; readonly attribute RenderBlockingStatusType renderBlockingStatus; readonly attribute DOMString contentType; + readonly attribute DOMString contentEncoding; [Default] object toJSON(); }; @@ -36,8 +41,7 @@ enum RenderBlockingStatusType { "non-blocking" }; -partial interface Performance { - undefined clearResourceTimings (); +partial interface Performance { undefined clearResourceTimings (); undefined setResourceTimingBufferSize (unsigned long maxSize); attribute EventHandler onresourcetimingbufferfull; }; diff --git a/test/fixtures/wpt/interfaces/streams.idl b/test/fixtures/wpt/interfaces/streams.idl index ab9be033e43ba0..8abc8f5cfda9fe 100644 --- a/test/fixtures/wpt/interfaces/streams.idl +++ b/test/fixtures/wpt/interfaces/streams.idl @@ -17,7 +17,7 @@ interface ReadableStream { Promise pipeTo(WritableStream destination, optional StreamPipeOptions options = {}); sequence tee(); - async iterable(optional ReadableStreamIteratorOptions options = {}); + async_iterable(optional ReadableStreamIteratorOptions options = {}); }; typedef (ReadableStreamDefaultReader or ReadableStreamBYOBReader) ReadableStreamReader; diff --git a/test/fixtures/wpt/interfaces/web-locks.idl b/test/fixtures/wpt/interfaces/web-locks.idl index 14bc3a22cc395f..00648cc3b1e5f4 100644 --- a/test/fixtures/wpt/interfaces/web-locks.idl +++ b/test/fixtures/wpt/interfaces/web-locks.idl @@ -1,3 +1,8 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: Web Locks API (https://w3c.github.io/web-locks/) + [SecureContext] interface mixin NavigatorLocks { readonly attribute LockManager locks; @@ -5,7 +10,7 @@ interface mixin NavigatorLocks { Navigator includes NavigatorLocks; WorkerNavigator includes NavigatorLocks; -[SecureContext, Exposed=(Window,Worker)] +[SecureContext, Exposed=(Window,Worker,SharedStorageWorklet)] interface LockManager { Promise request(DOMString name, LockGrantedCallback callback); @@ -38,7 +43,7 @@ dictionary LockInfo { DOMString clientId; }; -[SecureContext, Exposed=(Window,Worker)] +[SecureContext, Exposed=(Window,Worker,SharedStorageWorklet)] interface Lock { readonly attribute DOMString name; readonly attribute LockMode mode; diff --git a/test/fixtures/wpt/interfaces/webcrypto-modern-algos.idl b/test/fixtures/wpt/interfaces/webcrypto-modern-algos.idl new file mode 100644 index 00000000000000..aeb1d650b7d732 --- /dev/null +++ b/test/fixtures/wpt/interfaces/webcrypto-modern-algos.idl @@ -0,0 +1,118 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: Modern Algorithms in the Web Cryptography API (https://wicg.github.io/webcrypto-modern-algos/) + +[SecureContext,Exposed=(Window,Worker)] +partial interface SubtleCrypto { + Promise encapsulateKey( + AlgorithmIdentifier encapsulationAlgorithm, + CryptoKey encapsulationKey, + AlgorithmIdentifier sharedKeyAlgorithm, + boolean extractable, + sequence keyUsages + ); + Promise encapsulateBits( + AlgorithmIdentifier encapsulationAlgorithm, + CryptoKey encapsulationKey + ); + + Promise decapsulateKey( + AlgorithmIdentifier decapsulationAlgorithm, + CryptoKey decapsulationKey, + BufferSource ciphertext, + AlgorithmIdentifier sharedKeyAlgorithm, + boolean extractable, + sequence keyUsages + ); + Promise decapsulateBits( + AlgorithmIdentifier decapsulationAlgorithm, + CryptoKey decapsulationKey, + BufferSource ciphertext + ); + + Promise getPublicKey( + CryptoKey key, + sequence keyUsages + ); + + static boolean supports(DOMString operation, + AlgorithmIdentifier algorithm, + optional unsigned long? length = null); + static boolean supports(DOMString operation, + AlgorithmIdentifier algorithm, + AlgorithmIdentifier additionalAlgorithm); +}; + +enum KeyFormat { "raw-public", "raw-private", "raw-seed", "raw-secret", "raw", "spki", "pkcs8", "jwk" }; + +enum KeyUsage { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey", "encapsulateKey", "encapsulateBits", "decapsulateKey", "decapsulateBits" }; + +dictionary EncapsulatedKey { + CryptoKey sharedKey; + ArrayBuffer ciphertext; +}; + +dictionary EncapsulatedBits { + ArrayBuffer sharedKey; + ArrayBuffer ciphertext; +}; + +partial dictionary JsonWebKey { + // The following fields are defined in draft-ietf-cose-dilithium-08 + DOMString pub; + DOMString priv; +}; + +dictionary ContextParams : Algorithm { + BufferSource context; +}; + +dictionary AeadParams : Algorithm { + required BufferSource iv; + BufferSource additionalData; + [EnforceRange] octet tagLength; +}; + +dictionary CShakeParams : Algorithm { + required [EnforceRange] unsigned long outputLength; + BufferSource functionName; + BufferSource customization; +}; + +dictionary TurboShakeParams : Algorithm { + required [EnforceRange] unsigned long outputLength; + [EnforceRange] octet domainSeparation; +}; + +dictionary KangarooTwelveParams : Algorithm { + required [EnforceRange] unsigned long outputLength; + BufferSource customization; +}; + +dictionary KmacKeyGenParams : Algorithm { + [EnforceRange] unsigned long length; +}; + +dictionary KmacImportParams : Algorithm { + [EnforceRange] unsigned long length; +}; + +dictionary KmacKeyAlgorithm : KeyAlgorithm { + required unsigned long length; +}; + +dictionary KmacParams : Algorithm { + required [EnforceRange] unsigned long outputLength; + BufferSource customization; +}; + +dictionary Argon2Params : Algorithm { + required BufferSource nonce; + required [EnforceRange] unsigned long parallelism; + required [EnforceRange] unsigned long memory; + required [EnforceRange] unsigned long passes; + [EnforceRange] octet version; + BufferSource secretValue; + BufferSource associatedData; +}; diff --git a/test/fixtures/wpt/interfaces/webcrypto-secure-curves.idl b/test/fixtures/wpt/interfaces/webcrypto-secure-curves.idl new file mode 100644 index 00000000000000..01bb290b747827 --- /dev/null +++ b/test/fixtures/wpt/interfaces/webcrypto-secure-curves.idl @@ -0,0 +1,8 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: Secure Curves in the Web Cryptography API (https://wicg.github.io/webcrypto-secure-curves/) + +dictionary Ed448Params : Algorithm { + BufferSource context; +}; diff --git a/test/fixtures/wpt/interfaces/webcrypto.idl b/test/fixtures/wpt/interfaces/webcrypto.idl index ff7a89cd0d51be..ebb9cf5718b98d 100644 --- a/test/fixtures/wpt/interfaces/webcrypto.idl +++ b/test/fixtures/wpt/interfaces/webcrypto.idl @@ -1,7 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into webref // (https://github.com/w3c/webref) -// Source: Web Cryptography API (https://w3c.github.io/webcrypto/) +// Source: Web Cryptography API Level 2 (https://w3c.github.io/webcrypto/) partial interface mixin WindowOrWorkerGlobalScope { [SameObject] readonly attribute Crypto crypto; @@ -28,8 +28,6 @@ dictionary KeyAlgorithm { enum KeyType { "public", "private", "secret" }; -enum KeyUsage { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" }; - [SecureContext,Exposed=(Window,Worker),Serializable] interface CryptoKey { readonly attribute KeyType type; @@ -38,8 +36,6 @@ interface CryptoKey { readonly attribute object usages; }; -enum KeyFormat { "raw", "spki", "pkcs8", "jwk" }; - [SecureContext,Exposed=(Window,Worker)] interface SubtleCrypto { Promise encrypt( diff --git a/test/fixtures/wpt/interfaces/webidl.idl b/test/fixtures/wpt/interfaces/webidl.idl index f3db91096ac1be..651c1922115026 100644 --- a/test/fixtures/wpt/interfaces/webidl.idl +++ b/test/fixtures/wpt/interfaces/webidl.idl @@ -3,6 +3,19 @@ // (https://github.com/w3c/webref) // Source: Web IDL Standard (https://webidl.spec.whatwg.org/) +[Exposed=*, Serializable] +interface QuotaExceededError : DOMException { + constructor(optional DOMString message = "", optional QuotaExceededErrorOptions options = {}); + + readonly attribute double? quota; + readonly attribute double? requested; +}; + +dictionary QuotaExceededErrorOptions { + double quota; + double requested; +}; + typedef (Int8Array or Int16Array or Int32Array or Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or BigInt64Array or BigUint64Array or diff --git a/test/fixtures/wpt/resources/example.pdf b/test/fixtures/wpt/resources/example.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7bad251ba7e08efc9c383d88518367a6f204cdd6 GIT binary patch literal 618 zcmZvZK~IA)7>4it74LNgS*%f_;7IJuyXdP>;Fl0)@@1ovi$?2a= wCDetVJuafgL)JM{t*y&4gn84@AEe?r!rSV@Lc`y%ah1#F>_TmS$7 literal 0 HcmV?d00001 diff --git a/test/fixtures/wpt/resources/idlharness.js b/test/fixtures/wpt/resources/idlharness.js index 2eb710c1827cda..57cefedc22a182 100644 --- a/test/fixtures/wpt/resources/idlharness.js +++ b/test/fixtures/wpt/resources/idlharness.js @@ -1398,7 +1398,7 @@ IdlInterface.prototype.default_to_json_operation = function() { if (I.has_default_to_json_regular_operation()) { isDefault = true; for (const m of I.members) { - if (m.special !== "static" && m.type == "attribute" && I.array.is_json_type(m.idlType)) { + if (!m.untested && m.special !== "static" && m.type == "attribute" && I.array.is_json_type(m.idlType)) { map.set(m.name, m.idlType); } } diff --git a/test/fixtures/wpt/resources/testdriver-actions.js b/test/fixtures/wpt/resources/testdriver-actions.js index edb4759954d4c3..616a90b36b1b27 100644 --- a/test/fixtures/wpt/resources/testdriver-actions.js +++ b/test/fixtures/wpt/resources/testdriver-actions.js @@ -252,7 +252,7 @@ */ addTick: function(duration) { this.tickIdx += 1; - if (duration) { + if (duration !== undefined && duration !== null) { this.pause(duration); } return this; @@ -279,6 +279,10 @@ /** * Create a keyDown event for the current default key source * + * To send special keys, send the respective key's codepoint, + * as defined by `WebDriver + * `_. + * * @param {String} key - Key to press * @param {String?} sourceName - Named key source to use or null for the default key source * @returns {Actions} @@ -292,6 +296,10 @@ /** * Create a keyUp event for the current default key source * + * To send special keys, send the respective key's codepoint, + * as defined by `WebDriver + * `_. + * * @param {String} key - Key to release * @param {String?} sourceName - Named key source to use or null for the default key source * @returns {Actions} @@ -536,7 +544,7 @@ tick = actions.addTick().tickIdx; } let moveAction = {type: "pointerMove", x, y, origin}; - if (duration) { + if (duration !== undefined && duration !== null) { moveAction.duration = duration; } let actionProperties = setPointerProperties(moveAction, width, height, pressure, @@ -581,7 +589,7 @@ tick = actions.addTick().tickIdx; } this.actions.set(tick, {type: "scroll", x, y, deltaX, deltaY, origin}); - if (duration) { + if (duration !== undefined && duration !== null) { this.actions.get(tick).duration = duration; } }, diff --git a/test/fixtures/wpt/resources/testdriver.js b/test/fixtures/wpt/resources/testdriver.js index 5b390dedeb72bb..4402fbd2235318 100644 --- a/test/fixtures/wpt/resources/testdriver.js +++ b/test/fixtures/wpt/resources/testdriver.js @@ -23,6 +23,14 @@ } } + function assertTestIsTentative(){ + const testPath = location.pathname; + const tentative = testPath.includes('.tentative.') || testPath.includes('/tentative/'); + if (!tentative) { + throw new Error("Method in testdriver.js intended for tentative tests used in non-tentative test"); + } + } + function getInViewCenterPoint(rect) { var left = Math.max(0, rect.left); var right = Math.min(window.innerWidth, rect.right); @@ -769,6 +777,78 @@ }, } }, + /** + * `speculation `_ module. + */ + speculation: { + /** + * `speculation.PrefetchStatusUpdated `_ + * event. + */ + prefetch_status_updated: { + /** + * @typedef {object} PrefetchStatusUpdated + * `speculation.PrefetchStatusUpdatedParameters `_ + * event. + */ + + /** + * Subscribes to the event. Events will be emitted only if + * there is a subscription for the event. This method does + * not add actual listeners. To listen to the event, use the + * `on` or `once` methods. The buffered events will be + * emitted before the command promise is resolved. + * + * @param {object} [params] Parameters for the subscription. + * @param {null|Array.<(Context)>} [params.contexts] The + * optional contexts parameter specifies which browsing + * contexts to subscribe to the event on. It should be + * either an array of Context objects, or null. If null, the + * event will be subscribed to globally. If omitted, the + * event will be subscribed to on the current browsing + * context. + * @returns {Promise<(function(): Promise)>} Callback + * for unsubscribing from the created subscription. + */ + subscribe: async function(params = {}) { + assertBidiIsEnabled(); + return window.test_driver_internal.bidi.speculation + .prefetch_status_updated.subscribe(params); + }, + /** + * Adds an event listener for the event. + * + * @param {function(PrefetchStatusUpdated): void} callback The + * callback to be called when the event is emitted. The + * callback is called with the event object as a parameter. + * @returns {function(): void} A function that removes the + * added event listener when called. + */ + on: function(callback) { + assertBidiIsEnabled(); + return window.test_driver_internal.bidi.speculation + .prefetch_status_updated.on(callback); + }, + /** + * Adds an event listener for the event that is only called + * once and removed afterward. + * + * @return {Promise} The promise which + * is resolved with the event object when the event is emitted. + */ + once: function() { + assertBidiIsEnabled(); + return new Promise(resolve => { + const remove_handler = + window.test_driver_internal.bidi.speculation + .prefetch_status_updated.on(event => { + resolve(event); + remove_handler(); + }); + }); + } + } + }, /** * `emulation `_ module. */ @@ -882,6 +962,61 @@ return window.test_driver_internal.bidi.emulation.set_screen_orientation_override( params); }, + /** + * Overrides the touch configuration for the specified browsing + * contexts. + * Matches the `emulation.setTouchOverride + * `_ + * WebDriver BiDi command. + * + * @example + * await test_driver.bidi.emulation.set_touch_override({ + * maxTouchPoints: 5 + * }); + * + * @param {object} params - Parameters for the command. + * @param {null|number} params.maxTouchPoints - The + * maximum number of simultaneous touch points to support. + * If null or omitted, the override will be removed. + * @param {null|Array.<(Context)>} [params.contexts] The + * optional contexts parameter specifies which browsing contexts + * to set the touch override on. It should be either an array of + * Context objects (window or browsing context id), or null. If + * null or omitted, the override will be set on the current + * browsing context. + * @returns {Promise} Resolves when the touch + * override is successfully set. + */ + set_touch_override: function (params) { + assertBidiIsEnabled(); + return window.test_driver_internal.bidi.emulation.set_touch_override( + params); + }, + }, + /** + * `user_agent_client_hints `_ module. + */ + user_agent_client_hints: { + /** + * Overrides the user agent client hints configuration for the specified browsing + * contexts. Matches the `userAgentClientHints.setClientHintsOverride + * `_ + * WebDriver BiDi command. + * + * @param {object} params - Parameters for the command. + * @param {null|object} params.clientHints - The client hints to override. + * Matches the `userAgentClientHints.ClientHints` type. + * If null or omitted, the override will be removed. + * @param {null|Array.<(Context)>} [params.contexts] The + * optional contexts parameter specifies which browsing contexts + * to set the override on. + * @returns {Promise} Resolves when the override is successfully set. + */ + set_client_hints_override: function (params) { + assertBidiIsEnabled(); + return window.test_driver_internal.bidi.user_agent_client_hints.set_client_hints_override( + params); + } }, /** * `log `_ module. @@ -973,9 +1108,12 @@ * @param {PermissionState} params.state - a `PermissionState * `_ * value. - * @param {string} [params.origin] - an optional `origin` string to set the + * @param {string} [params.origin] - an optional top-level `origin` string to set the * permission for. If omitted, the permission is set for the * current window's origin. + * @param {string} [params.embeddedOrigin] - an optional embedded `origin` string to set the + * permission for. If omitted, the top-level `origin` is used as the + * embedded origin. * @returns {Promise} fulfilled after the permission is set, or rejected if setting * the permission fails. */ @@ -1191,6 +1329,34 @@ return role; }, + /** + * Get accessibility properties for a DOM element. + * + * @param {Element} element + * @returns {Promise} fulfilled after the accessibility properties are + * returned, or rejected in the cases the WebDriver + * command errors + */ + get_accessibility_properties_for_element: async function(element) { + assertTestIsTentative(); + let acc = await window.test_driver_internal.get_accessibility_properties_for_element(element); + return acc; + }, + + /** + * Get properties for an accessibility node. + * + * @param {String} accId + * @returns {Promise} fulfilled after the accessibility properties are + * returned, or rejected in the cases the WebDriver + * command errors + */ + get_accessibility_properties_for_accessibility_node: async function(accId) { + assertTestIsTentative(); + let acc = await window.test_driver_internal.get_accessibility_properties_for_accessibility_node(accId); + return acc; + }, + /** * Send keys to an element. * @@ -2169,6 +2335,69 @@ */ clear_display_features: function(context=null) { return window.test_driver_internal.clear_display_features(context); + }, + + /** + * Gets the current globally-applied privacy control status + * + * @returns {Promise} Fulfils with an object with boolean property `gpc` + * that encodes the current "do not sell or share" + * signal the browser is configured to convey. + */ + get_global_privacy_control: function() { + return window.test_driver_internal.get_global_privacy_control(); + }, + + /** + * Gets the current globally-applied privacy control status + * + * @param {bool} newValue - The a boolean that is true if the browers + * should convey a "do not sell or share" signal + * and false otherwise + * + * @returns {Promise} Fulfils with an object with boolean property `gpc` + * that encodes the new "do not sell or share" + * after applying the new value. + */ + set_global_privacy_control: function(newValue) { + return window.test_driver_internal.set_global_privacy_control(newValue); + }, + + /** + * Installs a WebExtension. + * + * Matches the `Install WebExtension + * `_ + * WebDriver command. + * + * @param {Object} params - Parameters for loading the extension. + * @param {String} params.type - A type such as "path", "archivePath", or "base64". + * + * @param {String} params.path - The path to the extension's resources if type "path" or "archivePath" is specified. + * + * @param {String} params.value - The base64 encoded value of the extension's resources if type "base64" is specified. + * + * @returns {Promise} Returns the extension identifier as defined in the spec. + * Rejected if the extension fails to load. + */ + install_web_extension: function(params) { + return window.test_driver_internal.install_web_extension(params); + }, + + /** + * Uninstalls a WebExtension. + * + * Matches the `Uninstall WebExtension + * `_ + * WebDriver command. + * + * @param {String} extension_id - The extension identifier. + * + * @returns {Promise} Fulfilled after the extension has been removed. + * Rejected in case the WebDriver command errors out. + */ + uninstall_web_extension: function(extension_id) { + return window.test_driver_internal.uninstall_web_extension(extension_id); } }; @@ -2252,6 +2481,16 @@ set_screen_orientation_override: function (params) { throw new Error( "bidi.emulation.set_screen_orientation_override is not implemented by testdriver-vendor.js"); + }, + set_touch_override: function (params) { + throw new Error( + "bidi.emulation.set_touch_override is not implemented by testdriver-vendor.js"); + } + }, + user_agent_client_hints: { + set_client_hints_override: function (params) { + throw new Error( + "bidi.user_agent_client_hints.set_client_hints_override is not implemented by testdriver-vendor.js"); } }, log: { @@ -2271,6 +2510,18 @@ throw new Error( "bidi.permissions.set_permission() is not implemented by testdriver-vendor.js"); } + }, + speculation: { + prefetch_status_updated: { + async subscribe() { + throw new Error( + 'bidi.speculation.prefetch_status_updated.subscribe is not implemented by testdriver-vendor.js'); + }, + on() { + throw new Error( + 'bidi.speculation.prefetch_status_updated.on is not implemented by testdriver-vendor.js'); + } + }, } }, @@ -2304,6 +2555,14 @@ throw new Error("get_computed_name is a testdriver.js function which cannot be run in this context."); }, + async get_accessibility_properties_for_element(element) { + throw new Error("get_accessibility_properties_for_element is a testdriver.js function which cannot be run in this context."); + }, + + async get_accessibility_properties_for_accessibility_node(accId) { + throw new Error("get_accessibility_properties_for_accessibility_node is a testdriver.js function which cannot be run in this context."); + }, + async send_keys(element, keys) { if (this.in_automation) { throw new Error("send_keys() is not implemented by testdriver-vendor.js"); @@ -2486,6 +2745,14 @@ async clear_display_features(context=null) { throw new Error("clear_display_features() is not implemented by testdriver-vendor.js"); + }, + + async set_global_privacy_control(newValue) { + throw new Error("set_global_privacy_control() is not implemented by testdriver-vendor.js"); + }, + + async get_global_privacy_control() { + throw new Error("get_global_privacy_control() is not implemented by testdriver-vendor.js"); } }; })(); diff --git a/test/fixtures/wpt/resources/testharness.js b/test/fixtures/wpt/resources/testharness.js index f495b62458ba75..c7ce4f51e1db07 100644 --- a/test/fixtures/wpt/resources/testharness.js +++ b/test/fixtures/wpt/resources/testharness.js @@ -5144,7 +5144,7 @@ table#results.assertions > tbody > tr > td:last-child {\ width:35%;\ }\ \ -table#results > thead > > tr > th {\ +table#results > thead > tr > th {\ padding:0;\ padding-bottom:0.5em;\ border-bottom:medium solid black;\ diff --git a/test/fixtures/wpt/resources/web-extensions-helper.js b/test/fixtures/wpt/resources/web-extensions-helper.js new file mode 100644 index 00000000000000..57a40fe84dae0a --- /dev/null +++ b/test/fixtures/wpt/resources/web-extensions-helper.js @@ -0,0 +1,40 @@ +// testharness file with WebExtensions utilities + +/** + * Loads the WebExtension at the path specified and runs the tests defined in the extension's resources. + * Listens to messages sent from the user agent and converts the `browser.test` assertions + * into testharness.js assertions. + * + * @param {string} extensionPath - a path to the extension's resources. + */ + +setup({ explicit_done: true }) +globalThis.runTestsWithWebExtension = function(extensionPath) { + test_driver.install_web_extension({ + type: "path", + path: extensionPath + }) + .then((result) => { + let test; + browser.test.onTestStarted.addListener((data) => { + test = async_test(data.testName) + }) + + browser.test.onTestFinished.addListener((data) => { + test.step(() => { + let description = data.message ? `${data.assertionDescription}. ${data.message}` : data.assertionDescription + assert_true(data.result, description) + }) + + test.done() + + if (!data.result) { + test.set_status(test.FAIL) + } + + if (!data.remainingTests) { + test_driver.uninstall_web_extension(result.extension).then(() => { done() }) + } + }) + }) +} diff --git a/test/fixtures/wpt/resources/webidl2/lib/VERSION.md b/test/fixtures/wpt/resources/webidl2/lib/VERSION.md index 5a3726c6c00fe5..2614a8d194be62 100644 --- a/test/fixtures/wpt/resources/webidl2/lib/VERSION.md +++ b/test/fixtures/wpt/resources/webidl2/lib/VERSION.md @@ -1 +1 @@ -Currently using webidl2.js@6889aee6fc7d65915ab1267825248157dbc50486. +Currently using webidl2.js@e6d8ab852ec4e76596f6e308eb7f2efc8b613bfd. diff --git a/test/fixtures/wpt/resources/webidl2/lib/webidl2.js b/test/fixtures/wpt/resources/webidl2/lib/webidl2.js index 7161def899cf24..bae0b2047595d0 100644 --- a/test/fixtures/wpt/resources/webidl2/lib/webidl2.js +++ b/test/fixtures/wpt/resources/webidl2/lib/webidl2.js @@ -17,7 +17,7 @@ return /******/ (() => { // webpackBootstrap __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "parse": () => (/* binding */ parse) +/* harmony export */ parse: () => (/* binding */ parse) /* harmony export */ }); /* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); /* harmony import */ var _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(15); @@ -46,11 +46,22 @@ __webpack_require__.r(__webpack_exports__); +/** @typedef {'callbackInterface'|'dictionary'|'interface'|'mixin'|'namespace'} ExtendableInterfaces */ +/** @typedef {{ extMembers?: import("./productions/container.js").AllowedMember[]}} Extension */ +/** @typedef {Partial>} Extensions */ + +/** + * Parser options. + * @typedef {Object} ParserOptions + * @property {string} [sourceName] + * @property {boolean} [concrete] + * @property {Function[]} [productions] + * @property {Extensions} [extensions] + */ + /** * @param {Tokeniser} tokeniser - * @param {object} options - * @param {boolean} [options.concrete] - * @param {Function[]} [options.productions] + * @param {ParserOptions} options */ function parseByTokens(tokeniser, options) { const source = tokeniser.source; @@ -67,7 +78,9 @@ function parseByTokens(tokeniser, options) { const callback = consume("callback"); if (!callback) return; if (tokeniser.probe("interface")) { - return _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__.CallbackInterface.parse(tokeniser, callback); + return _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__.CallbackInterface.parse(tokeniser, callback, { + ...options?.extensions?.callbackInterface, + }); } return _productions_callback_js__WEBPACK_IMPORTED_MODULE_5__.CallbackFunction.parse(tokeniser, callback); } @@ -75,20 +88,32 @@ function parseByTokens(tokeniser, options) { function interface_(opts) { const base = consume("interface"); if (!base) return; - const ret = - _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__.Mixin.parse(tokeniser, base, opts) || - _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__.Interface.parse(tokeniser, base, opts) || - error("Interface has no proper body"); - return ret; + return ( + _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__.Mixin.parse(tokeniser, base, { + ...opts, + ...options?.extensions?.mixin, + }) || + _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__.Interface.parse(tokeniser, base, { + ...opts, + ...options?.extensions?.interface, + }) || + error("Interface has no proper body") + ); } function partial() { const partial = consume("partial"); if (!partial) return; return ( - _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser, { partial }) || + _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser, { + partial, + ...options?.extensions?.dictionary, + }) || interface_({ partial }) || - _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser, { partial }) || + _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser, { + partial, + ...options?.extensions?.namespace, + }) || error("Partial doesn't apply to anything") ); } @@ -107,11 +132,11 @@ function parseByTokens(tokeniser, options) { callback() || interface_() || partial() || - _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser) || + _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser, options?.extensions?.dictionary) || _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__.Enum.parse(tokeniser) || _productions_typedef_js__WEBPACK_IMPORTED_MODULE_4__.Typedef.parse(tokeniser) || _productions_includes_js__WEBPACK_IMPORTED_MODULE_2__.Includes.parse(tokeniser) || - _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser) + _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser, options?.extensions?.namespace) ); } @@ -134,6 +159,7 @@ function parseByTokens(tokeniser, options) { } return defs; } + const res = definitions(); if (tokeniser.position < source.length) error("Unrecognised tokens"); return res; @@ -141,11 +167,7 @@ function parseByTokens(tokeniser, options) { /** * @param {string} str - * @param {object} [options] - * @param {*} [options.sourceName] - * @param {boolean} [options.concrete] - * @param {Function[]} [options.productions] - * @return {import("./productions/base.js").Base[]} + * @param {ParserOptions} [options] */ function parse(str, options = {}) { const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__.Tokeniser(str); @@ -163,11 +185,11 @@ function parse(str, options = {}) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Tokeniser": () => (/* binding */ Tokeniser), -/* harmony export */ "WebIDLParseError": () => (/* binding */ WebIDLParseError), -/* harmony export */ "argumentNameKeywords": () => (/* binding */ argumentNameKeywords), -/* harmony export */ "stringTypes": () => (/* binding */ stringTypes), -/* harmony export */ "typeNameKeywords": () => (/* binding */ typeNameKeywords) +/* harmony export */ Tokeniser: () => (/* binding */ Tokeniser), +/* harmony export */ WebIDLParseError: () => (/* binding */ WebIDLParseError), +/* harmony export */ argumentNameKeywords: () => (/* binding */ argumentNameKeywords), +/* harmony export */ stringTypes: () => (/* binding */ stringTypes), +/* harmony export */ typeNameKeywords: () => (/* binding */ typeNameKeywords) /* harmony export */ }); /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -191,6 +213,7 @@ const tokenRe = { const typeNameKeywords = [ "ArrayBuffer", + "SharedArrayBuffer", "DataView", "Int8Array", "Int16Array", @@ -201,6 +224,7 @@ const typeNameKeywords = [ "Uint8ClampedArray", "BigInt64Array", "BigUint64Array", + "Float16Array", "Float32Array", "Float64Array", "any", @@ -243,6 +267,8 @@ const nonRegexTerminals = [ "NaN", "ObservableArray", "Promise", + "async_iterable", + "async_sequence", "bigint", "boolean", "byte", @@ -327,10 +353,10 @@ function tokenise(str) { if (result !== -1) { if (reserved.includes(token.value)) { const message = `${(0,_productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)( - token.value + token.value, )} is a reserved identifier and must not be used.`; throw new WebIDLParseError( - (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(tokens, lastIndex, null, message) + (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(tokens, lastIndex, null, message), ); } else if (nonRegexTerminals.includes(token.value)) { token.type = "inline"; @@ -414,7 +440,7 @@ class Tokeniser { */ error(message) { throw new WebIDLParseError( - (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(this.source, this.position, this.current, message) + (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(this.source, this.position, this.current, message), ); } @@ -522,8 +548,8 @@ class WebIDLParseError extends Error { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "syntaxError": () => (/* binding */ syntaxError), -/* harmony export */ "validationError": () => (/* binding */ validationError) +/* harmony export */ syntaxError: () => (/* binding */ syntaxError), +/* harmony export */ validationError: () => (/* binding */ validationError) /* harmony export */ }); /** * @param {string} text @@ -572,7 +598,7 @@ function error( current, message, kind, - { level = "error", autofix, ruleName } = {} + { level = "error", autofix, ruleName } = {}, ) { /** * @param {number} count @@ -606,11 +632,11 @@ function error( source[position].type !== "eof" ? source[position].line : source.length > 1 - ? source[position - 1].line - : 1; + ? source[position - 1].line + : 1; const precedingLastLine = lastLine( - tokensToText(sliceTokens(-maxTokens), { precedes: true }) + tokensToText(sliceTokens(-maxTokens), { precedes: true }), ); const subsequentTokens = sliceTokens(maxTokens); @@ -625,7 +651,7 @@ function error( const grammaticalContext = current && current.name ? `, ${contextType} \`${current.partial ? "partial " : ""}${contextAsText( - current + current, )}\`` : ""; const context = `${kind} error at line ${line}${inSourceName}${grammaticalContext}:\n${sourceContext}`; @@ -659,7 +685,7 @@ function validationError( current, ruleName, message, - options = {} + options = {}, ) { options.ruleName = ruleName; return error( @@ -668,7 +694,7 @@ function validationError( current, message, "Validation", - options + options, ); } @@ -679,21 +705,21 @@ function validationError( __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "argument_list": () => (/* binding */ argument_list), -/* harmony export */ "autoParenter": () => (/* binding */ autoParenter), -/* harmony export */ "autofixAddExposedWindow": () => (/* binding */ autofixAddExposedWindow), -/* harmony export */ "const_data": () => (/* binding */ const_data), -/* harmony export */ "const_value": () => (/* binding */ const_value), -/* harmony export */ "findLastIndex": () => (/* binding */ findLastIndex), -/* harmony export */ "getFirstToken": () => (/* binding */ getFirstToken), -/* harmony export */ "getLastIndentation": () => (/* binding */ getLastIndentation), -/* harmony export */ "getMemberIndentation": () => (/* binding */ getMemberIndentation), -/* harmony export */ "list": () => (/* binding */ list), -/* harmony export */ "primitive_type": () => (/* binding */ primitive_type), -/* harmony export */ "return_type": () => (/* binding */ return_type), -/* harmony export */ "stringifier": () => (/* binding */ stringifier), -/* harmony export */ "type_with_extended_attributes": () => (/* binding */ type_with_extended_attributes), -/* harmony export */ "unescape": () => (/* binding */ unescape) +/* harmony export */ argument_list: () => (/* binding */ argument_list), +/* harmony export */ autoParenter: () => (/* binding */ autoParenter), +/* harmony export */ autofixAddExposedWindow: () => (/* binding */ autofixAddExposedWindow), +/* harmony export */ const_data: () => (/* binding */ const_data), +/* harmony export */ const_value: () => (/* binding */ const_value), +/* harmony export */ findLastIndex: () => (/* binding */ findLastIndex), +/* harmony export */ getFirstToken: () => (/* binding */ getFirstToken), +/* harmony export */ getLastIndentation: () => (/* binding */ getLastIndentation), +/* harmony export */ getMemberIndentation: () => (/* binding */ getMemberIndentation), +/* harmony export */ list: () => (/* binding */ list), +/* harmony export */ primitive_type: () => (/* binding */ primitive_type), +/* harmony export */ return_type: () => (/* binding */ return_type), +/* harmony export */ stringifier: () => (/* binding */ stringifier), +/* harmony export */ type_with_extended_attributes: () => (/* binding */ type_with_extended_attributes), +/* harmony export */ unescape: () => (/* binding */ unescape) /* harmony export */ }); /* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /* harmony import */ var _argument_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); @@ -816,7 +842,7 @@ function primitive_type(tokeniser) { "boolean", "byte", "octet", - "undefined" + "undefined", ); if (base) { return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { base } }); @@ -917,7 +943,7 @@ function autofixAddExposedWindow(def) { def.extAttrs.unshift(exposed); } else { autoParenter(def).extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse( - new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__.Tokeniser("[Exposed=Window]") + new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__.Tokeniser("[Exposed=Window]"), ); const trivia = def.tokens.base.trivia; def.extAttrs.tokens.open.trivia = trivia; @@ -1010,7 +1036,7 @@ function autoParenter(data, parent) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Type": () => (/* binding */ Type) +/* harmony export */ Type: () => (/* binding */ Type) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -1034,14 +1060,15 @@ function generic_type(tokeniser, typeName) { "FrozenArray", "ObservableArray", "Promise", + "async_sequence", "sequence", - "record" + "record", ); if (!base) { return; } const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( - new Type({ source: tokeniser.source, tokens: { base } }) + new Type({ source: tokeniser.source, tokens: { base } }), ); ret.tokens.open = tokeniser.consume("<") || @@ -1056,6 +1083,7 @@ function generic_type(tokeniser, typeName) { ret.subtype.push(subtype); break; } + case "async_sequence": case "sequence": case "FrozenArray": case "ObservableArray": { @@ -1143,7 +1171,7 @@ function union_type(tokeniser, type) { ret.type = type || null; while (true) { const typ = - (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser) || + (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, type) || tokeniser.error("No type after open parenthesis or 'or' in union type"); if (typ.idlType === "any") tokeniser.error("Type `any` cannot be included in a union type"); @@ -1157,7 +1185,7 @@ function union_type(tokeniser, type) { } if (ret.idlType.length < 2) { tokeniser.error( - "At least two types are expected in a union type but found less" + "At least two types are expected in a union type but found less", ); } tokens.close = @@ -1208,6 +1236,26 @@ class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { *validate(defs) { yield* this.extAttrs.validate(defs); + if (this.idlType === "BufferSource") { + // XXX: For now this is a hack. Consider moving parents' extAttrs into types as the spec says: + // https://webidl.spec.whatwg.org/#idl-annotated-types + for (const extAttrs of [this.extAttrs, this.parent?.extAttrs]) { + for (const extAttr of extAttrs) { + if (extAttr.name !== "AllowShared") { + continue; + } + const message = `\`[AllowShared] BufferSource\` is now replaced with AllowSharedBufferSource.`; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)( + this.tokens.base, + this, + "migrate-allowshared", + message, + { autofix: replaceAllowShared(this, extAttr, extAttrs) }, + ); + } + } + } + if (this.idlType === "void") { const message = `\`void\` is now replaced by \`undefined\`. Refer to the \ [relevant GitHub issue](https://github.com/whatwg/webidl/issues/60) \ @@ -1225,8 +1273,8 @@ for more information.`; const target = this.union ? this : typedef && typedef.type === "typedef" - ? typedef.idlType - : undefined; + ? typedef.idlType + : undefined; if (target && this.nullable) { // do not allow any dictionary const { reference } = (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_4__.idlTypeIncludesDictionary)(target, defs) || {}; @@ -1237,7 +1285,7 @@ for more information.`; targetToken, this, "no-nullable-union-dict", - message + message, ); } } else { @@ -1274,7 +1322,7 @@ for more information.`; this.idlType ), context: this, - } + }, ); return w.ts.wrap([w.ts.trivia(firstToken.trivia), ref]); }; @@ -1287,6 +1335,23 @@ for more information.`; } } +/** + * @param {Type} type + * @param {import("./extended-attributes.js").SimpleExtendedAttribute} extAttr + * @param {ExtendedAttributes} extAttrs + */ +function replaceAllowShared(type, extAttr, extAttrs) { + return () => { + const index = extAttrs.indexOf(extAttr); + extAttrs.splice(index, 1); + if (!extAttrs.length && type.tokens.base.trivia.match(/^\s$/)) { + type.tokens.base.trivia = ""; // (let's not remove comments) + } + + type.tokens.base.value = "AllowSharedBufferSource"; + }; +} + /** * @param {Type} type */ @@ -1303,7 +1368,7 @@ function replaceVoid(type) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Base": () => (/* binding */ Base) +/* harmony export */ Base: () => (/* binding */ Base) /* harmony export */ }); class Base { /** @@ -1344,14 +1409,17 @@ class Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "dictionaryIncludesRequiredField": () => (/* binding */ dictionaryIncludesRequiredField), -/* harmony export */ "idlTypeIncludesDictionary": () => (/* binding */ idlTypeIncludesDictionary) +/* harmony export */ dictionaryIncludesRequiredField: () => (/* binding */ dictionaryIncludesRequiredField), +/* harmony export */ idlTypeIncludesDictionary: () => (/* binding */ idlTypeIncludesDictionary), +/* harmony export */ idlTypeIncludesEnforceRange: () => (/* binding */ idlTypeIncludesEnforceRange) /* harmony export */ }); /** + * @typedef {import("../validator.js").Definitions} Definitions * @typedef {import("../productions/dictionary.js").Dictionary} Dictionary + * @typedef {import("../../lib/productions/type").Type} Type * - * @param {*} idlType - * @param {import("../validator.js").Definitions} defs + * @param {Type} idlType + * @param {Definitions} defs * @param {object} [options] * @param {boolean} [options.useNullableInner] use when the input idlType is nullable and you want to use its inner type * @return {{ reference: *, dictionary: Dictionary }} the type reference that ultimately includes dictionary. @@ -1359,7 +1427,7 @@ __webpack_require__.r(__webpack_exports__); function idlTypeIncludesDictionary( idlType, defs, - { useNullableInner } = {} + { useNullableInner } = {}, ) { if (!idlType.union) { const def = defs.unique.get(idlType.idlType); @@ -1405,8 +1473,8 @@ function idlTypeIncludesDictionary( } /** - * @param {*} dict dictionary type - * @param {import("../validator.js").Definitions} defs + * @param {Dictionary} dict dictionary type + * @param {Definitions} defs * @return {boolean} */ function dictionaryIncludesRequiredField(dict, defs) { @@ -1430,6 +1498,34 @@ function dictionaryIncludesRequiredField(dict, defs) { return result; } +/** + * For now this only checks the most frequent cases: + * 1. direct inclusion of [EnforceRange] + * 2. typedef of that + * + * More complex cases with dictionaries and records are not covered yet. + * + * @param {Type} idlType + * @param {Definitions} defs + */ +function idlTypeIncludesEnforceRange(idlType, defs) { + if (idlType.union) { + // TODO: This should ideally be checked too + return false; + } + + if (idlType.extAttrs.some((e) => e.name === "EnforceRange")) { + return true; + } + + const def = defs.unique.get(idlType.idlType); + if (def?.type !== "typedef") { + return false; + } + + return def.idlType.extAttrs.some((e) => e.name === "EnforceRange"); +} + /***/ }), /* 8 */ @@ -1437,9 +1533,9 @@ function dictionaryIncludesRequiredField(dict, defs) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "ExtendedAttributeParameters": () => (/* binding */ ExtendedAttributeParameters), -/* harmony export */ "ExtendedAttributes": () => (/* binding */ ExtendedAttributes), -/* harmony export */ "SimpleExtendedAttribute": () => (/* binding */ SimpleExtendedAttribute) +/* harmony export */ ExtendedAttributeParameters: () => (/* binding */ ExtendedAttributeParameters), +/* harmony export */ ExtendedAttributes: () => (/* binding */ ExtendedAttributes), +/* harmony export */ SimpleExtendedAttribute: () => (/* binding */ SimpleExtendedAttribute) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _array_base_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9); @@ -1494,7 +1590,7 @@ function extAttrListItems(tokeniser) { } } tokeniser.error( - `Expected identifiers, strings, decimals, or integers but none found` + `Expected identifiers, strings, decimals, or integers but none found`, ); } @@ -1505,7 +1601,7 @@ class ExtendedAttributeParameters extends _base_js__WEBPACK_IMPORTED_MODULE_0__. static parse(tokeniser) { const tokens = { assign: tokeniser.consume("=") }; const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)( - new ExtendedAttributeParameters({ source: tokeniser.source, tokens }) + new ExtendedAttributeParameters({ source: tokeniser.source, tokens }), ); ret.list = []; if (tokens.assign) { @@ -1603,8 +1699,8 @@ class SimpleExtendedAttribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base const value = this.params.rhsIsList ? list : this.params.tokens.secondaryName - ? (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(tokens.secondaryName.value) - : null; + ? (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(tokens.secondaryName.value) + : null; return { type, value }; } get arguments() { @@ -1627,7 +1723,7 @@ information.`; this, "no-nointerfaceobject", message, - { level: "warning" } + { level: "warning" }, ); } else if (renamedLegacies.has(name)) { const message = `\`[${name}]\` extended attribute is a legacy feature \ @@ -1652,7 +1748,7 @@ information.`; w.ts.wrap([ w.ts.extendedAttributeReference(this.name), this.params.write(w), - ]) + ]), ), w.token(this.tokens.separator), ]); @@ -1687,12 +1783,12 @@ class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__.Arr ...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.list)(tokeniser, { parser: SimpleExtendedAttribute.parse, listName: "extended attribute", - }) + }), ); tokens.close = tokeniser.consume("]") || tokeniser.error( - "Expected a closing token for the extended attribute list" + "Expected a closing token for the extended attribute list", ); if (!ret.length) { tokeniser.unconsume(tokens.close.index); @@ -1700,7 +1796,7 @@ class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__.Arr } if (tokeniser.probe("[")) { tokeniser.error( - "Illegal double extended attribute lists, consider merging them" + "Illegal double extended attribute lists, consider merging them", ); } return ret; @@ -1730,7 +1826,7 @@ class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__.Arr __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "ArrayBase": () => (/* binding */ ArrayBase) +/* harmony export */ ArrayBase: () => (/* binding */ ArrayBase) /* harmony export */ }); class ArrayBase extends Array { constructor({ source, tokens }) { @@ -1750,8 +1846,8 @@ class ArrayBase extends Array { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Eof": () => (/* binding */ Eof), -/* harmony export */ "WrappedToken": () => (/* binding */ WrappedToken) +/* harmony export */ Eof: () => (/* binding */ Eof), +/* harmony export */ WrappedToken: () => (/* binding */ WrappedToken) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -1775,6 +1871,10 @@ class WrappedToken extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { }; } + get type() { + return this.tokens.value.type; + } + get value() { return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.value.value); } @@ -1811,7 +1911,7 @@ class Eof extends WrappedToken { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Argument": () => (/* binding */ Argument) +/* harmony export */ Argument: () => (/* binding */ Argument) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _default_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12); @@ -1837,7 +1937,7 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { /** @type {Base["tokens"]} */ const tokens = {}; const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)( - new Argument({ source: tokeniser.source, tokens }) + new Argument({ source: tokeniser.source, tokens }), ); ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser); tokens.optional = tokeniser.consume("optional"); @@ -1887,7 +1987,7 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { this.tokens.name, this, "no-nullable-dict-arg", - message + message, ); } else if (!this.optional) { if ( @@ -1903,7 +2003,7 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { message, { autofix: autofixDictionaryArgumentOptionality(this), - } + }, ); } } else if (!this.default) { @@ -1915,7 +2015,7 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { message, { autofix: autofixOptionalDictionaryDefaultValue(this), - } + }, ); } } @@ -1977,7 +2077,7 @@ function autofixOptionalDictionaryDefaultValue(arg) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Default": () => (/* binding */ Default) +/* harmony export */ Default: () => (/* binding */ Default) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -2049,7 +2149,7 @@ class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Operation": () => (/* binding */ Operation) +/* harmony export */ Operation: () => (/* binding */ Operation) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -2060,17 +2160,15 @@ __webpack_require__.r(__webpack_exports__); class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { /** - * @typedef {import("../tokeniser.js").Token} Token - * * @param {import("../tokeniser.js").Tokeniser} tokeniser * @param {object} [options] - * @param {Token} [options.special] - * @param {Token} [options.regular] + * @param {import("../tokeniser.js").Token} [options.special] + * @param {import("../tokeniser.js").Token} [options.regular] */ static parse(tokeniser, { special, regular } = {}) { const tokens = { special }; const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( - new Operation({ source: tokeniser.source, tokens }) + new Operation({ source: tokeniser.source, tokens }), ); if (special && special.value === "stringifier") { tokens.termination = tokeniser.consume(";"); @@ -2121,6 +2219,15 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { yield (0,_error_js__WEBPACK_IMPORTED_MODULE_2__.validationError)(this.tokens.open, this, "incomplete-op", message); } if (this.idlType) { + if (this.idlType.generic === "async_sequence") { + const message = `async_sequence types cannot be returned by an operation.`; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_2__.validationError)( + this.idlType.tokens.base, + this, + "async-sequence-idl-to-js", + message, + ); + } yield* this.idlType.validate(defs); } for (const argument of this.arguments) { @@ -2149,7 +2256,7 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { ...body, w.token(this.tokens.termination), ]), - { data: this, parent } + { data: this, parent }, ); } } @@ -2161,7 +2268,7 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Attribute": () => (/* binding */ Attribute) +/* harmony export */ Attribute: () => (/* binding */ Attribute) /* harmony export */ }); /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7); @@ -2182,12 +2289,12 @@ class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { */ static parse( tokeniser, - { special, noInherit = false, readonly = false } = {} + { special, noInherit = false, readonly = false } = {}, ) { const start_position = tokeniser.position; const tokens = { special }; const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)( - new Attribute({ source: tokeniser.source, tokens }) + new Attribute({ source: tokeniser.source, tokens }), ); if (!special && !noInherit) { tokens.special = tokeniser.consume("inherit"); @@ -2237,32 +2344,34 @@ class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { yield* this.extAttrs.validate(defs); yield* this.idlType.validate(defs); - switch (this.idlType.generic) { - case "sequence": - case "record": { - const message = `Attributes cannot accept ${this.idlType.generic} types.`; - yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( - this.tokens.name, - this, - "attr-invalid-type", - message - ); - break; + if ( + ["async_sequence", "sequence", "record"].includes(this.idlType.generic) + ) { + const message = `Attributes cannot accept ${this.idlType.generic} types.`; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( + this.tokens.name, + this, + "attr-invalid-type", + message, + ); + } + + { + const { reference } = (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__.idlTypeIncludesDictionary)(this.idlType, defs) || {}; + if (reference) { + const targetToken = (this.idlType.union ? reference : this.idlType) + .tokens.base; + const message = "Attributes cannot accept dictionary types."; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(targetToken, this, "attr-invalid-type", message); } - default: { - const { reference } = - (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__.idlTypeIncludesDictionary)(this.idlType, defs) || {}; - if (reference) { - const targetToken = (this.idlType.union ? reference : this.idlType) - .tokens.base; - const message = "Attributes cannot accept dictionary types."; - yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( - targetToken, - this, - "attr-invalid-type", - message - ); - } + } + + if (this.readonly) { + if ((0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__.idlTypeIncludesEnforceRange)(this.idlType, defs)) { + const targetToken = this.idlType.tokens.base; + const message = + "Readonly attributes cannot accept [EnforceRange] extended attribute."; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(targetToken, this, "attr-invalid-type", message); } } } @@ -2280,7 +2389,7 @@ class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { w.name_token(this.tokens.name, { data: this, parent }), w.token(this.tokens.termination), ]), - { data: this, parent } + { data: this, parent }, ); } } @@ -2292,8 +2401,8 @@ class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Enum": () => (/* binding */ Enum), -/* harmony export */ "EnumValue": () => (/* binding */ EnumValue) +/* harmony export */ Enum: () => (/* binding */ Enum), +/* harmony export */ EnumValue: () => (/* binding */ EnumValue) /* harmony export */ }); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var _token_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10); @@ -2327,7 +2436,7 @@ class EnumValue extends _token_js__WEBPACK_IMPORTED_MODULE_1__.WrappedToken { w.ts.trivia(this.tokens.value.trivia), w.ts.definition( w.ts.wrap(['"', w.ts.name(this.value, { data: this, parent }), '"']), - { data: this, parent } + { data: this, parent }, ), w.token(this.tokens.separator), ]); @@ -2388,7 +2497,7 @@ class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { w.token(this.tokens.close), w.token(this.tokens.termination), ]), - { data: this } + { data: this }, ); } } @@ -2400,7 +2509,7 @@ class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Includes": () => (/* binding */ Includes) +/* harmony export */ Includes: () => (/* binding */ Includes) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -2451,7 +2560,7 @@ class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.reference_token(this.tokens.mixin, this), w.token(this.tokens.termination), ]), - { data: this } + { data: this }, ); } } @@ -2463,7 +2572,7 @@ class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Typedef": () => (/* binding */ Typedef) +/* harmony export */ Typedef: () => (/* binding */ Typedef) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -2516,7 +2625,7 @@ class Typedef extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.name_token(this.tokens.name, { data: this }), w.token(this.tokens.termination), ]), - { data: this } + { data: this }, ); } } @@ -2528,10 +2637,12 @@ class Typedef extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "CallbackFunction": () => (/* binding */ CallbackFunction) +/* harmony export */ CallbackFunction: () => (/* binding */ CallbackFunction) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); + @@ -2542,7 +2653,7 @@ class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { static parse(tokeniser, base) { const tokens = { base }; const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( - new CallbackFunction({ source: tokeniser.source, tokens }) + new CallbackFunction({ source: tokeniser.source, tokens }), ); tokens.name = tokeniser.consumeKind("identifier") || @@ -2573,6 +2684,18 @@ class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { *validate(defs) { yield* this.extAttrs.validate(defs); + for (const arg of this.arguments) { + yield* arg.validate(defs); + if (arg.idlType.generic === "async_sequence") { + const message = `async_sequence types cannot be returned as a callback argument.`; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_2__.validationError)( + arg.tokens.name, + arg, + "async-sequence-idl-to-js", + message, + ); + } + } yield* this.idlType.validate(defs); } @@ -2590,7 +2713,7 @@ class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.token(this.tokens.close), w.token(this.tokens.termination), ]), - { data: this } + { data: this }, ); } } @@ -2602,7 +2725,7 @@ class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Interface": () => (/* binding */ Interface) +/* harmony export */ Interface: () => (/* binding */ Interface) /* harmony export */ }); /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); /* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); @@ -2643,8 +2766,12 @@ function static_member(tokeniser) { class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { /** * @param {import("../tokeniser.js").Tokeniser} tokeniser + * @param {import("../tokeniser.js").Token} base + * @param {object} [options] + * @param {import("./container.js").AllowedMember[]} [options.extMembers] + * @param {import("../tokeniser.js").Token|null} [options.partial] */ - static parse(tokeniser, base, { partial = null } = {}) { + static parse(tokeniser, base, { extMembers = [], partial = null } = {}) { const tokens = { partial, base }; return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse( tokeniser, @@ -2652,6 +2779,7 @@ class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { { inheritable: !partial, allowedMembers: [ + ...extMembers, [_constant_js__WEBPACK_IMPORTED_MODULE_3__.Constant.parse], [_constructor_js__WEBPACK_IMPORTED_MODULE_8__.Constructor.parse], [static_member], @@ -2660,7 +2788,7 @@ class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { [_attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse], [_operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse], ], - } + }, ); } @@ -2686,11 +2814,11 @@ for more information.`; message, { autofix: (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autofixAddExposedWindow)(this), - } + }, ); } const oldConstructors = this.extAttrs.filter( - (extAttr) => extAttr.name === "Constructor" + (extAttr) => extAttr.name === "Constructor", ); for (const constructor of oldConstructors) { const message = `Constructors should now be represented as a \`constructor()\` operation on the interface \ @@ -2704,14 +2832,14 @@ for more information.`; message, { autofix: autofixConstructor(this, constructor), - } + }, ); } const isGlobal = this.extAttrs.some((extAttr) => extAttr.name === "Global"); if (isGlobal) { const factoryFunctions = this.extAttrs.filter( - (extAttr) => extAttr.name === "LegacyFactoryFunction" + (extAttr) => extAttr.name === "LegacyFactoryFunction", ); for (const named of factoryFunctions) { const message = `Interfaces marked as \`[Global]\` cannot have factory functions.`; @@ -2719,12 +2847,12 @@ for more information.`; named.tokens.name, this, "no-constructible-global", - message + message, ); } const constructors = this.members.filter( - (member) => member.type === "constructor" + (member) => member.type === "constructor", ); for (const named of constructors) { const message = `Interfaces marked as \`[Global]\` cannot have constructors.`; @@ -2732,7 +2860,7 @@ for more information.`; named.tokens.base, this, "no-constructible-global", - message + message, ); } } @@ -2748,13 +2876,13 @@ function autofixConstructor(interfaceDef, constructorExtAttr) { interfaceDef = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autoParenter)(interfaceDef); return () => { const indentation = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getLastIndentation)( - interfaceDef.extAttrs.tokens.open.trivia + interfaceDef.extAttrs.tokens.open.trivia, ); const memberIndent = interfaceDef.members.length ? (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getLastIndentation)((0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getFirstToken)(interfaceDef.members[0]).trivia) : (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getMemberIndentation)(indentation); const constructorOp = _constructor_js__WEBPACK_IMPORTED_MODULE_8__.Constructor.parse( - new _tokeniser_js__WEBPACK_IMPORTED_MODULE_9__.Tokeniser(`\n${memberIndent}constructor();`) + new _tokeniser_js__WEBPACK_IMPORTED_MODULE_9__.Tokeniser(`\n${memberIndent}constructor();`), ); constructorOp.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_10__.ExtendedAttributes({ source: interfaceDef.source, @@ -2764,7 +2892,7 @@ function autofixConstructor(interfaceDef, constructorExtAttr) { const existingIndex = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.findLastIndex)( interfaceDef.members, - (m) => m.type === "constructor" + (m) => m.type === "constructor", ); interfaceDef.members.splice(existingIndex + 1, 0, constructorOp); @@ -2793,7 +2921,7 @@ function autofixConstructor(interfaceDef, constructorExtAttr) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Container": () => (/* binding */ Container) +/* harmony export */ Container: () => (/* binding */ Container) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8); @@ -2816,6 +2944,19 @@ function inheritance(tokeniser) { return { colon, inheritance }; } +/** + * Parser callback. + * @callback ParserCallback + * @param {import("../tokeniser.js").Tokeniser} tokeniser + * @param {...*} args + */ + +/** + * A parser callback and optional option object. + * @typedef AllowedMember + * @type {[ParserCallback, object?]} + */ + class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { /** * @param {import("../tokeniser.js").Tokeniser} tokeniser @@ -2889,7 +3030,7 @@ class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.token(this.tokens.colon), w.ts.trivia(this.tokens.inheritance.trivia), w.ts.inheritance( - w.reference(this.tokens.inheritance.value, { context: this }) + w.reference(this.tokens.inheritance.value, { context: this }), ), ]); }; @@ -2908,7 +3049,7 @@ class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.token(this.tokens.close), w.token(this.tokens.termination), ]), - { data: this } + { data: this }, ); } } @@ -2920,7 +3061,7 @@ class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Constant": () => (/* binding */ Constant) +/* harmony export */ Constant: () => (/* binding */ Constant) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); @@ -2989,7 +3130,7 @@ class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.token(this.tokens.value), w.token(this.tokens.termination), ]), - { data: this, parent } + { data: this, parent }, ); } } @@ -3001,21 +3142,23 @@ class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "IterableLike": () => (/* binding */ IterableLike) +/* harmony export */ IterableLike: () => (/* binding */ IterableLike) /* harmony export */ }); -/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); -/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); +/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6); +/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); + -class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { +class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_1__.Base { /** * @param {import("../tokeniser.js").Tokeniser} tokeniser */ static parse(tokeniser) { const start_position = tokeniser.position; - const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( - new IterableLike({ source: tokeniser.source, tokens: {} }) + const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)( + new IterableLike({ source: tokeniser.source, tokens: {} }), ); const { tokens } = ret; tokens.readonly = tokeniser.consume("readonly"); @@ -3025,8 +3168,8 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { tokens.base = tokens.readonly ? tokeniser.consume("maplike", "setlike") : tokens.async - ? tokeniser.consume("iterable") - : tokeniser.consume("iterable", "maplike", "setlike"); + ? tokeniser.consume("iterable") + : tokeniser.consume("iterable", "async_iterable", "maplike", "setlike"); if (!tokens.base) { tokeniser.unconsume(start_position); return; @@ -3034,14 +3177,16 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { const { type } = ret; const secondTypeRequired = type === "maplike"; - const secondTypeAllowed = secondTypeRequired || type === "iterable"; - const argumentAllowed = ret.async && type === "iterable"; + const secondTypeAllowed = + secondTypeRequired || type === "iterable" || type === "async_iterable"; + const argumentAllowed = + type === "async_iterable" || (ret.async && type === "iterable"); tokens.open = tokeniser.consume("<") || tokeniser.error(`Missing less-than sign \`<\` in ${type} declaration`); const first = - (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser) || + (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.type_with_extended_attributes)(tokeniser) || tokeniser.error(`Missing a type argument in ${type} declaration`); ret.idlType = [first]; ret.arguments = []; @@ -3049,7 +3194,7 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { if (secondTypeAllowed) { first.tokens.separator = tokeniser.consume(","); if (first.tokens.separator) { - ret.idlType.push((0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser)); + ret.idlType.push((0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.type_with_extended_attributes)(tokeniser)); } else if (secondTypeRequired) { tokeniser.error(`Missing second type argument in ${type} declaration`); } @@ -3062,7 +3207,7 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { if (tokeniser.probe("(")) { if (argumentAllowed) { tokens.argsOpen = tokeniser.consume("("); - ret.arguments.push(...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser)); + ret.arguments.push(...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.argument_list)(tokeniser)); tokens.argsClose = tokeniser.consume(")") || tokeniser.error("Unterminated async iterable argument list"); @@ -3089,6 +3234,18 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { } *validate(defs) { + if (this.async && this.type === "iterable") { + const message = "`async iterable` is now changed to `async_iterable`."; + yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( + this.tokens.async, + this, + "obsolete-async-iterable-syntax", + message, + { + autofix: autofixAsyncIterableSyntax(this), + }, + ); + } for (const type of this.idlType) { yield* type.validate(defs); } @@ -3113,11 +3270,26 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.token(this.tokens.argsClose), w.token(this.tokens.termination), ]), - { data: this, parent: this.parent } + { data: this, parent: this.parent }, ); } } +/** + * @param {IterableLike} iterableLike + */ +function autofixAsyncIterableSyntax(iterableLike) { + return () => { + const async = iterableLike.tokens.async; + iterableLike.tokens.base = { + ...async, + type: "async_iterable", + value: "async_iterable", + }; + delete iterableLike.tokens.async; + }; +} + /***/ }), /* 23 */ @@ -3125,7 +3297,7 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "checkInterfaceMemberDuplication": () => (/* binding */ checkInterfaceMemberDuplication) +/* harmony export */ checkInterfaceMemberDuplication: () => (/* binding */ checkInterfaceMemberDuplication) /* harmony export */ }); /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); @@ -3164,7 +3336,7 @@ function* checkInterfaceMemberDuplication(defs, i) { addition.tokens.name, ext, "no-cross-overload", - message + message, ); } } @@ -3185,10 +3357,10 @@ function* checkInterfaceMemberDuplication(defs, i) { const ops = getOperations(i); return { statics: new Set( - ops.filter((op) => op.special === "static").map((op) => op.name) + ops.filter((op) => op.special === "static").map((op) => op.name), ), nonstatics: new Set( - ops.filter((op) => op.special !== "static").map((op) => op.name) + ops.filter((op) => op.special !== "static").map((op) => op.name), ), }; } @@ -3201,7 +3373,7 @@ function* checkInterfaceMemberDuplication(defs, i) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Constructor": () => (/* binding */ Constructor) +/* harmony export */ Constructor: () => (/* binding */ Constructor) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -3255,7 +3427,7 @@ class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { w.token(this.tokens.close), w.token(this.tokens.termination), ]), - { data: this, parent } + { data: this, parent }, ); } } @@ -3267,7 +3439,7 @@ class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Mixin": () => (/* binding */ Mixin) +/* harmony export */ Mixin: () => (/* binding */ Mixin) /* harmony export */ }); /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); /* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21); @@ -3282,14 +3454,13 @@ __webpack_require__.r(__webpack_exports__); class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { /** - * @typedef {import("../tokeniser.js").Token} Token - * * @param {import("../tokeniser.js").Tokeniser} tokeniser - * @param {Token} base + * @param {import("../tokeniser.js").Token} base * @param {object} [options] - * @param {Token} [options.partial] + * @param {import("./container.js").AllowedMember[]} [options.extMembers] + * @param {import("../tokeniser.js").Token} [options.partial] */ - static parse(tokeniser, base, { partial } = {}) { + static parse(tokeniser, base, { extMembers = [], partial } = {}) { const tokens = { partial, base }; tokens.mixin = tokeniser.consume("mixin"); if (!tokens.mixin) { @@ -3300,12 +3471,13 @@ class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { new Mixin({ source: tokeniser.source, tokens }), { allowedMembers: [ + ...extMembers, [_constant_js__WEBPACK_IMPORTED_MODULE_1__.Constant.parse], [_helpers_js__WEBPACK_IMPORTED_MODULE_4__.stringifier], [_attribute_js__WEBPACK_IMPORTED_MODULE_2__.Attribute.parse, { noInherit: true }], [_operation_js__WEBPACK_IMPORTED_MODULE_3__.Operation.parse, { regular: true }], ], - } + }, ); } @@ -3321,7 +3493,7 @@ class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Dictionary": () => (/* binding */ Dictionary) +/* harmony export */ Dictionary: () => (/* binding */ Dictionary) /* harmony export */ }); /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); /* harmony import */ var _field_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); @@ -3332,9 +3504,10 @@ class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { /** * @param {import("../tokeniser.js").Tokeniser} tokeniser * @param {object} [options] + * @param {import("./container.js").AllowedMember[]} [options.extMembers] * @param {import("../tokeniser.js").Token} [options.partial] */ - static parse(tokeniser, { partial } = {}) { + static parse(tokeniser, { extMembers = [], partial } = {}) { const tokens = { partial }; tokens.base = tokeniser.consume("dictionary"); if (!tokens.base) { @@ -3345,8 +3518,8 @@ class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { new Dictionary({ source: tokeniser.source, tokens }), { inheritable: !partial, - allowedMembers: [[_field_js__WEBPACK_IMPORTED_MODULE_1__.Field.parse]], - } + allowedMembers: [...extMembers, [_field_js__WEBPACK_IMPORTED_MODULE_1__.Field.parse]], + }, ); } @@ -3362,7 +3535,7 @@ class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Field": () => (/* binding */ Field) +/* harmony export */ Field: () => (/* binding */ Field) /* harmony export */ }); /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); @@ -3424,7 +3597,7 @@ class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { this.default ? this.default.write(w) : "", w.token(this.tokens.termination), ]), - { data: this, parent } + { data: this, parent }, ); } } @@ -3436,7 +3609,7 @@ class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Namespace": () => (/* binding */ Namespace) +/* harmony export */ Namespace: () => (/* binding */ Namespace) /* harmony export */ }); /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); /* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); @@ -3455,9 +3628,10 @@ class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { /** * @param {import("../tokeniser.js").Tokeniser} tokeniser * @param {object} [options] + * @param {import("./container.js").AllowedMember[]} [options.extMembers] * @param {import("../tokeniser.js").Token} [options.partial] */ - static parse(tokeniser, { partial } = {}) { + static parse(tokeniser, { extMembers = [], partial } = {}) { const tokens = { partial }; tokens.base = tokeniser.consume("namespace"); if (!tokens.base) { @@ -3468,11 +3642,12 @@ class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { new Namespace({ source: tokeniser.source, tokens }), { allowedMembers: [ + ...extMembers, [_attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse, { noInherit: true, readonly: true }], [_constant_js__WEBPACK_IMPORTED_MODULE_5__.Constant.parse], [_operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse, { regular: true }], ], - } + }, ); } @@ -3497,7 +3672,7 @@ for more information.`; message, { autofix: (0,_helpers_js__WEBPACK_IMPORTED_MODULE_4__.autofixAddExposedWindow)(this), - } + }, ); } yield* super.validate(defs); @@ -3511,7 +3686,7 @@ for more information.`; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "CallbackInterface": () => (/* binding */ CallbackInterface) +/* harmony export */ CallbackInterface: () => (/* binding */ CallbackInterface) /* harmony export */ }); /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); /* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(13); @@ -3523,8 +3698,11 @@ __webpack_require__.r(__webpack_exports__); class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { /** * @param {import("../tokeniser.js").Tokeniser} tokeniser + * @param {*} callback + * @param {object} [options] + * @param {import("./container.js").AllowedMember[]} [options.extMembers] */ - static parse(tokeniser, callback, { partial = null } = {}) { + static parse(tokeniser, callback, { extMembers = [] } = {}) { const tokens = { callback }; tokens.base = tokeniser.consume("interface"); if (!tokens.base) { @@ -3534,12 +3712,12 @@ class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Conta tokeniser, new CallbackInterface({ source: tokeniser.source, tokens }), { - inheritable: !partial, allowedMembers: [ + ...extMembers, [_constant_js__WEBPACK_IMPORTED_MODULE_2__.Constant.parse], [_operation_js__WEBPACK_IMPORTED_MODULE_1__.Operation.parse, { regular: true }], ], - } + }, ); } @@ -3555,8 +3733,8 @@ class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Conta __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Writer": () => (/* binding */ Writer), -/* harmony export */ "write": () => (/* binding */ write) +/* harmony export */ Writer: () => (/* binding */ Writer), +/* harmony export */ write: () => (/* binding */ write) /* harmony export */ }); function noop(arg) { return arg; @@ -3640,7 +3818,7 @@ function write(ast, { templates: ts = templates } = {}) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "validate": () => (/* binding */ validate) +/* harmony export */ validate: () => (/* binding */ validate) /* harmony export */ }); /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); @@ -3797,14 +3975,14 @@ function validate(ast) { /******/ /************************************************************************/ var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. (() => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "WebIDLParseError": () => (/* reexport safe */ _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__.WebIDLParseError), -/* harmony export */ "parse": () => (/* reexport safe */ _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__.parse), -/* harmony export */ "validate": () => (/* reexport safe */ _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__.validate), -/* harmony export */ "write": () => (/* reexport safe */ _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__.write) +/* harmony export */ WebIDLParseError: () => (/* reexport safe */ _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__.WebIDLParseError), +/* harmony export */ parse: () => (/* reexport safe */ _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__.parse), +/* harmony export */ validate: () => (/* reexport safe */ _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__.validate), +/* harmony export */ write: () => (/* reexport safe */ _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__.write) /* harmony export */ }); /* harmony import */ var _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 02c16cd1074435..22e374b606befe 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -52,7 +52,7 @@ "path": "html/webappapis/timers" }, "interfaces": { - "commit": "e1b27be06b43787a001b7297c4e0fabdd276560f", + "commit": "a8392bd0210378dda13278eeccf2c2602278e214", "path": "interfaces" }, "performance-timeline": { @@ -64,7 +64,7 @@ "path": "resource-timing" }, "resources": { - "commit": "1d2c5fb36a6e477c8f915bde7eca027be6abe792", + "commit": "6a2f32237615d7ea9c1eb1e30453066b5555c603", "path": "resources" }, "streams": { @@ -96,7 +96,7 @@ "path": "web-locks" }, "WebCryptoAPI": { - "commit": "0acea989ac21842d6545d16594f1a05491c6076e", + "commit": "caebe89c3b243513c4b7e5e8dd2a370e5800bb73", "path": "WebCryptoAPI" }, "webidl": { diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index 722a0b38398e1d..3f788d87fd0849 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -55,6 +55,12 @@ module.exports = { 'historical.any.js': { 'skip': 'Not relevant in Node.js context', }, + 'digest/turboshake.tentative.https.any.js': { + 'skip': 'not implemented', + }, + 'digest/kangarootwelve.tentative.https.any.js': { + 'skip': 'not implemented', + }, 'sign_verify/eddsa_small_order_points.https.any.js': { 'fail': { 'note': 'see https://github.com/nodejs/node/issues/54572', diff --git a/test/wpt/status/resource-timing.json b/test/wpt/status/resource-timing.json index 6406b88d3266f5..74de815387ed33 100644 --- a/test/wpt/status/resource-timing.json +++ b/test/wpt/status/resource-timing.json @@ -31,7 +31,17 @@ "PerformanceResourceTiming interface: resource must inherit property \"firstInterimResponseStart\" with the proper type", "PerformanceResourceTiming interface: resource must inherit property \"renderBlockingStatus\" with the proper type", "PerformanceResourceTiming interface: resource must inherit property \"contentType\" with the proper type", - "PerformanceResourceTiming interface: default toJSON operation on resource" + "PerformanceResourceTiming interface: default toJSON operation on resource", + "PerformanceResourceTiming interface: attribute workerRouterEvaluationStart", + "PerformanceResourceTiming interface: attribute workerCacheLookupStart", + "PerformanceResourceTiming interface: attribute workerMatchedRouterSource", + "PerformanceResourceTiming interface: attribute workerFinalRouterSource", + "PerformanceResourceTiming interface: attribute contentEncoding", + "PerformanceResourceTiming interface: resource must inherit property \"workerRouterEvaluationStart\" with the proper type", + "PerformanceResourceTiming interface: resource must inherit property \"workerCacheLookupStart\" with the proper type", + "PerformanceResourceTiming interface: resource must inherit property \"workerMatchedRouterSource\" with the proper type", + "PerformanceResourceTiming interface: resource must inherit property \"workerFinalRouterSource\" with the proper type", + "PerformanceResourceTiming interface: resource must inherit property \"contentEncoding\" with the proper type" ] } }