@es-joy/jsoe 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3489,22 +3489,8 @@ const structuredCloning = {
3489
3489
  // Not yet supported within JSOE
3490
3490
  'imagedata',
3491
3491
  'imagebitmap',
3492
- 'arraybuffer',
3493
- 'dataview',
3494
3492
  'cryptokey',
3495
- 'domquad',
3496
-
3497
- 'bigint64array',
3498
- 'biguint64array',
3499
- 'float32array',
3500
- 'float64array',
3501
- 'int8array',
3502
- 'int16array',
3503
- 'int32array',
3504
- 'uint8array',
3505
- 'uint8clampedarray',
3506
- 'uint16array',
3507
- 'uint32array'
3493
+ 'domquad'
3508
3494
  ].some((prop) => {
3509
3495
  return Object.hasOwn(typeSpecSet, prop);
3510
3496
  });
@@ -3597,25 +3583,13 @@ const structuredCloning = {
3597
3583
  'domrect',
3598
3584
  'dompoint',
3599
3585
  'dommatrix',
3586
+ 'buffersource',
3600
3587
  'resurrectable'
3601
3588
 
3602
3589
  // Ok, but will need some work and/or decisions on how to present:
3603
3590
  // 'cryptokey',
3604
3591
  // 'domquad',
3605
- // 'arraybuffer',
3606
- // 'dataview', 'imagedata', 'imagebitmap',
3607
- /*
3608
- // Typed Arrays
3609
- 'int8array',
3610
- 'uint8array',
3611
- 'uint8clampedarray',
3612
- 'int16array',
3613
- 'uint16array',
3614
- 'int32array',
3615
- 'uint32array',
3616
- 'float32array',
3617
- 'float64array',
3618
- */
3592
+ // 'imagedata', 'imagebitmap',
3619
3593
  ];
3620
3594
  }
3621
3595
  };
@@ -3623,7 +3597,8 @@ const structuredCloning = {
3623
3597
  /** @type {import('../formats.js').Format} */
3624
3598
  const indexedDBKey = {
3625
3599
  types: () => [
3626
- 'number', 'SpecialRealNumber', 'string', 'ValidDate', 'array'
3600
+ 'number', 'SpecialRealNumber', 'string', 'ValidDate', 'array',
3601
+ 'buffersource'
3627
3602
  ],
3628
3603
  // A hack until we simply pass in our own types or do own parsing
3629
3604
  testInvalid (newType, value) {
@@ -3661,8 +3636,6 @@ const indexedDBKey = {
3661
3636
  }
3662
3637
  };
3663
3638
 
3664
- // Todo (low): Support ArrayBuffer
3665
-
3666
3639
  /**
3667
3640
  * @type {Map<import('../types.js').AvailableType,
3668
3641
  * import('../types.js').AvailableType>
@@ -6630,7 +6603,7 @@ const regexpType = {
6630
6603
  }, '')
6631
6604
  );
6632
6605
  },
6633
- allowedFlags: ['g', 'i', 'm', 'u', 'y', 's'],
6606
+ allowedFlags: ['g', 'i', 'm', 'u', 'y', 's', 'v'],
6634
6607
  viewUI ({value}) {
6635
6608
  return ['i', {dataset: {type: 'regexp'}}, [String(value)]];
6636
6609
  },
@@ -10485,7 +10458,7 @@ const domexceptionType = {
10485
10458
  }
10486
10459
  };
10487
10460
 
10488
- let idx$2 = 0;
10461
+ let idx$3 = 0;
10489
10462
 
10490
10463
  /**
10491
10464
  * @type {import('../types.js').SuperTypeObject}
@@ -10577,7 +10550,7 @@ const domrectType = {
10577
10550
  width: '',
10578
10551
  height: ''
10579
10552
  }}) {
10580
- idx$2++;
10553
+ idx$3++;
10581
10554
  // eslint-disable-next-line @stylistic/max-len -- Long
10582
10555
  return ['div', {dataset: {type: 'domrect'}}, /** @type {import('jamilih').JamilihChildren} */ ([
10583
10556
  ['div', [
@@ -10585,7 +10558,7 @@ const domrectType = {
10585
10558
  ['input', {
10586
10559
  type: 'radio',
10587
10560
  class: 'domrect-readonly-readwrite',
10588
- name: `${typeNamespace}-domrect-readonly-${idx$2}`,
10561
+ name: `${typeNamespace}-domrect-readonly-${idx$3}`,
10589
10562
  value: 'readwrite',
10590
10563
  checked: toStringTag(value) !== 'DOMRectReadOnly'
10591
10564
  }],
@@ -10596,7 +10569,7 @@ const domrectType = {
10596
10569
  ['input', {
10597
10570
  type: 'radio',
10598
10571
  class: 'domrect-readonly-readonly',
10599
- name: `${typeNamespace}-domrect-readonly-${idx$2}`,
10572
+ name: `${typeNamespace}-domrect-readonly-${idx$3}`,
10600
10573
  value: 'readonly',
10601
10574
  checked: toStringTag(value) === 'DOMRectReadOnly'
10602
10575
  }],
@@ -10638,7 +10611,7 @@ const domrectType = {
10638
10611
  }
10639
10612
  };
10640
10613
 
10641
- let idx$1 = 0;
10614
+ let idx$2 = 0;
10642
10615
 
10643
10616
  /**
10644
10617
  * @type {import('../types.js').SuperTypeObject}
@@ -10731,7 +10704,7 @@ const dompointType = {
10731
10704
  z: '',
10732
10705
  w: ''
10733
10706
  }}) {
10734
- idx$1++;
10707
+ idx$2++;
10735
10708
  // eslint-disable-next-line @stylistic/max-len -- Long
10736
10709
  return ['div', {dataset: {type: 'dompoint'}}, /** @type {import('jamilih').JamilihChildren} */ ([
10737
10710
  ['div', [
@@ -10739,7 +10712,7 @@ const dompointType = {
10739
10712
  ['input', {
10740
10713
  type: 'radio',
10741
10714
  class: 'dompoint-readonly-readwrite',
10742
- name: `${typeNamespace}-dompoint-readonly-${idx$1}`,
10715
+ name: `${typeNamespace}-dompoint-readonly-${idx$2}`,
10743
10716
  value: 'readwrite',
10744
10717
  checked: toStringTag(value) !== 'DOMPointReadOnly'
10745
10718
  }],
@@ -10750,7 +10723,7 @@ const dompointType = {
10750
10723
  ['input', {
10751
10724
  type: 'radio',
10752
10725
  class: 'dompoint-readonly-readonly',
10753
- name: `${typeNamespace}-dompoint-readonly-${idx$1}`,
10726
+ name: `${typeNamespace}-dompoint-readonly-${idx$2}`,
10754
10727
  value: 'readonly',
10755
10728
  checked: toStringTag(value) === 'DOMPointReadOnly'
10756
10729
  }],
@@ -10792,7 +10765,7 @@ const dompointType = {
10792
10765
  }
10793
10766
  };
10794
10767
 
10795
- let idx = 0;
10768
+ let idx$1 = 0;
10796
10769
 
10797
10770
  /**
10798
10771
  * @type {import('../types.js').SuperTypeObject}
@@ -11093,7 +11066,7 @@ const dommatrixType = {
11093
11066
  ]];
11094
11067
  },
11095
11068
  editUI ({typeNamespace, value = {}}) {
11096
- idx++;
11069
+ idx$1++;
11097
11070
  const {is2D} = value;
11098
11071
  // eslint-disable-next-line @stylistic/max-len -- Long
11099
11072
  return ['div', {dataset: {type: 'dommatrix'}}, /** @type {import('jamilih').JamilihChildren} */ ([
@@ -11102,7 +11075,7 @@ const dommatrixType = {
11102
11075
  ['input', {
11103
11076
  type: 'radio',
11104
11077
  class: 'dommatrix-readonly-readwrite',
11105
- name: `${typeNamespace}-dommatrix-readonly-${idx}`,
11078
+ name: `${typeNamespace}-dommatrix-readonly-${idx$1}`,
11106
11079
  value: 'readwrite',
11107
11080
  checked: toStringTag(value) !== 'DOMMatrixReadOnly'
11108
11081
  }],
@@ -11113,7 +11086,7 @@ const dommatrixType = {
11113
11086
  ['input', {
11114
11087
  type: 'radio',
11115
11088
  class: 'dommatrix-readonly-readonly',
11116
- name: `${typeNamespace}-dommatrix-readonly-${idx}`,
11089
+ name: `${typeNamespace}-dommatrix-readonly-${idx$1}`,
11117
11090
  value: 'readonly',
11118
11091
  checked: toStringTag(value) === 'DOMMatrixReadOnly'
11119
11092
  }],
@@ -11142,7 +11115,7 @@ const dommatrixType = {
11142
11115
  '2d',
11143
11116
  ['input', {
11144
11117
  class: 'd2',
11145
- type: 'radio', name: `${typeNamespace}-dommatrix-dimension-${idx}`,
11118
+ type: 'radio', name: `${typeNamespace}-dommatrix-dimension-${idx$1}`,
11146
11119
  value: '2d',
11147
11120
  checked: Boolean(is2D)
11148
11121
  }]
@@ -11152,7 +11125,7 @@ const dommatrixType = {
11152
11125
  '3d',
11153
11126
  ['input', {
11154
11127
  class: 'd3',
11155
- type: 'radio', name: `${typeNamespace}-dommatrix-dimension-${idx}`,
11128
+ type: 'radio', name: `${typeNamespace}-dommatrix-dimension-${idx$1}`,
11156
11129
  value: '3d',
11157
11130
  checked: !is2D
11158
11131
  }]
@@ -11199,6 +11172,1456 @@ const dommatrixType = {
11199
11172
  }
11200
11173
  };
11201
11174
 
11175
+ const dataViewMethods = /** @type {const} */ ([
11176
+ 'setInt8',
11177
+ 'setUint8',
11178
+ 'setInt16',
11179
+ 'setUint16',
11180
+ 'setInt32',
11181
+ 'setUint32',
11182
+ 'setFloat32',
11183
+ 'setFloat64',
11184
+ 'setBigInt64',
11185
+ 'setBigUint64'
11186
+ ]);
11187
+
11188
+ const typedArrays = /** @type {const} */ ([
11189
+ 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array',
11190
+ 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array',
11191
+ 'Float64Array', 'BigInt64Array', 'BigUint64Array'
11192
+ ]);
11193
+
11194
+ /**
11195
+ * @param {TypedArray} typedArray
11196
+ * @returns {{min: number, max: number}}
11197
+ */
11198
+ const getMinMaxForTypedArray = (typedArray) => {
11199
+ switch (typedArray) {
11200
+ case 'Int8Array':
11201
+ return {min: -128, max: 127};
11202
+ case 'Uint8Array':
11203
+ return {min: 0, max: 255};
11204
+ case 'Uint8ClampedArray':
11205
+ return {min: 0, max: 255};
11206
+ case 'Int16Array':
11207
+ return {min: -32768, max: 32767};
11208
+ case 'Uint16Array':
11209
+ return {min: 0, max: 65535};
11210
+ case 'Int32Array':
11211
+ return {min: -2147483648, max: 2147483647};
11212
+ case 'Uint32Array':
11213
+ return {min: 0, max: 4294967295};
11214
+ case 'Float32Array':
11215
+ return {min: -3.4e38, max: 3.4e38};
11216
+ case 'Float64Array':
11217
+ // eslint-disable-next-line no-loss-of-precision -- Inevitable?
11218
+ return {min: -1.8e308, max: 1.8e308};
11219
+ case 'BigInt64Array':
11220
+ return {min: -(2 ** 63), max: (2 ** 63) - 1};
11221
+ case 'BigUint64Array':
11222
+ return {min: 0, max: (2 ** 64) - 1};
11223
+ /* istanbul ignore next -- Guard */
11224
+ default:
11225
+ /* istanbul ignore next -- Guard */
11226
+ throw new Error('Unexpected typed array type');
11227
+ }
11228
+ };
11229
+
11230
+ /**
11231
+ * @typedef {"Int8Array"|"Uint8Array"|"Uint8ClampedArray"|
11232
+ * "Int16Array"|"Uint16Array"|"Int32Array"|"Uint32Array"|
11233
+ * "Float32Array"|"Float64Array"|"BigInt64Array"|
11234
+ * "BigUint64Array"} TypedArray
11235
+ */
11236
+
11237
+ /**
11238
+ * @typedef {Int8Array|Uint8Array|Uint8ClampedArray|
11239
+ * Int16Array|Uint16Array|Int32Array|Uint32Array|
11240
+ * Float32Array|Float64Array|BigInt64Array|
11241
+ * BigUint64Array} TypedArrayInstance
11242
+ */
11243
+
11244
+ /**
11245
+ * @param {TypedArray} prop
11246
+ * @returns {Int8ArrayConstructor|Uint8ArrayConstructor|
11247
+ * Uint8ClampedArrayConstructor|Int16ArrayConstructor|
11248
+ * Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|
11249
+ * Float32ArrayConstructor|Float64ArrayConstructor|
11250
+ * BigInt64ArrayConstructor|BigUint64ArrayConstructor}
11251
+ */
11252
+ const getTypedArray = (prop) => {
11253
+ switch (prop) {
11254
+ case 'Int8Array':
11255
+ return Int8Array;
11256
+ case 'Uint8Array':
11257
+ return Uint8Array;
11258
+ case 'Uint8ClampedArray':
11259
+ return Uint8ClampedArray;
11260
+ case 'Int16Array':
11261
+ return Int16Array;
11262
+ case 'Uint16Array':
11263
+ return Uint16Array;
11264
+ case 'Int32Array':
11265
+ return Int32Array;
11266
+ case 'Uint32Array':
11267
+ return Uint32Array;
11268
+ case 'Float32Array':
11269
+ return Float32Array;
11270
+ case 'Float64Array':
11271
+ return Float64Array;
11272
+ case 'BigInt64Array':
11273
+ return BigInt64Array;
11274
+ case 'BigUint64Array':
11275
+ return BigUint64Array;
11276
+ /* istanbul ignore next -- Guard */
11277
+ default:
11278
+ /* istanbul ignore next -- Guard */
11279
+ throw new Error('Unexpected type');
11280
+ }
11281
+ };
11282
+
11283
+ let idx = 0;
11284
+
11285
+ /**
11286
+ * @type {import('../types.js').SuperTypeObject}
11287
+ */
11288
+ const buffersourceType = {
11289
+ option: ['Buffer source (ArrayBuffer, DataView, TypedArrays)'],
11290
+ childTypes: [
11291
+ 'arraybuffer',
11292
+ 'dataview',
11293
+ 'int8array', 'uint8array', 'uint8clampedarray', 'int16array',
11294
+ 'uint16array', 'int32array', 'uint32array', 'float32array',
11295
+ 'float64array', 'bigint64array', 'biguint64array'
11296
+ ],
11297
+ stringRegex: /^(?<bufferSourceClass>ArrayBuffer|DataView|(?:Int8|Uint8|Uint8Clamped|Int16|Uint16|Int32|Uint32|Float32|Float64|BigInt64|BigUint64)Array)\((?<innerContent>.*)\)$/u,
11298
+ toValue (s, rootInfo) {
11299
+ const {groups: {
11300
+ bufferSourceClass
11301
+ /* istanbul ignore next -- Should always be found */
11302
+ } = {}} = /** @type {RegExpMatchArray} */ (
11303
+ /** @type {import('../types.js').RootInfo} */ (rootInfo).match
11304
+ );
11305
+
11306
+ const o = JSON.parse(s);
11307
+ const {
11308
+ byteLength, maxByteLength, byteOffset,
11309
+ dataViewByteOffset,
11310
+ dataViewByteLength, length
11311
+ } = o;
11312
+ // @ts-expect-error Ok
11313
+ const buffer = new ArrayBuffer(byteLength, {maxByteLength});
11314
+
11315
+ let typedArray, TypedArray;
11316
+ if (bufferSourceClass.endsWith('Array') || 'typedArray' in o) {
11317
+ TypedArray = getTypedArray(
11318
+ /** @type {TypedArray} */ (o.typedArray ?? bufferSourceClass)
11319
+ );
11320
+
11321
+ typedArray = new TypedArray(buffer, byteOffset, length);
11322
+
11323
+ if ('set' in o) {
11324
+ o.set[0].forEach(
11325
+ /**
11326
+ * @param {string} s
11327
+ * @param {number} i
11328
+ * @returns {void}
11329
+ */
11330
+ (s, i) => {
11331
+ if (typeof s === 'string') {
11332
+ o.set[0][i] = BigInt(s);
11333
+ }
11334
+ }
11335
+ );
11336
+ typedArray.set(...(
11337
+ /**
11338
+ * @type {[
11339
+ * array: Array<bigint> & Array<number>,
11340
+ * offset?: number | undefined
11341
+ * ]}
11342
+ */ (o.set)));
11343
+ }
11344
+ }
11345
+
11346
+ /** @type {DataView|undefined} */
11347
+ let view;
11348
+ if (bufferSourceClass === 'DataView' || dataViewMethods.some((method) => {
11349
+ return method in o;
11350
+ })) {
11351
+ view = new DataView(buffer, dataViewByteOffset, dataViewByteLength);
11352
+ dataViewMethods.forEach((prop) => {
11353
+ o[prop]?.forEach(
11354
+ /**
11355
+ * @type {(info: [
11356
+ * byteOffset: number,
11357
+ * value: bigint|number,
11358
+ * littleEndian?: boolean|undefined
11359
+ * ]) => void}
11360
+ */
11361
+ (vals) => {
11362
+ if (typeof vals[1] === 'string') {
11363
+ vals[1] = BigInt(vals[1]);
11364
+ }
11365
+ // @ts-expect-error It's ok
11366
+ view[prop](...vals);
11367
+ }
11368
+ );
11369
+ });
11370
+ }
11371
+ return {
11372
+ value: bufferSourceClass === 'ArrayBuffer'
11373
+ ? buffer
11374
+ : bufferSourceClass === 'DataView'
11375
+ ? view
11376
+ : typedArray
11377
+ };
11378
+ },
11379
+ getInput ({root}) {
11380
+ const byteLength =
11381
+ /**
11382
+ * @type {HTMLInputElement & {
11383
+ * $value: BufferSource
11384
+ * }}
11385
+ */ ($e(root, '.byteLength'));
11386
+ return byteLength;
11387
+ },
11388
+ setValue ({root, value}) {
11389
+ const stringTag = toStringTag(value);
11390
+ if (stringTag === 'ArrayBuffer' || stringTag === 'DataView') {
11391
+ $e(root, `[value=${stringTag}].buffersource-returnType`)?.click();
11392
+ } else {
11393
+ $e(root, `[value=TypedArray].buffersource-returnType`)?.click();
11394
+ const typedArrays = /** @type {HTMLSelectElement} */ (
11395
+ $e(root, '.buffersource-typedArrays')
11396
+ );
11397
+ typedArrays.value = stringTag;
11398
+ typedArrays.dispatchEvent(new Event('change'));
11399
+ }
11400
+
11401
+ const byteLength =
11402
+ /**
11403
+ * @type {HTMLInputElement & {
11404
+ * $value: BufferSource
11405
+ * }}
11406
+ */ ($e(root, '.byteLength'));
11407
+
11408
+ byteLength.$value = value;
11409
+
11410
+ const buffer = stringTag === 'ArrayBuffer' ? value : value.buffer;
11411
+ byteLength.value = buffer.byteLength;
11412
+ byteLength.dispatchEvent(new Event('change'));
11413
+
11414
+ const maxByteLength = /** @type {HTMLInputElement} */ (
11415
+ $e(root, '.maxByteLength')
11416
+ );
11417
+ maxByteLength.value = buffer.maxByteLength;
11418
+ maxByteLength.dispatchEvent(new Event('change'));
11419
+
11420
+ if (stringTag === 'DataView') {
11421
+ const dataViewByteLength = /** @type {HTMLInputElement} */ (
11422
+ $e(root, '.dataViewByteLength')
11423
+ );
11424
+ dataViewByteLength.value = value.byteLength;
11425
+ dataViewByteLength.dispatchEvent(new Event('change'));
11426
+
11427
+ const dataViewByteOffset = /** @type {HTMLInputElement} */ (
11428
+ $e(root, '.dataViewByteOffset')
11429
+ );
11430
+ dataViewByteOffset.value = value.byteOffset;
11431
+ dataViewByteOffset.dispatchEvent(new Event('change'));
11432
+ } else if (stringTag !== 'ArrayBuffer') { // TypedArray
11433
+ const typedArrayByteOffset = /** @type {HTMLInputElement} */ (
11434
+ $e(root, '.typedArrayByteOffset')
11435
+ );
11436
+ typedArrayByteOffset.value = value.byteOffset;
11437
+ typedArrayByteOffset.dispatchEvent(new Event('change'));
11438
+
11439
+ const typedArrayLength = /** @type {HTMLInputElement} */ (
11440
+ $e(root, '.typedArrayLength')
11441
+ );
11442
+ typedArrayLength.value = value.length;
11443
+ typedArrayLength.dispatchEvent(new Event('change'));
11444
+ }
11445
+ },
11446
+ getValue ({root}) {
11447
+ return /** @type {HTMLInputElement & {$value: BufferSource}} */ (
11448
+ this.getInput({root})
11449
+ ).$value;
11450
+ },
11451
+ viewUI ({value}) {
11452
+ const stringTag = toStringTag(value);
11453
+ const buffer = stringTag === 'ArrayBuffer' ? value : value.buffer;
11454
+
11455
+ return ['div', {dataset: {type: 'buffersource'}}, [
11456
+ ['b', {class: 'emphasis'}, [stringTag]],
11457
+ ['br'],
11458
+ ['b', ['Buffer byte length: ']],
11459
+ buffer.byteLength,
11460
+ ['br'],
11461
+ ['b', ['Buffer max byte length: ']],
11462
+ buffer.maxByteLength,
11463
+
11464
+ ...stringTag === 'DataView'
11465
+ ? [
11466
+ ['br'],
11467
+ ['b', ['Data View byte length: ']],
11468
+ value.byteLength,
11469
+ ['br'],
11470
+ ['b', ['Data View byte offset: ']],
11471
+ value.byteOffset
11472
+ ]
11473
+ : [''],
11474
+ ...(stringTag !== 'DataView' && stringTag !== 'ArrayBuffer') // TypedArray
11475
+ ? [
11476
+ ['br'],
11477
+ ['b', ['Typed Array byte offset: ']],
11478
+ value.byteOffset,
11479
+ ['br'],
11480
+ ['b', ['Typed Array length: ']],
11481
+ value.length
11482
+ ]
11483
+ : [''],
11484
+ ['br'],
11485
+ ['button', {
11486
+ class: 'buffersource-viewData',
11487
+ $on: {
11488
+ async click (e) {
11489
+ e.preventDefault();
11490
+ const dialog = await dialogs.makeCancelDialog({
11491
+ // @ts-expect-error TS bug
11492
+ children: /** @type {import('jamilih').JamilihChildren} */ ([
11493
+ ['select', {
11494
+ class: 'buffersource-typedArrays-view',
11495
+ 'aria-label': 'Typed Arrays',
11496
+ $on: {
11497
+ change () {
11498
+ const typedArrayVal = /** @type {HTMLSelectElement} */ (
11499
+ this
11500
+ ).value;
11501
+ const TypedArray = getTypedArray(
11502
+ /** @type {TypedArray} */ (typedArrayVal)
11503
+ );
11504
+ const typedArray = new TypedArray(buffer);
11505
+ const typedArrayArea = /** @type {HTMLElement} */ ($e(
11506
+ /** @type {HTMLElement} */
11507
+ (this.parentElement),
11508
+ '.typedArrayArea'
11509
+ ));
11510
+ typedArrayArea.textContent = '';
11511
+ typedArrayArea.append(
11512
+ ...Array.from({
11513
+ length: typedArray.length
11514
+ }, (_v, key) => {
11515
+ return jml('span', [
11516
+ ['b', [key]],
11517
+ ' ',
11518
+ ['span', [
11519
+ typedArray[key]
11520
+ ? String(typedArray[key])
11521
+ : '0'
11522
+ ]],
11523
+ ' '
11524
+ ]);
11525
+ })
11526
+ );
11527
+ }
11528
+ }
11529
+ }, typedArrays.map((typedArray) => {
11530
+ return ['option', {
11531
+ selected: stringTag === typedArray
11532
+ ? true
11533
+ : undefined
11534
+ }, [typedArray]];
11535
+ })],
11536
+ ['div', {
11537
+ class: 'typedArrayArea'
11538
+ }]
11539
+ ])
11540
+ });
11541
+
11542
+ /** @type {HTMLSelectElement} */ (
11543
+ $e(dialog, '.buffersource-typedArrays-view')
11544
+ ).dispatchEvent(
11545
+ new Event('change')
11546
+ );
11547
+ // Todo: We could also add `DataView` get methods here
11548
+ // (and length/byte offset for the typed array) if
11549
+ // there is a demand
11550
+ }
11551
+ }
11552
+ }, ['View data']]
11553
+ ]];
11554
+ },
11555
+ editUI ({typeNamespace, value}) {
11556
+ idx++;
11557
+
11558
+ /**
11559
+ * @typedef {() => void} BuildInstances
11560
+ */
11561
+
11562
+ const div = /** @type {HTMLDivElement} */ (jml('div', {
11563
+ dataset: {type: 'buffersource'}
11564
+ }, [
11565
+ ['fieldset', {
11566
+ class: 'returnType',
11567
+ $on: {
11568
+ change () {
11569
+ /**
11570
+ * @type {HTMLFieldSetElement & {
11571
+ * $buildInstances: BuildInstances
11572
+ * }}
11573
+ */ (this).$buildInstances();
11574
+ }
11575
+ },
11576
+ $custom: {
11577
+ /** @type {BuildInstances} */
11578
+ $buildInstances () {
11579
+ const that = /** @type {HTMLFieldSetElement} */ (this);
11580
+ const ancestor = /** @type {HTMLDivElement} */ (that.parentElement);
11581
+ const {value} = /** @type {HTMLInputElement} */ ($e(
11582
+ that, `[name=${typeNamespace}-buffersource-returnType-${idx}]` +
11583
+ `:checked`
11584
+ ));
11585
+
11586
+ const byteLength =
11587
+ /**
11588
+ * @type {HTMLInputElement & {
11589
+ * $value: BufferSource,
11590
+ * $dataView: DataView,
11591
+ * $typedArray: TypedArrayInstance
11592
+ * }}
11593
+ */ (
11594
+ $e(ancestor, '.byteLength')
11595
+ );
11596
+ const byteLengthVal = Number.parseInt(byteLength.value);
11597
+ const maxByteLength = Number.parseInt(
11598
+ /** @type {HTMLInputElement} */ (
11599
+ $e(ancestor, '.maxByteLength')
11600
+ ).value
11601
+ );
11602
+
11603
+ const buffer = new ArrayBuffer(
11604
+ // @ts-expect-error New ArrayBuffer argument
11605
+ byteLengthVal, maxByteLength ? {maxByteLength} : undefined
11606
+ );
11607
+
11608
+ const dataViewByteOffsetVal = /** @type {HTMLInputElement} */ ($e(
11609
+ ancestor,
11610
+ '.dataViewByteOffset'
11611
+ )).value;
11612
+ const dataViewByteOffset = dataViewByteOffsetVal
11613
+ ? Number.parseInt(dataViewByteOffsetVal)
11614
+ : 0;
11615
+
11616
+ const dataViewByteLengthVal = /** @type {HTMLInputElement} */ ($e(
11617
+ ancestor,
11618
+ '.dataViewByteLength'
11619
+ )).value;
11620
+ const dataViewByteLength = dataViewByteLengthVal
11621
+ ? Number.parseInt(dataViewByteLengthVal)
11622
+ : undefined;
11623
+
11624
+ const dataView = new DataView(
11625
+ buffer, dataViewByteOffset, dataViewByteLength
11626
+ );
11627
+
11628
+ const {value: typedArrayValue} = /** @type {HTMLSelectElement} */ (
11629
+ $e(ancestor, '.buffersource-typedArrays-init')
11630
+ );
11631
+
11632
+ const TypedArray = getTypedArray(
11633
+ /** @type {TypedArray} */ (typedArrayValue)
11634
+ );
11635
+ const typedArrayByteOffsetVal =
11636
+ /** @type {HTMLInputElement} */ ($e(
11637
+ ancestor,
11638
+ '.typedArrayByteOffset'
11639
+ )).value;
11640
+ const typedArrayByteOffset = typedArrayByteOffsetVal
11641
+ ? Number.parseInt(typedArrayByteOffsetVal)
11642
+ : 0;
11643
+
11644
+ const typedArrayLengthVal =
11645
+ /** @type {HTMLInputElement} */ ($e(
11646
+ ancestor,
11647
+ '.typedArrayLength'
11648
+ )).value;
11649
+ const typedArrayLength = typedArrayLengthVal
11650
+ ? Number.parseInt(typedArrayLengthVal)
11651
+ : byteLengthVal;
11652
+
11653
+ const typedArray = new TypedArray(
11654
+ buffer, typedArrayByteOffset, typedArrayLength
11655
+ );
11656
+
11657
+ byteLength.$dataView = dataView;
11658
+ byteLength.$typedArray = typedArray;
11659
+
11660
+ const typedArrayValues = $$e(
11661
+ ancestor, '.typedArrayArea .typedArrayValue'
11662
+ ).map((input) => {
11663
+ // Don't check dataset, as may be changing to BigInt now
11664
+ return TypedArray.name.startsWith('Big')
11665
+ ? BigInt(
11666
+ /** @type {HTMLInputElement} */ (input).value
11667
+ )
11668
+ : Number(
11669
+ /** @type {HTMLInputElement} */ (input).value
11670
+ );
11671
+ });
11672
+
11673
+ // @ts-expect-error Ok
11674
+ byteLength.$typedArray.set(typedArrayValues, 0);
11675
+
11676
+ switch (value) {
11677
+ case 'ArrayBuffer':
11678
+ byteLength.$value = buffer;
11679
+ break;
11680
+ case 'DataView': {
11681
+ byteLength.$value = dataView;
11682
+ break;
11683
+ } default: // 'TypedArray'
11684
+ byteLength.$value = typedArray;
11685
+ break;
11686
+ }
11687
+ }
11688
+ }
11689
+ }, [
11690
+ ['legend', ['Return type']],
11691
+ ['label', {
11692
+ $on: {
11693
+ click () {
11694
+ /** @type {HTMLElement} */ ($e(
11695
+ /** @type {HTMLElement} */ (this.parentElement),
11696
+ '.buffersource-typedArrays'
11697
+ )).hidden = true;
11698
+ /** @type {HTMLElement} */ ($e(
11699
+ /** @type {HTMLElement} */ (this?.parentElement?.parentElement),
11700
+ '.buffersource-typedArrays-init'
11701
+ )).hidden = false;
11702
+ }
11703
+ }
11704
+ }, [
11705
+ ['input', {
11706
+ type: 'radio',
11707
+ class: 'buffersource-returnType ' +
11708
+ 'buffersource-returnType-arraybuffer',
11709
+ name: `${typeNamespace}-buffersource-returnType-${idx}`,
11710
+ checked: true,
11711
+ value: 'ArrayBuffer'
11712
+ // checked: toStringTag(value) !== ''
11713
+ }],
11714
+ 'ArrayBuffer'
11715
+ ]],
11716
+ ' ',
11717
+ ['label', {
11718
+ $on: {
11719
+ click () {
11720
+ /** @type {HTMLElement} */ ($e(
11721
+ /** @type {HTMLElement} */ (this.parentElement),
11722
+ '.buffersource-typedArrays'
11723
+ )).hidden = true;
11724
+ /** @type {HTMLElement} */ ($e(
11725
+ /** @type {HTMLElement} */ (this?.parentElement?.parentElement),
11726
+ '.buffersource-typedArrays-init'
11727
+ )).hidden = false;
11728
+ }
11729
+ }
11730
+ }, [
11731
+ ['input', {
11732
+ type: 'radio',
11733
+ class: 'buffersource-returnType buffersource-returnType-dataview',
11734
+ name: `${typeNamespace}-buffersource-returnType-${idx}`,
11735
+ value: 'DataView'
11736
+ // checked: toStringTag(value) !== ''
11737
+ }],
11738
+ 'DataView'
11739
+ ]],
11740
+ ' ',
11741
+ ['label', {
11742
+ $on: {
11743
+ click () {
11744
+ /** @type {HTMLElement} */ ($e(
11745
+ /** @type {HTMLElement} */ (this.parentElement),
11746
+ '.buffersource-typedArrays'
11747
+ )).hidden = false;
11748
+ /** @type {HTMLElement} */ ($e(
11749
+ /** @type {HTMLElement} */ (this?.parentElement?.parentElement),
11750
+ '.buffersource-typedArrays-init'
11751
+ )).hidden = true;
11752
+ }
11753
+ }
11754
+ }, [
11755
+ ['input', {
11756
+ type: 'radio',
11757
+ class: 'buffersource-returnType buffersource-returnType-typedarray',
11758
+ name: `${typeNamespace}-buffersource-returnType-${idx}`,
11759
+ value: 'TypedArray'
11760
+ // checked: toStringTag(value) !== ''
11761
+ }],
11762
+ 'Typed Array'
11763
+ ]],
11764
+ ' ',
11765
+ ['select', {
11766
+ hidden: true, class: 'buffersource-typedArrays',
11767
+ 'aria-label': 'Typed Arrays',
11768
+ $on: {
11769
+ change (e) {
11770
+ const that = /** @type {HTMLSelectElement} */ (this);
11771
+ const ancestor = /** @type {HTMLElement} */ (
11772
+ that.parentElement?.parentElement
11773
+ );
11774
+
11775
+ const select =
11776
+ /**
11777
+ * @type {HTMLSelectElement & {
11778
+ * $setMinsAndMaxes: SetMinsAndMaxes,
11779
+ * $checkTypedArrayByteLength: CheckTypedArrayByteLength
11780
+ * }}
11781
+ */
11782
+ ($e(
11783
+ ancestor,
11784
+ '.buffersource-typedArrays-init'
11785
+ ));
11786
+
11787
+ // Update to reflect current state changes if later revealing
11788
+ select.value = /** @type {HTMLSelectElement} */ (this).value;
11789
+
11790
+ const typedArrayLength =
11791
+ /**
11792
+ * @type {HTMLInputElement & {
11793
+ * $checkBufferBounds: CheckBufferBounds
11794
+ * }}
11795
+ */ (
11796
+ $e(ancestor, '.typedArrayLength')
11797
+ );
11798
+ if (!typedArrayLength.$checkBufferBounds(e)) {
11799
+ return;
11800
+ }
11801
+
11802
+ select.$setMinsAndMaxes(
11803
+ /** @type {TypedArray} */
11804
+ (/** @type {HTMLSelectElement} */ (this).value)
11805
+ );
11806
+
11807
+ select.$checkTypedArrayByteLength(e);
11808
+
11809
+ const typedArrayByteOffset = $e(
11810
+ /** @type {HTMLElement} */
11811
+ (this?.parentElement?.parentElement),
11812
+ '.typedArrayByteOffset'
11813
+ );
11814
+ /**
11815
+ * @type {HTMLInputElement & {
11816
+ * $checkByteOffsetMultiple: CheckByteOffsetMultiple
11817
+ * }}
11818
+ */ (typedArrayByteOffset).$checkByteOffsetMultiple(e);
11819
+ }
11820
+ }
11821
+ }, typedArrays.map((typedArray) => {
11822
+ return ['option', [typedArray]];
11823
+ })]
11824
+ ]],
11825
+ ['fieldset', {
11826
+ $on: {
11827
+ change () {
11828
+ /**
11829
+ * @type {HTMLFieldSetElement & {
11830
+ * $buildInstances: BuildInstances
11831
+ * }}
11832
+ */ (this.previousElementSibling).$buildInstances();
11833
+ }
11834
+ }
11835
+ }, [
11836
+ ['legend', ['Construction options']],
11837
+ ['fieldset', [
11838
+ ['legend', ['ArrayBuffer']],
11839
+ ['label', [
11840
+ 'Byte length ',
11841
+ ['input', {
11842
+ class: 'byteLength',
11843
+ type: 'number', step: '1', size: '4', pattern: '\\d+',
11844
+ min: 0,
11845
+ $custom: {
11846
+ $value: value ?? new ArrayBuffer(0)
11847
+ },
11848
+ $on: {
11849
+ change (e) {
11850
+ const that = /** @type {HTMLInputElement} */ (
11851
+ this
11852
+ );
11853
+
11854
+ const ancestor = /** @type {HTMLElement} */ (
11855
+ that.
11856
+ parentElement?.parentElement?.parentElement?.parentElement
11857
+ );
11858
+ const typedArrayLength =
11859
+ /**
11860
+ * @type {HTMLInputElement & {
11861
+ * $checkBufferBounds: CheckBufferBounds
11862
+ * }}
11863
+ */ (
11864
+ $e(ancestor, '.typedArrayLength')
11865
+ );
11866
+ if (!typedArrayLength.$checkBufferBounds(e)) {
11867
+ return;
11868
+ }
11869
+
11870
+ const maxByteLength = /** @type {HTMLInputElement} */ ($e(
11871
+ /** @type {HTMLElement} */ (
11872
+ that.parentElement?.parentElement
11873
+ ), '.maxByteLength'
11874
+ ));
11875
+ const val = that.value;
11876
+
11877
+ if (Number.parseInt(val) > Number.MAX_SAFE_INTEGER) {
11878
+ that.setCustomValidity(
11879
+ 'The ArrayBuffer length exceeds the maximum ' +
11880
+ 'allowable size'
11881
+ );
11882
+ e.stopPropagation();
11883
+ that.reportValidity();
11884
+ return;
11885
+ }
11886
+ that.setCustomValidity('');
11887
+ that.reportValidity();
11888
+
11889
+ if (
11890
+ Number.parseInt(val) > Number.parseInt(maxByteLength.value)
11891
+ ) {
11892
+ maxByteLength.value = val;
11893
+ }
11894
+
11895
+ const greatGrandparent = /** @type {HTMLElement} */
11896
+ (that.parentElement?.parentElement?.parentElement);
11897
+
11898
+ /**
11899
+ * @type {HTMLInputElement & {
11900
+ * $checkDataViewByteLength: CheckDataViewByteLength
11901
+ * }}
11902
+ */ ($e(
11903
+ greatGrandparent,
11904
+ '.dataViewByteLength'
11905
+ )).$checkDataViewByteLength(e);
11906
+
11907
+ /**
11908
+ * @type {HTMLSelectElement & {
11909
+ * $checkTypedArrayByteLength: CheckTypedArrayByteLength
11910
+ * }}
11911
+ */ ($e(
11912
+ /** @type {HTMLElement} */
11913
+ (greatGrandparent.parentElement),
11914
+ '.buffersource-typedArrays-init'
11915
+ )).$checkTypedArrayByteLength(e);
11916
+ }
11917
+ }
11918
+ }]
11919
+ ]],
11920
+ ' ',
11921
+ ['label', [
11922
+ 'Max byte length ',
11923
+ ['input', {
11924
+ class: 'maxByteLength',
11925
+ type: 'number', step: '1', size: '4', pattern: '\\d+',
11926
+ min: 0,
11927
+ $on: {
11928
+ change (e) {
11929
+ const that = /** @type {HTMLInputElement} */ (this);
11930
+ const byteLength = /** @type {HTMLInputElement} */ ($e(
11931
+ /** @type {HTMLElement} */ (
11932
+ that.parentElement?.parentElement
11933
+ ), '.byteLength'
11934
+ ));
11935
+ const val = that.value;
11936
+ if (
11937
+ Number.parseInt(val) < Number.parseInt(byteLength.value)
11938
+ ) {
11939
+ // byteLength.value = val;
11940
+ that.setCustomValidity(
11941
+ 'The max value cannot be less than the byte length'
11942
+ );
11943
+ e.stopPropagation();
11944
+ } else {
11945
+ that.setCustomValidity('');
11946
+ }
11947
+ that.reportValidity();
11948
+ }
11949
+ }
11950
+ }]
11951
+ ]]
11952
+ ]],
11953
+ ['fieldset', [
11954
+ ['legend', ['DataView']],
11955
+ ['label', [
11956
+ 'Byte length ',
11957
+ ['input', {
11958
+ class: 'dataViewByteLength',
11959
+ type: 'number', step: '1', size: '4', pattern: '\\d+',
11960
+ min: 0,
11961
+ $custom: {
11962
+ /**
11963
+ * @typedef {(e: Event) => void} CheckDataViewByteLength
11964
+ */
11965
+
11966
+ /** @type {CheckDataViewByteLength} */
11967
+ $checkDataViewByteLength (e) {
11968
+ const that = /** @type {HTMLInputElement} */ (
11969
+ this
11970
+ );
11971
+ const greatGrandparent = /** @type {HTMLElement} */
11972
+ (that.parentElement?.parentElement?.parentElement);
11973
+
11974
+ const byteOffset = Number.parseInt(
11975
+ /** @type {HTMLInputElement} */ ($e(
11976
+ greatGrandparent,
11977
+ '.dataViewByteOffset'
11978
+ )).value
11979
+ ) || 0;
11980
+
11981
+ const bufferByteLengthVal = /** @type {HTMLInputElement} */ (
11982
+ $e(
11983
+ greatGrandparent,
11984
+ '.byteLength'
11985
+ )).value;
11986
+ const bufferByteLength = bufferByteLengthVal
11987
+ ? Number.parseInt(
11988
+ bufferByteLengthVal
11989
+ )
11990
+ : 0;
11991
+
11992
+ const byteLength = that.value
11993
+ ? Number.parseInt(
11994
+ that.value
11995
+ )
11996
+ : bufferByteLength;
11997
+
11998
+ if (byteOffset + byteLength > bufferByteLength) {
11999
+ that.setCustomValidity(
12000
+ 'The DataView byte length and offset exceed ' +
12001
+ 'the buffer\'s byte length'
12002
+ );
12003
+ e.stopPropagation();
12004
+ } else {
12005
+ that.setCustomValidity('');
12006
+ }
12007
+ that.reportValidity();
12008
+ }
12009
+ },
12010
+ $on: {
12011
+ change (e) {
12012
+ /**
12013
+ * @type {HTMLInputElement & {
12014
+ * $checkDataViewByteLength: CheckDataViewByteLength
12015
+ * }}
12016
+ */ (
12017
+ this
12018
+ ).$checkDataViewByteLength(e);
12019
+ }
12020
+ }
12021
+ }]
12022
+ ]],
12023
+ ' ',
12024
+ ['label', [
12025
+ 'Byte offset ',
12026
+ ['input', {
12027
+ class: 'dataViewByteOffset',
12028
+ type: 'number', step: '1', size: '4', pattern: '\\d+',
12029
+ min: 0,
12030
+ $on: {
12031
+ change (e) {
12032
+ const that = /** @type {HTMLInputElement} */ (
12033
+ this
12034
+ );
12035
+ const greatGrandparent = /** @type {HTMLElement} */
12036
+ (that.parentElement?.parentElement?.parentElement);
12037
+
12038
+ /**
12039
+ * @type {HTMLInputElement & {
12040
+ * $checkDataViewByteLength: CheckDataViewByteLength
12041
+ * }}
12042
+ */ ($e(
12043
+ greatGrandparent,
12044
+ '.dataViewByteLength'
12045
+ )).$checkDataViewByteLength(e);
12046
+ }
12047
+ }
12048
+ }]
12049
+ ]]
12050
+ ]],
12051
+ ['fieldset', [
12052
+ ['legend', ['Typed array']],
12053
+ ['label', [
12054
+ 'Byte offset ',
12055
+ ['input', {
12056
+ class: 'typedArrayByteOffset',
12057
+ type: 'number', step: '1', size: '4', pattern: '\\d+',
12058
+ min: 0,
12059
+ max: (2 ** 53) - 1,
12060
+ $custom: {
12061
+ /**
12062
+ * @typedef {(e: Event) => void} CheckByteOffsetMultiple
12063
+ */
12064
+
12065
+ /** @type {CheckByteOffsetMultiple} */
12066
+ $checkByteOffsetMultiple (e) {
12067
+ const that = /** @type {HTMLInputElement} */ (this);
12068
+ const ancestor = /** @type {HTMLElement} */ (
12069
+ that.
12070
+ parentElement?.parentElement?.parentElement?.parentElement
12071
+ );
12072
+
12073
+ const {value} = /** @type {HTMLSelectElement} */ (
12074
+ $e(ancestor, '.buffersource-typedArrays-init')
12075
+ );
12076
+
12077
+ const TypedArray = getTypedArray(
12078
+ /** @type {TypedArray} */ (value)
12079
+ );
12080
+ if (
12081
+ Number.parseInt(that.value) % TypedArray.BYTES_PER_ELEMENT
12082
+ ) {
12083
+ that.setCustomValidity(
12084
+ 'Byte offset must be a multiple of the typed ' +
12085
+ `array's bytes-per-element size (${
12086
+ TypedArray.BYTES_PER_ELEMENT
12087
+ })`
12088
+ );
12089
+ e.stopPropagation();
12090
+ } else {
12091
+ that.setCustomValidity('');
12092
+ }
12093
+ that.reportValidity();
12094
+ }
12095
+ },
12096
+ $on: {
12097
+ change (e) {
12098
+ const that = /** @type {HTMLInputElement} */ (this);
12099
+ const ancestor = /** @type {HTMLElement} */ (
12100
+ that.
12101
+ parentElement?.parentElement?.parentElement?.parentElement
12102
+ );
12103
+ const typedArrayLength =
12104
+ /**
12105
+ * @type {HTMLInputElement & {
12106
+ * $checkBufferBounds: CheckBufferBounds
12107
+ * }}
12108
+ */ (
12109
+ $e(ancestor, '.typedArrayLength')
12110
+ );
12111
+ if (!typedArrayLength.$checkBufferBounds(e)) {
12112
+ return;
12113
+ }
12114
+ /**
12115
+ * @type {HTMLInputElement & {
12116
+ * $checkByteOffsetMultiple: CheckByteOffsetMultiple
12117
+ * }}
12118
+ */ (this).$checkByteOffsetMultiple(e);
12119
+ }
12120
+ }
12121
+ }]
12122
+ ]]
12123
+ // ' ',
12124
+ // ['label', [
12125
+ // 'Length ',
12126
+ // ['input', {
12127
+ // class: 'typedArrayLength',
12128
+ // type: 'number', step: '1', size: '4', pattern: '\\d+',
12129
+ // min: 0
12130
+ // }]
12131
+ // ]]
12132
+ ]]
12133
+ ]],
12134
+ ['fieldset', [
12135
+ ['legend', ['Typed Array initialization (optional)']],
12136
+ ['select', {
12137
+ class: 'buffersource-typedArrays-init',
12138
+ 'aria-label': 'Typed Arrays',
12139
+ $custom: {
12140
+ /**
12141
+ * @callback SetMinsAndMaxes
12142
+ * @param {TypedArray} typedArray
12143
+ * @returns {void}
12144
+ */
12145
+
12146
+ /** @type {SetMinsAndMaxes} */
12147
+ $setMinsAndMaxes (typedArray) {
12148
+ const {min, max} = getMinMaxForTypedArray(typedArray);
12149
+
12150
+ /** @type {HTMLInputElement[]} */ (
12151
+ $$e(/** @type {HTMLElement} */ (
12152
+ /** @type {HTMLSelectElement} */ (this).parentElement
12153
+ ), '.typedArrayValue')
12154
+ ).forEach((typedArrayValue) => {
12155
+ typedArrayValue.className =
12156
+ 'typedArrayValue typedArray-' + typedArray;
12157
+ typedArrayValue.min = String(min);
12158
+ typedArrayValue.max = String(max);
12159
+ });
12160
+ },
12161
+
12162
+ /**
12163
+ * @typedef {(e: Event) => void} CheckTypedArrayByteLength
12164
+ */
12165
+
12166
+ /** @type {CheckTypedArrayByteLength} */
12167
+ $checkTypedArrayByteLength (e) {
12168
+ const that = /** @type {HTMLSelectElement} */ (this);
12169
+ const TypedArray = getTypedArray(
12170
+ /** @type {TypedArray} */ (that.value)
12171
+ );
12172
+
12173
+ const byteLength = /** @type {HTMLInputElement} */ ($e(
12174
+ /** @type {HTMLElement} */
12175
+ (that.parentElement?.parentElement),
12176
+ '.byteLength'
12177
+ ));
12178
+ const arrayBufferLength = byteLength.value
12179
+ ? Number.parseInt(
12180
+ byteLength.value
12181
+ )
12182
+ : 0;
12183
+ if (arrayBufferLength % TypedArray.BYTES_PER_ELEMENT) {
12184
+ byteLength.setCustomValidity(
12185
+ 'Array buffer must be a multiple of the typed array\'s ' +
12186
+ `bytes-per-element size (${TypedArray.BYTES_PER_ELEMENT})`
12187
+ );
12188
+ e.stopPropagation();
12189
+ } else {
12190
+ byteLength.setCustomValidity('');
12191
+ }
12192
+ byteLength.reportValidity();
12193
+ }
12194
+ },
12195
+ $on: {
12196
+ change (e) {
12197
+ const that =
12198
+ /**
12199
+ * @type {HTMLSelectElement & {
12200
+ * $setMinsAndMaxes: SetMinsAndMaxes,
12201
+ * $checkTypedArrayByteLength: CheckTypedArrayByteLength
12202
+ * }}
12203
+ */ (
12204
+ this
12205
+ );
12206
+
12207
+ const ancestor = /** @type {HTMLElement} */ (
12208
+ that.
12209
+ parentElement?.parentElement?.parentElement
12210
+ );
12211
+
12212
+ // Update to reflect current state changes if later revealing
12213
+ /** @type {HTMLSelectElement} */ ($e(
12214
+ /** @type {HTMLElement} */
12215
+ (this.parentElement?.parentElement),
12216
+ '.buffersource-typedArrays'
12217
+ )).value = that.value;
12218
+
12219
+ const typedArrayLength =
12220
+ /**
12221
+ * @type {HTMLInputElement & {
12222
+ * $checkBufferBounds: CheckBufferBounds
12223
+ * }}
12224
+ */ (
12225
+ $e(ancestor, '.typedArrayLength')
12226
+ );
12227
+ if (!typedArrayLength.$checkBufferBounds(e)) {
12228
+ return;
12229
+ }
12230
+
12231
+ that.$checkTypedArrayByteLength(e);
12232
+
12233
+ that.$setMinsAndMaxes(/** @type {TypedArray} */ (that.value));
12234
+
12235
+ const typedArrayByteOffset = $e(
12236
+ /** @type {HTMLElement} */
12237
+ (that?.parentElement?.parentElement),
12238
+ '.typedArrayByteOffset'
12239
+ );
12240
+ /**
12241
+ * @type {HTMLInputElement & {
12242
+ * $checkByteOffsetMultiple: CheckByteOffsetMultiple
12243
+ * }}
12244
+ */ (typedArrayByteOffset).$checkByteOffsetMultiple(e);
12245
+
12246
+ /**
12247
+ * @type {HTMLFieldSetElement & {
12248
+ * $buildInstances: BuildInstances
12249
+ * }}
12250
+ */ ($e(
12251
+ /** @type {HTMLElement} */
12252
+ (this.parentElement?.parentElement),
12253
+ '.returnType'
12254
+ )).$buildInstances();
12255
+ }
12256
+ }
12257
+ }, typedArrays.map((typedArray) => {
12258
+ return ['option', [typedArray]];
12259
+ })],
12260
+ ' ',
12261
+ ['label', [
12262
+ 'Array length: ',
12263
+ ['input', {
12264
+ class: 'typedArrayLength',
12265
+ type: 'number', step: '1', size: '4', pattern: '\\d+',
12266
+ min: 0,
12267
+ $custom: {
12268
+ /**
12269
+ * When creating a view from a buffer, the bounds are outside
12270
+ * the buffer. In other words, `byteOffset + length *
12271
+ * TypedArray.BYTES_PER_ELEMENT > buffer.byteLength`.
12272
+ * @typedef {(e: Event) => boolean} CheckBufferBounds
12273
+ */
12274
+
12275
+ /** @type {CheckBufferBounds} */
12276
+ $checkBufferBounds (e) {
12277
+ const that = /** @type {HTMLInputElement} */ (this);
12278
+
12279
+ const ancestor = /** @type {HTMLElement} */ (
12280
+ that.parentElement?.parentElement?.parentElement
12281
+ );
12282
+ const bufferByteLengthVal = /** @type {HTMLInputElement} */ (
12283
+ $e(
12284
+ ancestor,
12285
+ '.byteLength'
12286
+ )).value;
12287
+ const bufferByteLength = bufferByteLengthVal
12288
+ ? Number.parseInt(
12289
+ bufferByteLengthVal
12290
+ )
12291
+ : 0;
12292
+
12293
+ const length = that.value
12294
+ ? Number.parseInt(that.value)
12295
+ : bufferByteLength;
12296
+
12297
+ const {value} = /** @type {HTMLSelectElement} */ (
12298
+ $e(ancestor, '.buffersource-typedArrays-init')
12299
+ );
12300
+
12301
+ const TypedArray = getTypedArray(
12302
+ /** @type {TypedArray} */ (value)
12303
+ );
12304
+
12305
+ const typedArrayByteOffsetVal =
12306
+ /** @type {HTMLInputElement} */ ($e(
12307
+ ancestor,
12308
+ '.typedArrayByteOffset'
12309
+ )).value;
12310
+ const typedArrayByteOffset = typedArrayByteOffsetVal
12311
+ ? Number.parseInt(typedArrayByteOffsetVal)
12312
+ : 0;
12313
+
12314
+ console.log('1111', typedArrayByteOffset,
12315
+ length, TypedArray.BYTES_PER_ELEMENT,
12316
+ bufferByteLength);
12317
+
12318
+ if (
12319
+ (typedArrayByteOffset +
12320
+ (length * TypedArray.BYTES_PER_ELEMENT)) >
12321
+ bufferByteLength
12322
+ ) {
12323
+ that.setCustomValidity(
12324
+ 'The byte offset and the length times bytes per element ' +
12325
+ 'is greater than the buffer length'
12326
+ );
12327
+ e.stopPropagation();
12328
+ that.reportValidity();
12329
+ return false;
12330
+ }
12331
+
12332
+ that.setCustomValidity('');
12333
+ that.reportValidity();
12334
+ return true;
12335
+ },
12336
+
12337
+ /**
12338
+ * @typedef {() => void} BuildTypedArray
12339
+ */
12340
+
12341
+ /** @type {BuildTypedArray} */
12342
+ $buildTypedArray () {
12343
+ const that = /** @type {HTMLInputElement} */ (this);
12344
+ const length = Number.parseInt(that.value);
12345
+ const grandparent = /** @type {HTMLElement} */ (
12346
+ that.parentElement?.parentElement
12347
+ );
12348
+
12349
+ const ancestor = /** @type {HTMLElement} */ (
12350
+ that.parentElement?.parentElement?.parentElement
12351
+ );
12352
+ const bufferByteLength =
12353
+ /**
12354
+ * @type {HTMLInputElement & {
12355
+ * $typedArray: TypedArrayInstance
12356
+ * }}
12357
+ */ ($e(
12358
+ ancestor,
12359
+ '.byteLength'
12360
+ ));
12361
+
12362
+ const typedArrayArea = /** @type {HTMLElement} */ ($e(
12363
+ grandparent, '.typedArrayArea'
12364
+ ));
12365
+
12366
+ typedArrayArea.addEventListener('change', (e) => {
12367
+ const input = /** @type {HTMLInputElement} */ (e.target);
12368
+ bufferByteLength.$typedArray.set([
12369
+ // @ts-expect-error Ok
12370
+ input.dataset.bigint === 'true'
12371
+ ? BigInt(input.value)
12372
+ : Number(input.value)
12373
+ ], Number.parseInt(
12374
+ /** @type {string} */ (input.dataset.key)
12375
+ ));
12376
+ });
12377
+ const {value} = /** @type {HTMLSelectElement} */ (
12378
+ $e(grandparent, '.buffersource-typedArrays-init')
12379
+ );
12380
+ const {min, max} = getMinMaxForTypedArray(
12381
+ /** @type {TypedArray} */ (value)
12382
+ );
12383
+
12384
+ typedArrayArea.textContent = '';
12385
+ typedArrayArea.append(
12386
+ ...Array.from({length}, (_v, key) => {
12387
+ return jml('label', [
12388
+ key,
12389
+ ' ',
12390
+ ['input', {
12391
+ class: 'typedArrayValue typedArray-' + value,
12392
+ dataset: {
12393
+ key, bigint: String(value.startsWith('BigInt'))
12394
+ },
12395
+ type: 'number', step: '1',
12396
+ pattern: value.startsWith('Float')
12397
+ ? '\\d+(?:\\.\\d+)?'
12398
+ : '\\d+',
12399
+ value: bufferByteLength.$typedArray[key]
12400
+ ? String(bufferByteLength.$typedArray[key])
12401
+ : '0',
12402
+ min, max
12403
+ }],
12404
+ ' '
12405
+ // !key || key % 9 ? ' ' : ['br']
12406
+ ]);
12407
+ })
12408
+ );
12409
+ }
12410
+ },
12411
+ $on: {
12412
+ change (e) {
12413
+ const that =
12414
+ /**
12415
+ * @type {HTMLInputElement & {
12416
+ * $checkBufferBounds: CheckBufferBounds,
12417
+ * $buildTypedArray: BuildTypedArray
12418
+ * }}
12419
+ */ (
12420
+ this
12421
+ );
12422
+ const grandparent = /** @type {HTMLElement} */ (
12423
+ this.parentElement?.parentElement
12424
+ );
12425
+
12426
+ if (!that.$checkBufferBounds(e)) {
12427
+ return;
12428
+ }
12429
+
12430
+ const {value} = /** @type {HTMLSelectElement} */ (
12431
+ $e(grandparent, '.buffersource-typedArrays-init')
12432
+ );
12433
+
12434
+ const length = Number.parseInt(that.value);
12435
+ try {
12436
+ const TypedArray = getTypedArray(
12437
+ /** @type {TypedArray} */ (value)
12438
+ );
12439
+ // eslint-disable-next-line no-new -- Testing
12440
+ new TypedArray(length);
12441
+ } catch (err) {
12442
+ that.setCustomValidity('Typed Array length is too long');
12443
+ e.stopPropagation();
12444
+ that.reportValidity();
12445
+ return;
12446
+ }
12447
+ that.setCustomValidity('');
12448
+ that.reportValidity();
12449
+
12450
+ /**
12451
+ * @type {HTMLFieldSetElement & {
12452
+ * $buildInstances: BuildInstances
12453
+ * }}
12454
+ */ ($e(
12455
+ /** @type {HTMLElement} */
12456
+ (this.parentElement?.parentElement?.parentElement),
12457
+ '.returnType'
12458
+ )).$buildInstances();
12459
+
12460
+ that.$buildTypedArray();
12461
+ }
12462
+ }
12463
+ }],
12464
+ ['div', {
12465
+ class: 'typedArrayArea'
12466
+ }]
12467
+ ]]
12468
+ ]],
12469
+ ['fieldset', [
12470
+ ['legend', ['DataView initialization (optional)']],
12471
+ ['select', {
12472
+ class: 'dataViewMethod',
12473
+ 'aria-label': 'Data View methods',
12474
+ $on: {
12475
+ change () {
12476
+ const dataViewArea = /** @type {HTMLDivElement} */ ($e(
12477
+ /** @type {HTMLElement} */ (this.parentElement), '.dataViewArea'
12478
+ ));
12479
+
12480
+ const val = /** @type {HTMLSelectElement} */ (this).value;
12481
+ const typedArray = /** @type {TypedArray} */ (
12482
+ val.slice(3) + 'Array'
12483
+ );
12484
+
12485
+ dataViewArea.textContent = '';
12486
+ dataViewArea.append(
12487
+ jml(
12488
+ 'label', [
12489
+ 'Byte offset ',
12490
+ ['input', {
12491
+ type: 'number',
12492
+ class: 'dataViewSetByteOffset',
12493
+ step: '1', size: '4', pattern: '\\d+'
12494
+ }]
12495
+ ]
12496
+ ),
12497
+ ' ',
12498
+ jml(
12499
+ 'label', [
12500
+ 'Value ',
12501
+ ['input', {
12502
+ type: 'number',
12503
+ step: '1', size: '4', pattern: '\\d+',
12504
+ class: 'typedArrayValue typedArray-' + typedArray,
12505
+ ...getMinMaxForTypedArray(typedArray)
12506
+ }]
12507
+ ]
12508
+ ),
12509
+ val === 'setInt8' || val === 'setUint8'
12510
+ ? ''
12511
+ : jml('label', [
12512
+ ['input', {
12513
+ class: 'littleEndian',
12514
+ type: 'checkbox'
12515
+ }],
12516
+ 'Little endian'
12517
+ ]),
12518
+ ' ',
12519
+ jml('button', {
12520
+ $on: {
12521
+ click (e) {
12522
+ e.preventDefault();
12523
+ const ancestor = /** @type {HTMLElement} */ (
12524
+ this.parentElement
12525
+ );
12526
+ const dataViewMethod =
12527
+ /** @type {dataViewMethods[number]} */ (
12528
+ /** @type {HTMLSelectElement} */ (
12529
+ ancestor.previousElementSibling
12530
+ )?.value
12531
+ );
12532
+
12533
+ const dataViewSetByteOffset =
12534
+ Number.parseInt(/** @type {HTMLInputElement} */ ($e(
12535
+ ancestor,
12536
+ '.dataViewSetByteOffset'
12537
+ )).value);
12538
+ const typedArrayValue =
12539
+ /** @type {HTMLInputElement} */ ($e(
12540
+ ancestor,
12541
+ '.typedArrayValue'
12542
+ )).value;
12543
+ const littleEndian =
12544
+ /** @type {HTMLInputElement|null} */ ($e(
12545
+ ancestor,
12546
+ '.littleEndian'
12547
+ ))?.checked;
12548
+
12549
+ const byteLength =
12550
+ /**
12551
+ * @type {HTMLInputElement & {
12552
+ * $dataView: DataView,
12553
+ * }}
12554
+ */ (
12555
+ $e(
12556
+ /** @type {HTMLElement} */
12557
+ (ancestor?.parentElement?.parentElement),
12558
+ '.byteLength'
12559
+ )
12560
+ );
12561
+
12562
+ if (
12563
+ dataViewMethod === 'setBigInt64' ||
12564
+ dataViewMethod === 'setBigUint64'
12565
+ ) {
12566
+ byteLength.$dataView[dataViewMethod](
12567
+ dataViewSetByteOffset,
12568
+ BigInt(typedArrayValue),
12569
+ littleEndian
12570
+ );
12571
+ } else {
12572
+ byteLength.$dataView[dataViewMethod](
12573
+ dataViewSetByteOffset,
12574
+ Number(typedArrayValue),
12575
+ littleEndian
12576
+ );
12577
+ }
12578
+
12579
+ const typedArrayLength =
12580
+ /**
12581
+ * @type {HTMLInputElement & {
12582
+ * $buildTypedArray: BuildTypedArray
12583
+ * }}
12584
+ */ ($e(
12585
+ /** @type {HTMLElement} */
12586
+ (ancestor.parentElement?.parentElement),
12587
+ '.typedArrayLength'
12588
+ ));
12589
+ typedArrayLength.$buildTypedArray();
12590
+ }
12591
+ }
12592
+ }, ['Set'])
12593
+ );
12594
+ }
12595
+ }
12596
+ }, [
12597
+ ['option', {value: ''}, ['(Select a data view method)']],
12598
+ ...dataViewMethods.map((dataViewMethod) => {
12599
+ return /** @type {import('jamilih').JamilihArray} */ (
12600
+ ['option', [dataViewMethod]]
12601
+ );
12602
+ })
12603
+ ]],
12604
+ ' ',
12605
+ ['div', {class: 'dataViewArea'}]
12606
+ ]]
12607
+ ]));
12608
+
12609
+ if (this.setValue && value) {
12610
+ this.setValue({root: div, value});
12611
+ } else {
12612
+ const byteLength =
12613
+ /**
12614
+ * @type {HTMLInputElement & {
12615
+ * $value: BufferSource
12616
+ * }}
12617
+ */ ($e(div, '.byteLength'));
12618
+ byteLength.$value = new ArrayBuffer(0);
12619
+ }
12620
+
12621
+ return [div];
12622
+ }
12623
+ };
12624
+
11202
12625
  /**
11203
12626
  * @type {import('../types.js').TypeObject}
11204
12627
  */
@@ -11610,7 +13033,7 @@ const getPropertyValueFromLegend = (legend) => {
11610
13033
  * "objectReference"|"array"|"object"|"date"|"userObject"|"undef"|
11611
13034
  * "SpecialRealNumber"|"SpecialNumber"|"regexp"|"BooleanObject"|
11612
13035
  * "NumberObject"|"StringObject"|"map"|"set"|"file"|"filelist"|"blobHTML"|
11613
- * "arraybuffer"|"arraybufferview"|"dataview"|"imagedata"|"imagebitmap"|
13036
+ * "buffersource"|"dataview"|"imagedata"|"imagebitmap"|
11614
13037
  * "int8array"|"uint8array"|"uint8clampedarray"|"int16array"|"uint16array"|
11615
13038
  * "int32array"|"uint32array"|"float32array"|"float64array"|"ValidDate"|
11616
13039
  * "arrayNonindexKeys"|"error"|"errors"|"blob"|"domexception"|"domrect"|
@@ -11688,12 +13111,7 @@ class Types {
11688
13111
 
11689
13112
  resurrectable: noneditableType,
11690
13113
 
11691
- arraybuffer: {
11692
- option: ['ArrayBuffer']
11693
- },
11694
- arraybufferview: {
11695
- option: ['ArrayBufferView']
11696
- },
13114
+ buffersource: buffersourceType,
11697
13115
  dataview: {
11698
13116
  option: ['DataView']
11699
13117
  },