| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003 |
- 'use strict'
- const assert = require('node:assert')
- const { types, inspect } = require('node:util')
- const { runtimeFeatures } = require('../../util/runtime-features')
- const UNDEFINED = 1
- const BOOLEAN = 2
- const STRING = 3
- const SYMBOL = 4
- const NUMBER = 5
- const BIGINT = 6
- const NULL = 7
- const OBJECT = 8 // function and object
- const FunctionPrototypeSymbolHasInstance = Function.call.bind(Function.prototype[Symbol.hasInstance])
- /** @type {import('../../../types/webidl').Webidl} */
- const webidl = {
- converters: {},
- util: {},
- errors: {},
- is: {}
- }
- /**
- * @description Instantiate an error.
- *
- * @param {Object} opts
- * @param {string} opts.header
- * @param {string} opts.message
- * @returns {TypeError}
- */
- webidl.errors.exception = function (message) {
- return new TypeError(`${message.header}: ${message.message}`)
- }
- /**
- * @description Instantiate an error when conversion from one type to another has failed.
- *
- * @param {Object} opts
- * @param {string} opts.prefix
- * @param {string} opts.argument
- * @param {string[]} opts.types
- * @returns {TypeError}
- */
- webidl.errors.conversionFailed = function (opts) {
- const plural = opts.types.length === 1 ? '' : ' one of'
- const message =
- `${opts.argument} could not be converted to` +
- `${plural}: ${opts.types.join(', ')}.`
- return webidl.errors.exception({
- header: opts.prefix,
- message
- })
- }
- /**
- * @description Instantiate an error when an invalid argument is provided
- *
- * @param {Object} context
- * @param {string} context.prefix
- * @param {string} context.value
- * @param {string} context.type
- * @returns {TypeError}
- */
- webidl.errors.invalidArgument = function (context) {
- return webidl.errors.exception({
- header: context.prefix,
- message: `"${context.value}" is an invalid ${context.type}.`
- })
- }
- // https://webidl.spec.whatwg.org/#implements
- webidl.brandCheck = function (V, I) {
- if (!FunctionPrototypeSymbolHasInstance(I, V)) {
- const err = new TypeError('Illegal invocation')
- err.code = 'ERR_INVALID_THIS' // node compat.
- throw err
- }
- }
- webidl.brandCheckMultiple = function (List) {
- const prototypes = List.map((c) => webidl.util.MakeTypeAssertion(c))
- return (V) => {
- if (prototypes.every(typeCheck => !typeCheck(V))) {
- const err = new TypeError('Illegal invocation')
- err.code = 'ERR_INVALID_THIS' // node compat.
- throw err
- }
- }
- }
- webidl.argumentLengthCheck = function ({ length }, min, ctx) {
- if (length < min) {
- throw webidl.errors.exception({
- message: `${min} argument${min !== 1 ? 's' : ''} required, ` +
- `but${length ? ' only' : ''} ${length} found.`,
- header: ctx
- })
- }
- }
- webidl.illegalConstructor = function () {
- throw webidl.errors.exception({
- header: 'TypeError',
- message: 'Illegal constructor'
- })
- }
- webidl.util.MakeTypeAssertion = function (I) {
- return (O) => FunctionPrototypeSymbolHasInstance(I, O)
- }
- // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
- webidl.util.Type = function (V) {
- switch (typeof V) {
- case 'undefined': return UNDEFINED
- case 'boolean': return BOOLEAN
- case 'string': return STRING
- case 'symbol': return SYMBOL
- case 'number': return NUMBER
- case 'bigint': return BIGINT
- case 'function':
- case 'object': {
- if (V === null) {
- return NULL
- }
- return OBJECT
- }
- }
- }
- webidl.util.Types = {
- UNDEFINED,
- BOOLEAN,
- STRING,
- SYMBOL,
- NUMBER,
- BIGINT,
- NULL,
- OBJECT
- }
- webidl.util.TypeValueToString = function (o) {
- switch (webidl.util.Type(o)) {
- case UNDEFINED: return 'Undefined'
- case BOOLEAN: return 'Boolean'
- case STRING: return 'String'
- case SYMBOL: return 'Symbol'
- case NUMBER: return 'Number'
- case BIGINT: return 'BigInt'
- case NULL: return 'Null'
- case OBJECT: return 'Object'
- }
- }
- webidl.util.markAsUncloneable = runtimeFeatures.has('markAsUncloneable')
- ? require('node:worker_threads').markAsUncloneable
- : () => {}
- // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
- webidl.util.ConvertToInt = function (V, bitLength, signedness, flags) {
- let upperBound
- let lowerBound
- // 1. If bitLength is 64, then:
- if (bitLength === 64) {
- // 1. Let upperBound be 2^53 − 1.
- upperBound = Math.pow(2, 53) - 1
- // 2. If signedness is "unsigned", then let lowerBound be 0.
- if (signedness === 'unsigned') {
- lowerBound = 0
- } else {
- // 3. Otherwise let lowerBound be −2^53 + 1.
- lowerBound = Math.pow(-2, 53) + 1
- }
- } else if (signedness === 'unsigned') {
- // 2. Otherwise, if signedness is "unsigned", then:
- // 1. Let lowerBound be 0.
- lowerBound = 0
- // 2. Let upperBound be 2^bitLength − 1.
- upperBound = Math.pow(2, bitLength) - 1
- } else {
- // 3. Otherwise:
- // 1. Let lowerBound be -2^bitLength − 1.
- lowerBound = Math.pow(-2, bitLength) - 1
- // 2. Let upperBound be 2^bitLength − 1 − 1.
- upperBound = Math.pow(2, bitLength - 1) - 1
- }
- // 4. Let x be ? ToNumber(V).
- let x = Number(V)
- // 5. If x is −0, then set x to +0.
- if (x === 0) {
- x = 0
- }
- // 6. If the conversion is to an IDL type associated
- // with the [EnforceRange] extended attribute, then:
- if (webidl.util.HasFlag(flags, webidl.attributes.EnforceRange)) {
- // 1. If x is NaN, +∞, or −∞, then throw a TypeError.
- if (
- Number.isNaN(x) ||
- x === Number.POSITIVE_INFINITY ||
- x === Number.NEGATIVE_INFINITY
- ) {
- throw webidl.errors.exception({
- header: 'Integer conversion',
- message: `Could not convert ${webidl.util.Stringify(V)} to an integer.`
- })
- }
- // 2. Set x to IntegerPart(x).
- x = webidl.util.IntegerPart(x)
- // 3. If x < lowerBound or x > upperBound, then
- // throw a TypeError.
- if (x < lowerBound || x > upperBound) {
- throw webidl.errors.exception({
- header: 'Integer conversion',
- message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.`
- })
- }
- // 4. Return x.
- return x
- }
- // 7. If x is not NaN and the conversion is to an IDL
- // type associated with the [Clamp] extended
- // attribute, then:
- if (!Number.isNaN(x) && webidl.util.HasFlag(flags, webidl.attributes.Clamp)) {
- // 1. Set x to min(max(x, lowerBound), upperBound).
- x = Math.min(Math.max(x, lowerBound), upperBound)
- // 2. Round x to the nearest integer, choosing the
- // even integer if it lies halfway between two,
- // and choosing +0 rather than −0.
- if (Math.floor(x) % 2 === 0) {
- x = Math.floor(x)
- } else {
- x = Math.ceil(x)
- }
- // 3. Return x.
- return x
- }
- // 8. If x is NaN, +0, +∞, or −∞, then return +0.
- if (
- Number.isNaN(x) ||
- (x === 0 && Object.is(0, x)) ||
- x === Number.POSITIVE_INFINITY ||
- x === Number.NEGATIVE_INFINITY
- ) {
- return 0
- }
- // 9. Set x to IntegerPart(x).
- x = webidl.util.IntegerPart(x)
- // 10. Set x to x modulo 2^bitLength.
- x = x % Math.pow(2, bitLength)
- // 11. If signedness is "signed" and x ≥ 2^bitLength − 1,
- // then return x − 2^bitLength.
- if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) {
- return x - Math.pow(2, bitLength)
- }
- // 12. Otherwise, return x.
- return x
- }
- // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
- webidl.util.IntegerPart = function (n) {
- // 1. Let r be floor(abs(n)).
- const r = Math.floor(Math.abs(n))
- // 2. If n < 0, then return -1 × r.
- if (n < 0) {
- return -1 * r
- }
- // 3. Otherwise, return r.
- return r
- }
- webidl.util.Stringify = function (V) {
- const type = webidl.util.Type(V)
- switch (type) {
- case SYMBOL:
- return `Symbol(${V.description})`
- case OBJECT:
- return inspect(V)
- case STRING:
- return `"${V}"`
- case BIGINT:
- return `${V}n`
- default:
- return `${V}`
- }
- }
- webidl.util.IsResizableArrayBuffer = function (V) {
- if (types.isArrayBuffer(V)) {
- return V.resizable
- }
- if (types.isSharedArrayBuffer(V)) {
- return V.growable
- }
- throw webidl.errors.exception({
- header: 'IsResizableArrayBuffer',
- message: `"${webidl.util.Stringify(V)}" is not an array buffer.`
- })
- }
- webidl.util.HasFlag = function (flags, attributes) {
- return typeof flags === 'number' && (flags & attributes) === attributes
- }
- // https://webidl.spec.whatwg.org/#es-sequence
- webidl.sequenceConverter = function (converter) {
- return (V, prefix, argument, Iterable) => {
- // 1. If Type(V) is not Object, throw a TypeError.
- if (webidl.util.Type(V) !== OBJECT) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.`
- })
- }
- // 2. Let method be ? GetMethod(V, @@iterator).
- /** @type {Generator} */
- const method = typeof Iterable === 'function' ? Iterable() : V?.[Symbol.iterator]?.()
- const seq = []
- let index = 0
- // 3. If method is undefined, throw a TypeError.
- if (
- method === undefined ||
- typeof method.next !== 'function'
- ) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} is not iterable.`
- })
- }
- // https://webidl.spec.whatwg.org/#create-sequence-from-iterable
- while (true) {
- const { done, value } = method.next()
- if (done) {
- break
- }
- seq.push(converter(value, prefix, `${argument}[${index++}]`))
- }
- return seq
- }
- }
- // https://webidl.spec.whatwg.org/#es-to-record
- webidl.recordConverter = function (keyConverter, valueConverter) {
- return (O, prefix, argument) => {
- // 1. If Type(O) is not Object, throw a TypeError.
- if (webidl.util.Type(O) !== OBJECT) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} ("${webidl.util.TypeValueToString(O)}") is not an Object.`
- })
- }
- // 2. Let result be a new empty instance of record<K, V>.
- const result = {}
- if (!types.isProxy(O)) {
- // 1. Let desc be ? O.[[GetOwnProperty]](key).
- const keys = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)]
- for (const key of keys) {
- const keyName = webidl.util.Stringify(key)
- // 1. Let typedKey be key converted to an IDL value of type K.
- const typedKey = keyConverter(key, prefix, `Key ${keyName} in ${argument}`)
- // 2. Let value be ? Get(O, key).
- // 3. Let typedValue be value converted to an IDL value of type V.
- const typedValue = valueConverter(O[key], prefix, `${argument}[${keyName}]`)
- // 4. Set result[typedKey] to typedValue.
- result[typedKey] = typedValue
- }
- // 5. Return result.
- return result
- }
- // 3. Let keys be ? O.[[OwnPropertyKeys]]().
- const keys = Reflect.ownKeys(O)
- // 4. For each key of keys.
- for (const key of keys) {
- // 1. Let desc be ? O.[[GetOwnProperty]](key).
- const desc = Reflect.getOwnPropertyDescriptor(O, key)
- // 2. If desc is not undefined and desc.[[Enumerable]] is true:
- if (desc?.enumerable) {
- // 1. Let typedKey be key converted to an IDL value of type K.
- const typedKey = keyConverter(key, prefix, argument)
- // 2. Let value be ? Get(O, key).
- // 3. Let typedValue be value converted to an IDL value of type V.
- const typedValue = valueConverter(O[key], prefix, argument)
- // 4. Set result[typedKey] to typedValue.
- result[typedKey] = typedValue
- }
- }
- // 5. Return result.
- return result
- }
- }
- webidl.interfaceConverter = function (TypeCheck, name) {
- return (V, prefix, argument) => {
- if (!TypeCheck(V)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `Expected ${argument} ("${webidl.util.Stringify(V)}") to be an instance of ${name}.`
- })
- }
- return V
- }
- }
- webidl.dictionaryConverter = function (converters) {
- return (dictionary, prefix, argument) => {
- const dict = {}
- if (dictionary != null && webidl.util.Type(dictionary) !== OBJECT) {
- throw webidl.errors.exception({
- header: prefix,
- message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`
- })
- }
- for (const options of converters) {
- const { key, defaultValue, required, converter } = options
- if (required === true) {
- if (dictionary == null || !Object.hasOwn(dictionary, key)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `Missing required key "${key}".`
- })
- }
- }
- let value = dictionary?.[key]
- const hasDefault = defaultValue !== undefined
- // Only use defaultValue if value is undefined and
- // a defaultValue options was provided.
- if (hasDefault && value === undefined) {
- value = defaultValue()
- }
- // A key can be optional and have no default value.
- // When this happens, do not perform a conversion,
- // and do not assign the key a value.
- if (required || hasDefault || value !== undefined) {
- value = converter(value, prefix, `${argument}.${key}`)
- if (
- options.allowedValues &&
- !options.allowedValues.includes(value)
- ) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.`
- })
- }
- dict[key] = value
- }
- }
- return dict
- }
- }
- webidl.nullableConverter = function (converter) {
- return (V, prefix, argument) => {
- if (V === null) {
- return V
- }
- return converter(V, prefix, argument)
- }
- }
- /**
- * @param {*} value
- * @returns {boolean}
- */
- webidl.is.USVString = function (value) {
- return (
- typeof value === 'string' &&
- value.isWellFormed()
- )
- }
- webidl.is.ReadableStream = webidl.util.MakeTypeAssertion(ReadableStream)
- webidl.is.Blob = webidl.util.MakeTypeAssertion(Blob)
- webidl.is.URLSearchParams = webidl.util.MakeTypeAssertion(URLSearchParams)
- webidl.is.File = webidl.util.MakeTypeAssertion(File)
- webidl.is.URL = webidl.util.MakeTypeAssertion(URL)
- webidl.is.AbortSignal = webidl.util.MakeTypeAssertion(AbortSignal)
- webidl.is.MessagePort = webidl.util.MakeTypeAssertion(MessagePort)
- webidl.is.BufferSource = function (V) {
- return types.isArrayBuffer(V) || (
- ArrayBuffer.isView(V) &&
- types.isArrayBuffer(V.buffer)
- )
- }
- // https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy
- webidl.util.getCopyOfBytesHeldByBufferSource = function (bufferSource) {
- // 1. Let jsBufferSource be the result of converting bufferSource to a JavaScript value.
- const jsBufferSource = bufferSource
- // 2. Let jsArrayBuffer be jsBufferSource.
- let jsArrayBuffer = jsBufferSource
- // 3. Let offset be 0.
- let offset = 0
- // 4. Let length be 0.
- let length = 0
- // 5. If jsBufferSource has a [[ViewedArrayBuffer]] internal slot, then:
- if (types.isTypedArray(jsBufferSource) || types.isDataView(jsBufferSource)) {
- // 5.1. Set jsArrayBuffer to jsBufferSource.[[ViewedArrayBuffer]].
- jsArrayBuffer = jsBufferSource.buffer
- // 5.2. Set offset to jsBufferSource.[[ByteOffset]].
- offset = jsBufferSource.byteOffset
- // 5.3. Set length to jsBufferSource.[[ByteLength]].
- length = jsBufferSource.byteLength
- } else {
- // 6. Otherwise:
- // 6.1. Assert: jsBufferSource is an ArrayBuffer or SharedArrayBuffer object.
- assert(types.isAnyArrayBuffer(jsBufferSource))
- // 6.2. Set length to jsBufferSource.[[ArrayBufferByteLength]].
- length = jsBufferSource.byteLength
- }
- // 7. If IsDetachedBuffer(jsArrayBuffer) is true, then return the empty byte sequence.
- if (jsArrayBuffer.detached) {
- return new Uint8Array(0)
- }
- // 8. Let bytes be a new byte sequence of length equal to length.
- const bytes = new Uint8Array(length)
- // 9. For i in the range offset to offset + length − 1, inclusive,
- // set bytes[i − offset] to GetValueFromBuffer(jsArrayBuffer, i, Uint8, true, Unordered).
- const view = new Uint8Array(jsArrayBuffer, offset, length)
- bytes.set(view)
- // 10. Return bytes.
- return bytes
- }
- // https://webidl.spec.whatwg.org/#es-DOMString
- webidl.converters.DOMString = function (V, prefix, argument, flags) {
- // 1. If V is null and the conversion is to an IDL type
- // associated with the [LegacyNullToEmptyString]
- // extended attribute, then return the DOMString value
- // that represents the empty string.
- if (V === null && webidl.util.HasFlag(flags, webidl.attributes.LegacyNullToEmptyString)) {
- return ''
- }
- // 2. Let x be ? ToString(V).
- if (typeof V === 'symbol') {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} is a symbol, which cannot be converted to a DOMString.`
- })
- }
- // 3. Return the IDL DOMString value that represents the
- // same sequence of code units as the one the
- // ECMAScript String value x represents.
- return String(V)
- }
- // https://webidl.spec.whatwg.org/#es-ByteString
- webidl.converters.ByteString = function (V, prefix, argument) {
- // 1. Let x be ? ToString(V).
- if (typeof V === 'symbol') {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} is a symbol, which cannot be converted to a ByteString.`
- })
- }
- const x = String(V)
- // 2. If the value of any element of x is greater than
- // 255, then throw a TypeError.
- for (let index = 0; index < x.length; index++) {
- if (x.charCodeAt(index) > 255) {
- throw new TypeError(
- 'Cannot convert argument to a ByteString because the character at ' +
- `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.`
- )
- }
- }
- // 3. Return an IDL ByteString value whose length is the
- // length of x, and where the value of each element is
- // the value of the corresponding element of x.
- return x
- }
- /**
- * @param {unknown} value
- * @returns {string}
- * @see https://webidl.spec.whatwg.org/#es-USVString
- */
- webidl.converters.USVString = function (value) {
- // TODO: rewrite this so we can control the errors thrown
- if (typeof value === 'string') {
- return value.toWellFormed()
- }
- return `${value}`.toWellFormed()
- }
- // https://webidl.spec.whatwg.org/#es-boolean
- webidl.converters.boolean = function (V) {
- // 1. Let x be the result of computing ToBoolean(V).
- // https://262.ecma-international.org/10.0/index.html#table-10
- const x = Boolean(V)
- // 2. Return the IDL boolean value that is the one that represents
- // the same truth value as the ECMAScript Boolean value x.
- return x
- }
- // https://webidl.spec.whatwg.org/#es-any
- webidl.converters.any = function (V) {
- return V
- }
- // https://webidl.spec.whatwg.org/#es-long-long
- webidl.converters['long long'] = function (V, prefix, argument) {
- // 1. Let x be ? ConvertToInt(V, 64, "signed").
- const x = webidl.util.ConvertToInt(V, 64, 'signed', 0, prefix, argument)
- // 2. Return the IDL long long value that represents
- // the same numeric value as x.
- return x
- }
- // https://webidl.spec.whatwg.org/#es-unsigned-long-long
- webidl.converters['unsigned long long'] = function (V, prefix, argument) {
- // 1. Let x be ? ConvertToInt(V, 64, "unsigned").
- const x = webidl.util.ConvertToInt(V, 64, 'unsigned', 0, prefix, argument)
- // 2. Return the IDL unsigned long long value that
- // represents the same numeric value as x.
- return x
- }
- // https://webidl.spec.whatwg.org/#es-unsigned-long
- webidl.converters['unsigned long'] = function (V, prefix, argument) {
- // 1. Let x be ? ConvertToInt(V, 32, "unsigned").
- const x = webidl.util.ConvertToInt(V, 32, 'unsigned', 0, prefix, argument)
- // 2. Return the IDL unsigned long value that
- // represents the same numeric value as x.
- return x
- }
- // https://webidl.spec.whatwg.org/#es-unsigned-short
- webidl.converters['unsigned short'] = function (V, prefix, argument, flags) {
- // 1. Let x be ? ConvertToInt(V, 16, "unsigned").
- const x = webidl.util.ConvertToInt(V, 16, 'unsigned', flags, prefix, argument)
- // 2. Return the IDL unsigned short value that represents
- // the same numeric value as x.
- return x
- }
- // https://webidl.spec.whatwg.org/#idl-ArrayBuffer
- webidl.converters.ArrayBuffer = function (V, prefix, argument, flags) {
- // 1. If V is not an Object, or V does not have an
- // [[ArrayBufferData]] internal slot, then throw a
- // TypeError.
- // 2. If IsSharedArrayBuffer(V) is true, then throw a
- // TypeError.
- // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances
- if (
- webidl.util.Type(V) !== OBJECT ||
- !types.isArrayBuffer(V)
- ) {
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: ['ArrayBuffer']
- })
- }
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V) is true, then throw a
- // TypeError.
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowResizable) && webidl.util.IsResizableArrayBuffer(V)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a resizable ArrayBuffer.`
- })
- }
- // 4. Return the IDL ArrayBuffer value that is a
- // reference to the same object as V.
- return V
- }
- // https://webidl.spec.whatwg.org/#idl-SharedArrayBuffer
- webidl.converters.SharedArrayBuffer = function (V, prefix, argument, flags) {
- // 1. If V is not an Object, or V does not have an
- // [[ArrayBufferData]] internal slot, then throw a
- // TypeError.
- // 2. If IsSharedArrayBuffer(V) is false, then throw a
- // TypeError.
- // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances
- if (
- webidl.util.Type(V) !== OBJECT ||
- !types.isSharedArrayBuffer(V)
- ) {
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: ['SharedArrayBuffer']
- })
- }
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V) is true, then throw a
- // TypeError.
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowResizable) && webidl.util.IsResizableArrayBuffer(V)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a resizable SharedArrayBuffer.`
- })
- }
- // 4. Return the IDL SharedArrayBuffer value that is a
- // reference to the same object as V.
- return V
- }
- // https://webidl.spec.whatwg.org/#dfn-typed-array-type
- webidl.converters.TypedArray = function (V, T, prefix, argument, flags) {
- // 1. Let T be the IDL type V is being converted to.
- // 2. If Type(V) is not Object, or V does not have a
- // [[TypedArrayName]] internal slot with a value
- // equal to T’s name, then throw a TypeError.
- if (
- webidl.util.Type(V) !== OBJECT ||
- !types.isTypedArray(V) ||
- V.constructor.name !== T.name
- ) {
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: [T.name]
- })
- }
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowShared] extended attribute, and
- // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is
- // true, then throw a TypeError.
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowShared) && types.isSharedArrayBuffer(V.buffer)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a view on a shared array buffer.`
- })
- }
- // 4. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
- // true, then throw a TypeError.
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowResizable) && webidl.util.IsResizableArrayBuffer(V.buffer)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a view on a resizable array buffer.`
- })
- }
- // 5. Return the IDL value of type T that is a reference
- // to the same object as V.
- return V
- }
- // https://webidl.spec.whatwg.org/#idl-DataView
- webidl.converters.DataView = function (V, prefix, argument, flags) {
- // 1. If Type(V) is not Object, or V does not have a
- // [[DataView]] internal slot, then throw a TypeError.
- if (webidl.util.Type(V) !== OBJECT || !types.isDataView(V)) {
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: ['DataView']
- })
- }
- // 2. If the conversion is not to an IDL type associated
- // with the [AllowShared] extended attribute, and
- // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true,
- // then throw a TypeError.
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowShared) && types.isSharedArrayBuffer(V.buffer)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a view on a shared array buffer.`
- })
- }
- // 3. If the conversion is not to an IDL type associated
- // with the [AllowResizable] extended attribute, and
- // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
- // true, then throw a TypeError.
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowResizable) && webidl.util.IsResizableArrayBuffer(V.buffer)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a view on a resizable array buffer.`
- })
- }
- // 4. Return the IDL DataView value that is a reference
- // to the same object as V.
- return V
- }
- // https://webidl.spec.whatwg.org/#ArrayBufferView
- webidl.converters.ArrayBufferView = function (V, prefix, argument, flags) {
- if (
- webidl.util.Type(V) !== OBJECT ||
- !types.isArrayBufferView(V)
- ) {
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: ['ArrayBufferView']
- })
- }
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowShared) && types.isSharedArrayBuffer(V.buffer)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a view on a shared array buffer.`
- })
- }
- if (!webidl.util.HasFlag(flags, webidl.attributes.AllowResizable) && webidl.util.IsResizableArrayBuffer(V.buffer)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a view on a resizable array buffer.`
- })
- }
- return V
- }
- // https://webidl.spec.whatwg.org/#BufferSource
- webidl.converters.BufferSource = function (V, prefix, argument, flags) {
- if (types.isArrayBuffer(V)) {
- return webidl.converters.ArrayBuffer(V, prefix, argument, flags)
- }
- if (types.isArrayBufferView(V)) {
- flags &= ~webidl.attributes.AllowShared
- return webidl.converters.ArrayBufferView(V, prefix, argument, flags)
- }
- // Make this explicit for easier debugging
- if (types.isSharedArrayBuffer(V)) {
- throw webidl.errors.exception({
- header: prefix,
- message: `${argument} cannot be a SharedArrayBuffer.`
- })
- }
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: ['ArrayBuffer', 'ArrayBufferView']
- })
- }
- // https://webidl.spec.whatwg.org/#AllowSharedBufferSource
- webidl.converters.AllowSharedBufferSource = function (V, prefix, argument, flags) {
- if (types.isArrayBuffer(V)) {
- return webidl.converters.ArrayBuffer(V, prefix, argument, flags)
- }
- if (types.isSharedArrayBuffer(V)) {
- return webidl.converters.SharedArrayBuffer(V, prefix, argument, flags)
- }
- if (types.isArrayBufferView(V)) {
- flags |= webidl.attributes.AllowShared
- return webidl.converters.ArrayBufferView(V, prefix, argument, flags)
- }
- throw webidl.errors.conversionFailed({
- prefix,
- argument: `${argument} ("${webidl.util.Stringify(V)}")`,
- types: ['ArrayBuffer', 'SharedArrayBuffer', 'ArrayBufferView']
- })
- }
- webidl.converters['sequence<ByteString>'] = webidl.sequenceConverter(
- webidl.converters.ByteString
- )
- webidl.converters['sequence<sequence<ByteString>>'] = webidl.sequenceConverter(
- webidl.converters['sequence<ByteString>']
- )
- webidl.converters['record<ByteString, ByteString>'] = webidl.recordConverter(
- webidl.converters.ByteString,
- webidl.converters.ByteString
- )
- webidl.converters.Blob = webidl.interfaceConverter(webidl.is.Blob, 'Blob')
- webidl.converters.AbortSignal = webidl.interfaceConverter(
- webidl.is.AbortSignal,
- 'AbortSignal'
- )
- /**
- * [LegacyTreatNonObjectAsNull]
- * callback EventHandlerNonNull = any (Event event);
- * typedef EventHandlerNonNull? EventHandler;
- * @param {*} V
- */
- webidl.converters.EventHandlerNonNull = function (V) {
- if (webidl.util.Type(V) !== OBJECT) {
- return null
- }
- // [I]f the value is not an object, it will be converted to null, and if the value is not callable,
- // it will be converted to a callback function value that does nothing when called.
- if (typeof V === 'function') {
- return V
- }
- return () => {}
- }
- webidl.attributes = {
- Clamp: 1 << 0,
- EnforceRange: 1 << 1,
- AllowShared: 1 << 2,
- AllowResizable: 1 << 3,
- LegacyNullToEmptyString: 1 << 4
- }
- module.exports = {
- webidl
- }
|