[d24f17c] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | const { types } = require('util')
|
---|
| 4 | const { hasOwn, toUSVString } = require('./util')
|
---|
| 5 |
|
---|
| 6 | /** @type {import('../../types/webidl').Webidl} */
|
---|
| 7 | const webidl = {}
|
---|
| 8 | webidl.converters = {}
|
---|
| 9 | webidl.util = {}
|
---|
| 10 | webidl.errors = {}
|
---|
| 11 |
|
---|
| 12 | webidl.errors.exception = function (message) {
|
---|
| 13 | return new TypeError(`${message.header}: ${message.message}`)
|
---|
| 14 | }
|
---|
| 15 |
|
---|
| 16 | webidl.errors.conversionFailed = function (context) {
|
---|
| 17 | const plural = context.types.length === 1 ? '' : ' one of'
|
---|
| 18 | const message =
|
---|
| 19 | `${context.argument} could not be converted to` +
|
---|
| 20 | `${plural}: ${context.types.join(', ')}.`
|
---|
| 21 |
|
---|
| 22 | return webidl.errors.exception({
|
---|
| 23 | header: context.prefix,
|
---|
| 24 | message
|
---|
| 25 | })
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 | webidl.errors.invalidArgument = function (context) {
|
---|
| 29 | return webidl.errors.exception({
|
---|
| 30 | header: context.prefix,
|
---|
| 31 | message: `"${context.value}" is an invalid ${context.type}.`
|
---|
| 32 | })
|
---|
| 33 | }
|
---|
| 34 |
|
---|
| 35 | // https://webidl.spec.whatwg.org/#implements
|
---|
| 36 | webidl.brandCheck = function (V, I, opts = undefined) {
|
---|
| 37 | if (opts?.strict !== false && !(V instanceof I)) {
|
---|
| 38 | throw new TypeError('Illegal invocation')
|
---|
| 39 | } else {
|
---|
| 40 | return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag]
|
---|
| 41 | }
|
---|
| 42 | }
|
---|
| 43 |
|
---|
| 44 | webidl.argumentLengthCheck = function ({ length }, min, ctx) {
|
---|
| 45 | if (length < min) {
|
---|
| 46 | throw webidl.errors.exception({
|
---|
| 47 | message: `${min} argument${min !== 1 ? 's' : ''} required, ` +
|
---|
| 48 | `but${length ? ' only' : ''} ${length} found.`,
|
---|
| 49 | ...ctx
|
---|
| 50 | })
|
---|
| 51 | }
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | webidl.illegalConstructor = function () {
|
---|
| 55 | throw webidl.errors.exception({
|
---|
| 56 | header: 'TypeError',
|
---|
| 57 | message: 'Illegal constructor'
|
---|
| 58 | })
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 | // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
|
---|
| 62 | webidl.util.Type = function (V) {
|
---|
| 63 | switch (typeof V) {
|
---|
| 64 | case 'undefined': return 'Undefined'
|
---|
| 65 | case 'boolean': return 'Boolean'
|
---|
| 66 | case 'string': return 'String'
|
---|
| 67 | case 'symbol': return 'Symbol'
|
---|
| 68 | case 'number': return 'Number'
|
---|
| 69 | case 'bigint': return 'BigInt'
|
---|
| 70 | case 'function':
|
---|
| 71 | case 'object': {
|
---|
| 72 | if (V === null) {
|
---|
| 73 | return 'Null'
|
---|
| 74 | }
|
---|
| 75 |
|
---|
| 76 | return 'Object'
|
---|
| 77 | }
|
---|
| 78 | }
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
|
---|
| 82 | webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) {
|
---|
| 83 | let upperBound
|
---|
| 84 | let lowerBound
|
---|
| 85 |
|
---|
| 86 | // 1. If bitLength is 64, then:
|
---|
| 87 | if (bitLength === 64) {
|
---|
| 88 | // 1. Let upperBound be 2^53 − 1.
|
---|
| 89 | upperBound = Math.pow(2, 53) - 1
|
---|
| 90 |
|
---|
| 91 | // 2. If signedness is "unsigned", then let lowerBound be 0.
|
---|
| 92 | if (signedness === 'unsigned') {
|
---|
| 93 | lowerBound = 0
|
---|
| 94 | } else {
|
---|
| 95 | // 3. Otherwise let lowerBound be −2^53 + 1.
|
---|
| 96 | lowerBound = Math.pow(-2, 53) + 1
|
---|
| 97 | }
|
---|
| 98 | } else if (signedness === 'unsigned') {
|
---|
| 99 | // 2. Otherwise, if signedness is "unsigned", then:
|
---|
| 100 |
|
---|
| 101 | // 1. Let lowerBound be 0.
|
---|
| 102 | lowerBound = 0
|
---|
| 103 |
|
---|
| 104 | // 2. Let upperBound be 2^bitLength − 1.
|
---|
| 105 | upperBound = Math.pow(2, bitLength) - 1
|
---|
| 106 | } else {
|
---|
| 107 | // 3. Otherwise:
|
---|
| 108 |
|
---|
| 109 | // 1. Let lowerBound be -2^bitLength − 1.
|
---|
| 110 | lowerBound = Math.pow(-2, bitLength) - 1
|
---|
| 111 |
|
---|
| 112 | // 2. Let upperBound be 2^bitLength − 1 − 1.
|
---|
| 113 | upperBound = Math.pow(2, bitLength - 1) - 1
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | // 4. Let x be ? ToNumber(V).
|
---|
| 117 | let x = Number(V)
|
---|
| 118 |
|
---|
| 119 | // 5. If x is −0, then set x to +0.
|
---|
| 120 | if (x === 0) {
|
---|
| 121 | x = 0
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | // 6. If the conversion is to an IDL type associated
|
---|
| 125 | // with the [EnforceRange] extended attribute, then:
|
---|
| 126 | if (opts.enforceRange === true) {
|
---|
| 127 | // 1. If x is NaN, +∞, or −∞, then throw a TypeError.
|
---|
| 128 | if (
|
---|
| 129 | Number.isNaN(x) ||
|
---|
| 130 | x === Number.POSITIVE_INFINITY ||
|
---|
| 131 | x === Number.NEGATIVE_INFINITY
|
---|
| 132 | ) {
|
---|
| 133 | throw webidl.errors.exception({
|
---|
| 134 | header: 'Integer conversion',
|
---|
| 135 | message: `Could not convert ${V} to an integer.`
|
---|
| 136 | })
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | // 2. Set x to IntegerPart(x).
|
---|
| 140 | x = webidl.util.IntegerPart(x)
|
---|
| 141 |
|
---|
| 142 | // 3. If x < lowerBound or x > upperBound, then
|
---|
| 143 | // throw a TypeError.
|
---|
| 144 | if (x < lowerBound || x > upperBound) {
|
---|
| 145 | throw webidl.errors.exception({
|
---|
| 146 | header: 'Integer conversion',
|
---|
| 147 | message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.`
|
---|
| 148 | })
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 | // 4. Return x.
|
---|
| 152 | return x
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | // 7. If x is not NaN and the conversion is to an IDL
|
---|
| 156 | // type associated with the [Clamp] extended
|
---|
| 157 | // attribute, then:
|
---|
| 158 | if (!Number.isNaN(x) && opts.clamp === true) {
|
---|
| 159 | // 1. Set x to min(max(x, lowerBound), upperBound).
|
---|
| 160 | x = Math.min(Math.max(x, lowerBound), upperBound)
|
---|
| 161 |
|
---|
| 162 | // 2. Round x to the nearest integer, choosing the
|
---|
| 163 | // even integer if it lies halfway between two,
|
---|
| 164 | // and choosing +0 rather than −0.
|
---|
| 165 | if (Math.floor(x) % 2 === 0) {
|
---|
| 166 | x = Math.floor(x)
|
---|
| 167 | } else {
|
---|
| 168 | x = Math.ceil(x)
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 | // 3. Return x.
|
---|
| 172 | return x
|
---|
| 173 | }
|
---|
| 174 |
|
---|
| 175 | // 8. If x is NaN, +0, +∞, or −∞, then return +0.
|
---|
| 176 | if (
|
---|
| 177 | Number.isNaN(x) ||
|
---|
| 178 | (x === 0 && Object.is(0, x)) ||
|
---|
| 179 | x === Number.POSITIVE_INFINITY ||
|
---|
| 180 | x === Number.NEGATIVE_INFINITY
|
---|
| 181 | ) {
|
---|
| 182 | return 0
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | // 9. Set x to IntegerPart(x).
|
---|
| 186 | x = webidl.util.IntegerPart(x)
|
---|
| 187 |
|
---|
| 188 | // 10. Set x to x modulo 2^bitLength.
|
---|
| 189 | x = x % Math.pow(2, bitLength)
|
---|
| 190 |
|
---|
| 191 | // 11. If signedness is "signed" and x ≥ 2^bitLength − 1,
|
---|
| 192 | // then return x − 2^bitLength.
|
---|
| 193 | if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) {
|
---|
| 194 | return x - Math.pow(2, bitLength)
|
---|
| 195 | }
|
---|
| 196 |
|
---|
| 197 | // 12. Otherwise, return x.
|
---|
| 198 | return x
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 | // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
|
---|
| 202 | webidl.util.IntegerPart = function (n) {
|
---|
| 203 | // 1. Let r be floor(abs(n)).
|
---|
| 204 | const r = Math.floor(Math.abs(n))
|
---|
| 205 |
|
---|
| 206 | // 2. If n < 0, then return -1 × r.
|
---|
| 207 | if (n < 0) {
|
---|
| 208 | return -1 * r
|
---|
| 209 | }
|
---|
| 210 |
|
---|
| 211 | // 3. Otherwise, return r.
|
---|
| 212 | return r
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | // https://webidl.spec.whatwg.org/#es-sequence
|
---|
| 216 | webidl.sequenceConverter = function (converter) {
|
---|
| 217 | return (V) => {
|
---|
| 218 | // 1. If Type(V) is not Object, throw a TypeError.
|
---|
| 219 | if (webidl.util.Type(V) !== 'Object') {
|
---|
| 220 | throw webidl.errors.exception({
|
---|
| 221 | header: 'Sequence',
|
---|
| 222 | message: `Value of type ${webidl.util.Type(V)} is not an Object.`
|
---|
| 223 | })
|
---|
| 224 | }
|
---|
| 225 |
|
---|
| 226 | // 2. Let method be ? GetMethod(V, @@iterator).
|
---|
| 227 | /** @type {Generator} */
|
---|
| 228 | const method = V?.[Symbol.iterator]?.()
|
---|
| 229 | const seq = []
|
---|
| 230 |
|
---|
| 231 | // 3. If method is undefined, throw a TypeError.
|
---|
| 232 | if (
|
---|
| 233 | method === undefined ||
|
---|
| 234 | typeof method.next !== 'function'
|
---|
| 235 | ) {
|
---|
| 236 | throw webidl.errors.exception({
|
---|
| 237 | header: 'Sequence',
|
---|
| 238 | message: 'Object is not an iterator.'
|
---|
| 239 | })
|
---|
| 240 | }
|
---|
| 241 |
|
---|
| 242 | // https://webidl.spec.whatwg.org/#create-sequence-from-iterable
|
---|
| 243 | while (true) {
|
---|
| 244 | const { done, value } = method.next()
|
---|
| 245 |
|
---|
| 246 | if (done) {
|
---|
| 247 | break
|
---|
| 248 | }
|
---|
| 249 |
|
---|
| 250 | seq.push(converter(value))
|
---|
| 251 | }
|
---|
| 252 |
|
---|
| 253 | return seq
|
---|
| 254 | }
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | // https://webidl.spec.whatwg.org/#es-to-record
|
---|
| 258 | webidl.recordConverter = function (keyConverter, valueConverter) {
|
---|
| 259 | return (O) => {
|
---|
| 260 | // 1. If Type(O) is not Object, throw a TypeError.
|
---|
| 261 | if (webidl.util.Type(O) !== 'Object') {
|
---|
| 262 | throw webidl.errors.exception({
|
---|
| 263 | header: 'Record',
|
---|
| 264 | message: `Value of type ${webidl.util.Type(O)} is not an Object.`
|
---|
| 265 | })
|
---|
| 266 | }
|
---|
| 267 |
|
---|
| 268 | // 2. Let result be a new empty instance of record<K, V>.
|
---|
| 269 | const result = {}
|
---|
| 270 |
|
---|
| 271 | if (!types.isProxy(O)) {
|
---|
| 272 | // Object.keys only returns enumerable properties
|
---|
| 273 | const keys = Object.keys(O)
|
---|
| 274 |
|
---|
| 275 | for (const key of keys) {
|
---|
| 276 | // 1. Let typedKey be key converted to an IDL value of type K.
|
---|
| 277 | const typedKey = keyConverter(key)
|
---|
| 278 |
|
---|
| 279 | // 2. Let value be ? Get(O, key).
|
---|
| 280 | // 3. Let typedValue be value converted to an IDL value of type V.
|
---|
| 281 | const typedValue = valueConverter(O[key])
|
---|
| 282 |
|
---|
| 283 | // 4. Set result[typedKey] to typedValue.
|
---|
| 284 | result[typedKey] = typedValue
|
---|
| 285 | }
|
---|
| 286 |
|
---|
| 287 | // 5. Return result.
|
---|
| 288 | return result
|
---|
| 289 | }
|
---|
| 290 |
|
---|
| 291 | // 3. Let keys be ? O.[[OwnPropertyKeys]]().
|
---|
| 292 | const keys = Reflect.ownKeys(O)
|
---|
| 293 |
|
---|
| 294 | // 4. For each key of keys.
|
---|
| 295 | for (const key of keys) {
|
---|
| 296 | // 1. Let desc be ? O.[[GetOwnProperty]](key).
|
---|
| 297 | const desc = Reflect.getOwnPropertyDescriptor(O, key)
|
---|
| 298 |
|
---|
| 299 | // 2. If desc is not undefined and desc.[[Enumerable]] is true:
|
---|
| 300 | if (desc?.enumerable) {
|
---|
| 301 | // 1. Let typedKey be key converted to an IDL value of type K.
|
---|
| 302 | const typedKey = keyConverter(key)
|
---|
| 303 |
|
---|
| 304 | // 2. Let value be ? Get(O, key).
|
---|
| 305 | // 3. Let typedValue be value converted to an IDL value of type V.
|
---|
| 306 | const typedValue = valueConverter(O[key])
|
---|
| 307 |
|
---|
| 308 | // 4. Set result[typedKey] to typedValue.
|
---|
| 309 | result[typedKey] = typedValue
|
---|
| 310 | }
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | // 5. Return result.
|
---|
| 314 | return result
|
---|
| 315 | }
|
---|
| 316 | }
|
---|
| 317 |
|
---|
| 318 | webidl.interfaceConverter = function (i) {
|
---|
| 319 | return (V, opts = {}) => {
|
---|
| 320 | if (opts.strict !== false && !(V instanceof i)) {
|
---|
| 321 | throw webidl.errors.exception({
|
---|
| 322 | header: i.name,
|
---|
| 323 | message: `Expected ${V} to be an instance of ${i.name}.`
|
---|
| 324 | })
|
---|
| 325 | }
|
---|
| 326 |
|
---|
| 327 | return V
|
---|
| 328 | }
|
---|
| 329 | }
|
---|
| 330 |
|
---|
| 331 | webidl.dictionaryConverter = function (converters) {
|
---|
| 332 | return (dictionary) => {
|
---|
| 333 | const type = webidl.util.Type(dictionary)
|
---|
| 334 | const dict = {}
|
---|
| 335 |
|
---|
| 336 | if (type === 'Null' || type === 'Undefined') {
|
---|
| 337 | return dict
|
---|
| 338 | } else if (type !== 'Object') {
|
---|
| 339 | throw webidl.errors.exception({
|
---|
| 340 | header: 'Dictionary',
|
---|
| 341 | message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`
|
---|
| 342 | })
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | for (const options of converters) {
|
---|
| 346 | const { key, defaultValue, required, converter } = options
|
---|
| 347 |
|
---|
| 348 | if (required === true) {
|
---|
| 349 | if (!hasOwn(dictionary, key)) {
|
---|
| 350 | throw webidl.errors.exception({
|
---|
| 351 | header: 'Dictionary',
|
---|
| 352 | message: `Missing required key "${key}".`
|
---|
| 353 | })
|
---|
| 354 | }
|
---|
| 355 | }
|
---|
| 356 |
|
---|
| 357 | let value = dictionary[key]
|
---|
| 358 | const hasDefault = hasOwn(options, 'defaultValue')
|
---|
| 359 |
|
---|
| 360 | // Only use defaultValue if value is undefined and
|
---|
| 361 | // a defaultValue options was provided.
|
---|
| 362 | if (hasDefault && value !== null) {
|
---|
| 363 | value = value ?? defaultValue
|
---|
| 364 | }
|
---|
| 365 |
|
---|
| 366 | // A key can be optional and have no default value.
|
---|
| 367 | // When this happens, do not perform a conversion,
|
---|
| 368 | // and do not assign the key a value.
|
---|
| 369 | if (required || hasDefault || value !== undefined) {
|
---|
| 370 | value = converter(value)
|
---|
| 371 |
|
---|
| 372 | if (
|
---|
| 373 | options.allowedValues &&
|
---|
| 374 | !options.allowedValues.includes(value)
|
---|
| 375 | ) {
|
---|
| 376 | throw webidl.errors.exception({
|
---|
| 377 | header: 'Dictionary',
|
---|
| 378 | message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.`
|
---|
| 379 | })
|
---|
| 380 | }
|
---|
| 381 |
|
---|
| 382 | dict[key] = value
|
---|
| 383 | }
|
---|
| 384 | }
|
---|
| 385 |
|
---|
| 386 | return dict
|
---|
| 387 | }
|
---|
| 388 | }
|
---|
| 389 |
|
---|
| 390 | webidl.nullableConverter = function (converter) {
|
---|
| 391 | return (V) => {
|
---|
| 392 | if (V === null) {
|
---|
| 393 | return V
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 | return converter(V)
|
---|
| 397 | }
|
---|
| 398 | }
|
---|
| 399 |
|
---|
| 400 | // https://webidl.spec.whatwg.org/#es-DOMString
|
---|
| 401 | webidl.converters.DOMString = function (V, opts = {}) {
|
---|
| 402 | // 1. If V is null and the conversion is to an IDL type
|
---|
| 403 | // associated with the [LegacyNullToEmptyString]
|
---|
| 404 | // extended attribute, then return the DOMString value
|
---|
| 405 | // that represents the empty string.
|
---|
| 406 | if (V === null && opts.legacyNullToEmptyString) {
|
---|
| 407 | return ''
|
---|
| 408 | }
|
---|
| 409 |
|
---|
| 410 | // 2. Let x be ? ToString(V).
|
---|
| 411 | if (typeof V === 'symbol') {
|
---|
| 412 | throw new TypeError('Could not convert argument of type symbol to string.')
|
---|
| 413 | }
|
---|
| 414 |
|
---|
| 415 | // 3. Return the IDL DOMString value that represents the
|
---|
| 416 | // same sequence of code units as the one the
|
---|
| 417 | // ECMAScript String value x represents.
|
---|
| 418 | return String(V)
|
---|
| 419 | }
|
---|
| 420 |
|
---|
| 421 | // https://webidl.spec.whatwg.org/#es-ByteString
|
---|
| 422 | webidl.converters.ByteString = function (V) {
|
---|
| 423 | // 1. Let x be ? ToString(V).
|
---|
| 424 | // Note: DOMString converter perform ? ToString(V)
|
---|
| 425 | const x = webidl.converters.DOMString(V)
|
---|
| 426 |
|
---|
| 427 | // 2. If the value of any element of x is greater than
|
---|
| 428 | // 255, then throw a TypeError.
|
---|
| 429 | for (let index = 0; index < x.length; index++) {
|
---|
| 430 | if (x.charCodeAt(index) > 255) {
|
---|
| 431 | throw new TypeError(
|
---|
| 432 | 'Cannot convert argument to a ByteString because the character at ' +
|
---|
| 433 | `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.`
|
---|
| 434 | )
|
---|
| 435 | }
|
---|
| 436 | }
|
---|
| 437 |
|
---|
| 438 | // 3. Return an IDL ByteString value whose length is the
|
---|
| 439 | // length of x, and where the value of each element is
|
---|
| 440 | // the value of the corresponding element of x.
|
---|
| 441 | return x
|
---|
| 442 | }
|
---|
| 443 |
|
---|
| 444 | // https://webidl.spec.whatwg.org/#es-USVString
|
---|
| 445 | webidl.converters.USVString = toUSVString
|
---|
| 446 |
|
---|
| 447 | // https://webidl.spec.whatwg.org/#es-boolean
|
---|
| 448 | webidl.converters.boolean = function (V) {
|
---|
| 449 | // 1. Let x be the result of computing ToBoolean(V).
|
---|
| 450 | const x = Boolean(V)
|
---|
| 451 |
|
---|
| 452 | // 2. Return the IDL boolean value that is the one that represents
|
---|
| 453 | // the same truth value as the ECMAScript Boolean value x.
|
---|
| 454 | return x
|
---|
| 455 | }
|
---|
| 456 |
|
---|
| 457 | // https://webidl.spec.whatwg.org/#es-any
|
---|
| 458 | webidl.converters.any = function (V) {
|
---|
| 459 | return V
|
---|
| 460 | }
|
---|
| 461 |
|
---|
| 462 | // https://webidl.spec.whatwg.org/#es-long-long
|
---|
| 463 | webidl.converters['long long'] = function (V) {
|
---|
| 464 | // 1. Let x be ? ConvertToInt(V, 64, "signed").
|
---|
| 465 | const x = webidl.util.ConvertToInt(V, 64, 'signed')
|
---|
| 466 |
|
---|
| 467 | // 2. Return the IDL long long value that represents
|
---|
| 468 | // the same numeric value as x.
|
---|
| 469 | return x
|
---|
| 470 | }
|
---|
| 471 |
|
---|
| 472 | // https://webidl.spec.whatwg.org/#es-unsigned-long-long
|
---|
| 473 | webidl.converters['unsigned long long'] = function (V) {
|
---|
| 474 | // 1. Let x be ? ConvertToInt(V, 64, "unsigned").
|
---|
| 475 | const x = webidl.util.ConvertToInt(V, 64, 'unsigned')
|
---|
| 476 |
|
---|
| 477 | // 2. Return the IDL unsigned long long value that
|
---|
| 478 | // represents the same numeric value as x.
|
---|
| 479 | return x
|
---|
| 480 | }
|
---|
| 481 |
|
---|
| 482 | // https://webidl.spec.whatwg.org/#es-unsigned-long
|
---|
| 483 | webidl.converters['unsigned long'] = function (V) {
|
---|
| 484 | // 1. Let x be ? ConvertToInt(V, 32, "unsigned").
|
---|
| 485 | const x = webidl.util.ConvertToInt(V, 32, 'unsigned')
|
---|
| 486 |
|
---|
| 487 | // 2. Return the IDL unsigned long value that
|
---|
| 488 | // represents the same numeric value as x.
|
---|
| 489 | return x
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 | // https://webidl.spec.whatwg.org/#es-unsigned-short
|
---|
| 493 | webidl.converters['unsigned short'] = function (V, opts) {
|
---|
| 494 | // 1. Let x be ? ConvertToInt(V, 16, "unsigned").
|
---|
| 495 | const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts)
|
---|
| 496 |
|
---|
| 497 | // 2. Return the IDL unsigned short value that represents
|
---|
| 498 | // the same numeric value as x.
|
---|
| 499 | return x
|
---|
| 500 | }
|
---|
| 501 |
|
---|
| 502 | // https://webidl.spec.whatwg.org/#idl-ArrayBuffer
|
---|
| 503 | webidl.converters.ArrayBuffer = function (V, opts = {}) {
|
---|
| 504 | // 1. If Type(V) is not Object, or V does not have an
|
---|
| 505 | // [[ArrayBufferData]] internal slot, then throw a
|
---|
| 506 | // TypeError.
|
---|
| 507 | // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances
|
---|
| 508 | // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances
|
---|
| 509 | if (
|
---|
| 510 | webidl.util.Type(V) !== 'Object' ||
|
---|
| 511 | !types.isAnyArrayBuffer(V)
|
---|
| 512 | ) {
|
---|
| 513 | throw webidl.errors.conversionFailed({
|
---|
| 514 | prefix: `${V}`,
|
---|
| 515 | argument: `${V}`,
|
---|
| 516 | types: ['ArrayBuffer']
|
---|
| 517 | })
|
---|
| 518 | }
|
---|
| 519 |
|
---|
| 520 | // 2. If the conversion is not to an IDL type associated
|
---|
| 521 | // with the [AllowShared] extended attribute, and
|
---|
| 522 | // IsSharedArrayBuffer(V) is true, then throw a
|
---|
| 523 | // TypeError.
|
---|
| 524 | if (opts.allowShared === false && types.isSharedArrayBuffer(V)) {
|
---|
| 525 | throw webidl.errors.exception({
|
---|
| 526 | header: 'ArrayBuffer',
|
---|
| 527 | message: 'SharedArrayBuffer is not allowed.'
|
---|
| 528 | })
|
---|
| 529 | }
|
---|
| 530 |
|
---|
| 531 | // 3. If the conversion is not to an IDL type associated
|
---|
| 532 | // with the [AllowResizable] extended attribute, and
|
---|
| 533 | // IsResizableArrayBuffer(V) is true, then throw a
|
---|
| 534 | // TypeError.
|
---|
| 535 | // Note: resizable ArrayBuffers are currently a proposal.
|
---|
| 536 |
|
---|
| 537 | // 4. Return the IDL ArrayBuffer value that is a
|
---|
| 538 | // reference to the same object as V.
|
---|
| 539 | return V
|
---|
| 540 | }
|
---|
| 541 |
|
---|
| 542 | webidl.converters.TypedArray = function (V, T, opts = {}) {
|
---|
| 543 | // 1. Let T be the IDL type V is being converted to.
|
---|
| 544 |
|
---|
| 545 | // 2. If Type(V) is not Object, or V does not have a
|
---|
| 546 | // [[TypedArrayName]] internal slot with a value
|
---|
| 547 | // equal to T’s name, then throw a TypeError.
|
---|
| 548 | if (
|
---|
| 549 | webidl.util.Type(V) !== 'Object' ||
|
---|
| 550 | !types.isTypedArray(V) ||
|
---|
| 551 | V.constructor.name !== T.name
|
---|
| 552 | ) {
|
---|
| 553 | throw webidl.errors.conversionFailed({
|
---|
| 554 | prefix: `${T.name}`,
|
---|
| 555 | argument: `${V}`,
|
---|
| 556 | types: [T.name]
|
---|
| 557 | })
|
---|
| 558 | }
|
---|
| 559 |
|
---|
| 560 | // 3. If the conversion is not to an IDL type associated
|
---|
| 561 | // with the [AllowShared] extended attribute, and
|
---|
| 562 | // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is
|
---|
| 563 | // true, then throw a TypeError.
|
---|
| 564 | if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) {
|
---|
| 565 | throw webidl.errors.exception({
|
---|
| 566 | header: 'ArrayBuffer',
|
---|
| 567 | message: 'SharedArrayBuffer is not allowed.'
|
---|
| 568 | })
|
---|
| 569 | }
|
---|
| 570 |
|
---|
| 571 | // 4. If the conversion is not to an IDL type associated
|
---|
| 572 | // with the [AllowResizable] extended attribute, and
|
---|
| 573 | // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
|
---|
| 574 | // true, then throw a TypeError.
|
---|
| 575 | // Note: resizable array buffers are currently a proposal
|
---|
| 576 |
|
---|
| 577 | // 5. Return the IDL value of type T that is a reference
|
---|
| 578 | // to the same object as V.
|
---|
| 579 | return V
|
---|
| 580 | }
|
---|
| 581 |
|
---|
| 582 | webidl.converters.DataView = function (V, opts = {}) {
|
---|
| 583 | // 1. If Type(V) is not Object, or V does not have a
|
---|
| 584 | // [[DataView]] internal slot, then throw a TypeError.
|
---|
| 585 | if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) {
|
---|
| 586 | throw webidl.errors.exception({
|
---|
| 587 | header: 'DataView',
|
---|
| 588 | message: 'Object is not a DataView.'
|
---|
| 589 | })
|
---|
| 590 | }
|
---|
| 591 |
|
---|
| 592 | // 2. If the conversion is not to an IDL type associated
|
---|
| 593 | // with the [AllowShared] extended attribute, and
|
---|
| 594 | // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true,
|
---|
| 595 | // then throw a TypeError.
|
---|
| 596 | if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) {
|
---|
| 597 | throw webidl.errors.exception({
|
---|
| 598 | header: 'ArrayBuffer',
|
---|
| 599 | message: 'SharedArrayBuffer is not allowed.'
|
---|
| 600 | })
|
---|
| 601 | }
|
---|
| 602 |
|
---|
| 603 | // 3. If the conversion is not to an IDL type associated
|
---|
| 604 | // with the [AllowResizable] extended attribute, and
|
---|
| 605 | // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is
|
---|
| 606 | // true, then throw a TypeError.
|
---|
| 607 | // Note: resizable ArrayBuffers are currently a proposal
|
---|
| 608 |
|
---|
| 609 | // 4. Return the IDL DataView value that is a reference
|
---|
| 610 | // to the same object as V.
|
---|
| 611 | return V
|
---|
| 612 | }
|
---|
| 613 |
|
---|
| 614 | // https://webidl.spec.whatwg.org/#BufferSource
|
---|
| 615 | webidl.converters.BufferSource = function (V, opts = {}) {
|
---|
| 616 | if (types.isAnyArrayBuffer(V)) {
|
---|
| 617 | return webidl.converters.ArrayBuffer(V, opts)
|
---|
| 618 | }
|
---|
| 619 |
|
---|
| 620 | if (types.isTypedArray(V)) {
|
---|
| 621 | return webidl.converters.TypedArray(V, V.constructor)
|
---|
| 622 | }
|
---|
| 623 |
|
---|
| 624 | if (types.isDataView(V)) {
|
---|
| 625 | return webidl.converters.DataView(V, opts)
|
---|
| 626 | }
|
---|
| 627 |
|
---|
| 628 | throw new TypeError(`Could not convert ${V} to a BufferSource.`)
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | webidl.converters['sequence<ByteString>'] = webidl.sequenceConverter(
|
---|
| 632 | webidl.converters.ByteString
|
---|
| 633 | )
|
---|
| 634 |
|
---|
| 635 | webidl.converters['sequence<sequence<ByteString>>'] = webidl.sequenceConverter(
|
---|
| 636 | webidl.converters['sequence<ByteString>']
|
---|
| 637 | )
|
---|
| 638 |
|
---|
| 639 | webidl.converters['record<ByteString, ByteString>'] = webidl.recordConverter(
|
---|
| 640 | webidl.converters.ByteString,
|
---|
| 641 | webidl.converters.ByteString
|
---|
| 642 | )
|
---|
| 643 |
|
---|
| 644 | module.exports = {
|
---|
| 645 | webidl
|
---|
| 646 | }
|
---|