@shgysk8zer0/polyfills 0.0.2

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +2 -0
  4. package/abort.js +194 -0
  5. package/all.js +30 -0
  6. package/animation.js +33 -0
  7. package/aom.js +43 -0
  8. package/appBadge.js +27 -0
  9. package/array.js +258 -0
  10. package/assets/CookieStore.js +230 -0
  11. package/assets/Lock.js +31 -0
  12. package/assets/LockManager.js +278 -0
  13. package/assets/Sanitizer.js +59 -0
  14. package/assets/SanitizerConfig.js +348 -0
  15. package/assets/SanitizerConfigBase.js +18 -0
  16. package/assets/SanitizerConfigEdge.js +335 -0
  17. package/assets/SanitizerConfigW3C.js +766 -0
  18. package/assets/Scheduler.js +124 -0
  19. package/assets/TextDecoder.js +83 -0
  20. package/assets/TextEncoder.js +41 -0
  21. package/assets/TrustedTypes.js +595 -0
  22. package/assets/attributes.js +15 -0
  23. package/assets/csp.js +29 -0
  24. package/assets/error.js +8 -0
  25. package/assets/sanitizerUtils.js +270 -0
  26. package/assets/trust.js +190 -0
  27. package/assets/utility.js +101 -0
  28. package/cookieStore.js +2 -0
  29. package/crypto.js +8 -0
  30. package/dialog.js +63 -0
  31. package/element.js +171 -0
  32. package/elementInternals.js +616 -0
  33. package/errors.js +21 -0
  34. package/function.js +31 -0
  35. package/globalThis.js +36 -0
  36. package/iterator.js +197 -0
  37. package/legacy/array.js +15 -0
  38. package/legacy/element.js +140 -0
  39. package/legacy/map.js +168 -0
  40. package/legacy/object.js +42 -0
  41. package/legacy.js +9 -0
  42. package/locks.js +33 -0
  43. package/map.js +32 -0
  44. package/match-media.js +58 -0
  45. package/math.js +69 -0
  46. package/navigator.js +55 -0
  47. package/number.js +14 -0
  48. package/package.json +52 -0
  49. package/performance.js +36 -0
  50. package/promise.js +70 -0
  51. package/sanitizer.js +3 -0
  52. package/scheduler.js +5 -0
  53. package/secure-context.js +31 -0
  54. package/set.js +73 -0
  55. package/share.js +17 -0
  56. package/symbols.js +9 -0
  57. package/textEncoder.js +16 -0
  58. package/trustedTypes.js +3 -0
  59. package/weakMap.js +28 -0
  60. package/window.js +85 -0
@@ -0,0 +1,616 @@
1
+ /**
2
+ * @copyright 2023 Chris Zuber <admin@kernvalley.us>
3
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals
4
+ * @see https://caniuse.com/mdn-api_formdataevent
5
+ * @see https://caniuse.com/mdn-api_elementinternals
6
+ * @todo: Figure out how to cleanup MutationObserver for removed inputs
7
+ * @todo: Can I add a MutationObserver to automatically set/unset forms,
8
+ * even in `ShadowRoot`s?
9
+ *
10
+ * This polyfill needs a bit of extra work from the custom element to work.
11
+ * Check if `internals._polyfilled` to see if extra steps are necessary:
12
+ * - Call `internals._associateForm(form, this)` in `connectedCallback()`
13
+ * - Call again with `(null, this)` in `disconnectedCallback()` to disassociate
14
+ *
15
+ * Additionally, if `internals.states._polyfilled`
16
+ * - Use `._state--*` in addition to `:--*` to query element internals states
17
+ * - This includes `:disabled` -> `._state--disabled` & `:invalid` -> `._state--invalid`
18
+ */
19
+ import { aria } from './aom.js';
20
+
21
+ const symbols = {
22
+ key: Symbol('key'),
23
+ internals: Symbol('element-internals'),
24
+ form: Symbol('form'),
25
+ fieldset: Symbol('fieldset'),
26
+ element: Symbol('element'),
27
+ validity: Symbol('validity'),
28
+ validationMessage: Symbol('validation-message'),
29
+ value: Symbol('value'),
30
+ state: Symbol('state'),
31
+ formController: Symbol('form-controller'),
32
+ anchor: Symbol('anchor'),
33
+ customInputs: Symbol('custom-inputs'),
34
+ };
35
+
36
+ function shimAria(prototype) {
37
+ const enumerable = true;
38
+ const configurable = true;
39
+ const props = Object.fromEntries(Object.keys(aria).map(prop => [prop, {
40
+ get: function() {
41
+ return this[symbols.element][prop];
42
+ },
43
+ set: function(val) {
44
+ this[symbols.element][prop] = val;
45
+ },
46
+ enumerable, configurable,
47
+ }]));
48
+
49
+ Object.defineProperties(prototype, props);
50
+ }
51
+
52
+ if (! (HTMLElement.prototype.attachInternals instanceof Function) && 'FormDataEvent' in globalThis) {
53
+ const validationObject = {
54
+ valueMissing: false, typeMismatch: false, patternMismatch: false, tooLong: false,
55
+ tooShort: false, rangeUnderflow: false, rangeOverflow: false, stepMismatch: false,
56
+ badInput: false, customError: false, valid: true,
57
+ };
58
+
59
+ const hasDisabledFieldset = component => component.hasOwnProperty(symbols.fieldset)
60
+ && component[symbols.fieldset] instanceof HTMLFieldSetElement
61
+ && component[symbols.fieldset].disabled;
62
+
63
+ const isFormAssociated = (component) => {
64
+ return component instanceof HTMLElement
65
+ && component.tagName.includes('-')
66
+ && customElements.get(component.tagName.toLowerCase()).formAssociated;
67
+ };
68
+
69
+ const getFormDataHandler = (component, internals) => {
70
+ return function(event) {
71
+ if (! event.target.reportValidity()) {
72
+ event.preventDefault();
73
+ event.stopImmediatePropagation();
74
+ event.stopPropagation();
75
+ } else if (internals.willValidate && event.formData instanceof FormData) {
76
+ const value = internals[symbols.value];
77
+
78
+ if (value instanceof FormData) {
79
+ value.entries().forEach(([k, v]) => event.formData.set(k, v));
80
+ } else if (component.hasAttribute('name')) {
81
+ event.formData.set(component.getAttribute('name'), internals[symbols.value]);
82
+ }
83
+ }
84
+ };
85
+ };
86
+
87
+ const css = (el, rules) => {
88
+ Object.entries(rules).forEach(([k, v]) => el.style.setProperty(k, v));
89
+ };
90
+
91
+ const findAssociatedForm = (component) => {
92
+ if (component.hasAttribute('form')) {
93
+ return document.forms[component.getAttribute('form')] || component.closest('form');
94
+ } else {
95
+ return component.closest('form');
96
+ }
97
+ };
98
+
99
+ // To be used in/after `connectedCallback`
100
+ const associateForm = (form, internals, component) => {
101
+ if (! (form instanceof HTMLFormElement)) {
102
+ if (internals[symbols.formController] instanceof AbortController) {
103
+ internals[symbols.formController].abort();
104
+ }
105
+
106
+ internals[symbols.form] = null;
107
+ internals[symbols.formController] = null;
108
+
109
+ if (component.hasOwnProperty(symbols.fieldset)) {
110
+ const fieldset = component[symbols.fieldset];
111
+
112
+ if (fieldset.hasOwnProperty(symbols.customInputs)) {
113
+ fieldset[symbols.customInputs].delete(component);
114
+
115
+ if (fieldset[symbols.customInputs.size] === 0) {
116
+ delete fieldset[symbols.customInputs];
117
+ }
118
+ }
119
+ component[symbols.fieldset] = null;
120
+ }
121
+ } else if (! (component instanceof HTMLElement && component.tagName.includes('-'))) {
122
+ throw new TypeError('Not a custom element');
123
+ } else if (! (internals instanceof ElementInternals || internals instanceof globalThis.ElementInternals)) {
124
+ throw new TypeError('Invalid ElementInternals');
125
+ } else if (! isFormAssociated(component)) {
126
+ throw new TypeError(`${component.tagName} is not form associated.`);
127
+ } else if (! (component.formAssociatedCallback instanceof Function)) {
128
+ throw new TypeError(`${component.tagName} is missing a formAssociatedCallback method.`);
129
+ } else {
130
+ const controller = new AbortController();
131
+ const fieldset = component.closest('fieldset');
132
+
133
+ if (fieldset instanceof Element) {
134
+ component[symbols.fieldset] = fieldset;
135
+ if (! fieldset.hasOwnProperty(symbols.customInputs)) {
136
+ fieldset[symbols.customInputs] = new Set();
137
+ }
138
+
139
+ fieldset[symbols.customInputs].add(component);
140
+ observer.observe(fieldset, observerOpts);
141
+ }
142
+
143
+ internals[symbols.form] = form;
144
+ internals[symbols.formController] = controller;
145
+
146
+ const { checkValidity, reportValidity } = form;
147
+
148
+ form.reportValidity = function() {
149
+ if (! reportValidity.call(this)) {
150
+ return false;
151
+ } else {
152
+ return internals.reportValidity();
153
+ }
154
+ };
155
+
156
+ form.checkValidity = function() {
157
+ if (! checkValidity.call(this)) {
158
+ return false;
159
+ } else {
160
+ return internals.checkValidity();
161
+ }
162
+ };
163
+
164
+ controller.signal.addEventListener('abort', () => {
165
+ form.reportValidity = reportValidity;
166
+ form.checkValidity = checkValidity;
167
+ }, { once: true });
168
+
169
+ form.addEventListener('formdata', getFormDataHandler(component, internals), { signal: controller.signal });
170
+ form.addEventListener('submit', event => {
171
+ if (! event.target.reportValidity()) {
172
+ event.preventDefault();
173
+ event.stopImmediatePropagation();
174
+ event.stopPropagation();
175
+ }
176
+ }, { signal: controller.signal });
177
+
178
+ if (component.formResetCallback instanceof Function) {
179
+ form.addEventListener('reset', () => component.formResetCallback(), { signal: controller.signal });
180
+ }
181
+ }
182
+ };
183
+
184
+ const observer = new MutationObserver((mutations) => {
185
+ mutations.forEach(({ target, type, attributeName }) => {
186
+ if (type === 'attributes' && attributeName === 'disabled') {
187
+ const disabled = target.hasAttribute('disabled');
188
+
189
+ /**
190
+ * Check that target is a valid candiate and not a child of a
191
+ * `<fieldset disabled>`, unless they are both being toggled
192
+ * together to the same value.
193
+ */
194
+ if (
195
+ isFormAssociated(target)
196
+ && target.hasOwnProperty(symbols.internals)
197
+ && target[symbols.internals].states.has('--disabled') !== disabled
198
+ && (
199
+ mutations.length === 1
200
+ // target is not a descendant of a `<fieldset disabled>`
201
+ ? ! hasDisabledFieldset(target)
202
+ : (
203
+ // target & `<fieldset>` are being enabled/disabled together
204
+ target.hasAttribute('disabled') === hasDisabledFieldset(target)
205
+ && mutations.some((m) =>
206
+ m.target.isSameNode(target[symbols.fieldset])
207
+ )
208
+ )
209
+ )
210
+ ) {
211
+ const internals = target[symbols.internals];
212
+
213
+ if (disabled) {
214
+ internals.states.add('--disabled');
215
+ } else {
216
+ internals.states.delete('--disabled');
217
+ }
218
+
219
+ if (target.formDisabledCallback instanceof Function) {
220
+ target.formDisabledCallback(disabled);
221
+ }
222
+ } else if (
223
+ target.tagName === 'FIELDSET'
224
+ && target.hasOwnProperty(symbols.customInputs)
225
+ && (
226
+ mutations.length === 1
227
+ || ! mutations.some(m => target[symbols.customInputs].has(m.target))
228
+ )
229
+ ) {
230
+ target[symbols.customInputs].forEach(el => {
231
+ if (el.isConnected && el.hasOwnProperty(symbols.internals)) {
232
+ // Do not toggle disabled on elements that are `disabled`
233
+ if (! el.hasAttribute('disabled')) {
234
+ if (disabled) {
235
+ el[symbols.internals].states.add('--disabled');
236
+ } else {
237
+ el[symbols.internals].states.delete('--disabled');
238
+ }
239
+
240
+ if (el.formDisabledCallback instanceof Function) {
241
+ el.formDisabledCallback(disabled);
242
+ }
243
+ }
244
+ } else {
245
+ target[symbols.customInputs].delete(el);
246
+ }
247
+ });
248
+ }
249
+ }
250
+ });
251
+ });
252
+
253
+ const observerOpts = { attributes :true, attributeFilter: ['disabled'] };
254
+
255
+ class ElementInternals {
256
+ constructor(element, key) {
257
+ if (key !== symbols.key) {
258
+ throw new TypeError('Illegal constructor');
259
+ } else if (! (element instanceof HTMLElement)) {
260
+ throw new TypeError('Must be called on an HTMLElement');
261
+ } else if (! element.tagName.includes('-')) {
262
+ throw new DOMException('Cannot attach internals to a built-in element.');
263
+ } else {
264
+ // internals.add(this);
265
+ const configurable = true;
266
+ const enumerable = false;
267
+ const writable = true;
268
+
269
+ Object.defineProperties(this, {
270
+ [symbols.element]: { value: element, configurable, enumerable, writable },
271
+ [symbols.form]: { value: null, configurable, enumerable, writable },
272
+ [symbols.fieldset]: { value: null, configurable, enumerable, writable },
273
+ [symbols.anchor]: { value: null, configurable, enumerable, writable },
274
+ [symbols.validity]: { value: validationObject, configurable, enumerable, writable },
275
+ [symbols.validationMessage]: { value: '', configurable, enumerable, writable },
276
+ [symbols.value]: { value: null, configurable, enumerable, writable },
277
+ [symbols.state]: { value: null, configurable, enumerable, writable },
278
+ [symbols.formController]: { value: null, configurable, enumerable, writable },
279
+ });
280
+
281
+ if (isFormAssociated(element)) {
282
+ observer.observe(element, observerOpts);
283
+ }
284
+
285
+ Object.defineProperty(element, symbols.internals, {
286
+ value: this,
287
+ enumerable: false,
288
+ configurable: false,
289
+ writable: false,
290
+ });
291
+
292
+ setTimeout(() => this.states.add('--element-internals-polyfilled'), 10);
293
+ }
294
+ }
295
+
296
+ get form() {
297
+ return this[symbols.form];
298
+ }
299
+
300
+ get labels() {
301
+ const form = this.form;
302
+
303
+ if (form instanceof HTMLFormElement && this[symbols.element].id.length !== 0) {
304
+ return form.querySelectorAll(`label[for="${this[symbols.element].id}"]`);
305
+ } else {
306
+ return document.createDocumentFragment().childNodes;
307
+ }
308
+ }
309
+
310
+ get _polyfilled() {
311
+ return true;
312
+ }
313
+
314
+ get shadowRoot() {
315
+ const el = this[symbols.element];
316
+ return el.shadowRoot;
317
+ }
318
+
319
+ get validity() {
320
+ if (isFormAssociated(this[symbols.element])) {
321
+ return this[symbols.validity];
322
+ } else {
323
+ return undefined;
324
+ }
325
+ }
326
+
327
+ get validationMessage() {
328
+ if (isFormAssociated(this[symbols.element])) {
329
+ return this[symbols.validationMessage] || '';
330
+ } else {
331
+ return undefined;
332
+ }
333
+ }
334
+
335
+ get willValidate() {
336
+ const element = this[symbols.element];
337
+
338
+ return isFormAssociated(element)
339
+ && ! hasDisabledFieldset(element)
340
+ && ! ['disabled', 'readonly'].some(attr => element.hasAttribute(attr));
341
+ }
342
+
343
+ checkValidity() {
344
+ if (! this.willValidate) {
345
+ return true;
346
+ } else if (! this.validity.valid) {
347
+ this[symbols.element].dispatchEvent(new Event('invalid'));
348
+ return false;
349
+ } else {
350
+ const next = this[symbols.element].nextElementSibling;
351
+
352
+ if (next instanceof HTMLElement && next.classList.contains('_element-internals-popup')) {
353
+ next.remove();
354
+ }
355
+ return true;
356
+ }
357
+ }
358
+
359
+ reportValidity() {
360
+ if (! this.checkValidity()) {
361
+ const message = this.validationMessage;
362
+
363
+ if (typeof message === 'string' && message.length !== 0) {
364
+ // this[symbols.element].scrollIntoView({ block: 'start' });
365
+ const { bottom, left } = this[symbols.element].getBoundingClientRect();
366
+ const el = document.createElement('div');
367
+ el.textContent = message;
368
+
369
+ css(el, {
370
+ 'position': 'fixed',
371
+ 'background-color': '#2b2a33',
372
+ 'color': '#fafafa',
373
+ 'top': `${bottom + 2}px`,
374
+ 'left': `${left}px`,
375
+ 'z-index': 2147483647,
376
+ 'color-scheme': 'light-dark',
377
+ 'font-family': 'system-ui, serif',
378
+ 'font-size': '18px',
379
+ 'display': 'inline-block',
380
+ 'padding': '0.6em 0.8em',
381
+ 'border': '1px solid #1a1a1a',
382
+ 'border-radius': '6px',
383
+ });
384
+
385
+ el.classList.add('_element-internals-popup');
386
+
387
+ this[symbols.element].focus();
388
+
389
+ const next = this[symbols.element].nextElementSibling;
390
+
391
+ if (next instanceof Element && next.classList.contains('_element-internals-popup')) {
392
+ next.remove();
393
+ }
394
+
395
+ this[symbols.element].insertAdjacentElement('afterend', el);
396
+
397
+ if (this[symbols.anchor] instanceof Element) {
398
+ this[symbols.anchor].focus();
399
+ }
400
+
401
+ setTimeout(() => {
402
+ if (el.isConnected) {
403
+ el.remove();
404
+ }
405
+ }, 3000);
406
+ }
407
+
408
+ return false;
409
+ } else {
410
+ return true;
411
+ }
412
+ }
413
+
414
+ setFormValue(value, state) {
415
+ if (isFormAssociated(this[symbols.element])) {
416
+ this[symbols.value] = value;
417
+ this[symbols.state] = state;
418
+ } else {
419
+ throw new DOMException('Not form associated');
420
+ }
421
+ }
422
+
423
+ setValidity({
424
+ valueMissing = false,
425
+ typeMismatch = false,
426
+ patternMismatch = false,
427
+ tooLong = false,
428
+ tooShort = false,
429
+ rangeUnderflow = false,
430
+ rangeOverflow = false,
431
+ stepMismatch = false,
432
+ badInput = false,
433
+ customError = false,
434
+ }, message = '', anchor) {
435
+ if (! isFormAssociated(this[symbols.element])) {
436
+ throw new DOMException('Not form associated');
437
+ } else if (
438
+ (typeof message !== 'string' || message.length === 0)
439
+ && (
440
+ valueMissing || typeMismatch || patternMismatch || tooLong || tooShort
441
+ || rangeUnderflow || rangeOverflow || stepMismatch || badInput || customError
442
+ )
443
+ ) {
444
+ throw new DOMException('Message required if any flags are true.');
445
+ } else {
446
+ const valid = [
447
+ valueMissing, typeMismatch, patternMismatch, tooLong, tooShort,
448
+ rangeUnderflow, rangeOverflow, stepMismatch, badInput, customError,
449
+ ].every(val => val === false);
450
+
451
+ this[symbols.validity] = {
452
+ valueMissing, typeMismatch, patternMismatch, tooLong, tooShort,
453
+ rangeUnderflow, rangeOverflow, stepMismatch, badInput, customError,
454
+ valid,
455
+ };
456
+
457
+ this[symbols.validationMessage] = message;
458
+ this[symbols.anchor] = anchor;
459
+
460
+ if (! valid) {
461
+ this.states.add('--invalid');
462
+ this.states.delete('--valid');
463
+ this[symbols.element].dispatchEvent(new Event('invalid'));
464
+ } else {
465
+ this.states.delete('--invalid');
466
+ this.states.add('--valid');
467
+ }
468
+ }
469
+ }
470
+
471
+ _associateForm(form, component) {
472
+ associateForm(form, this, component);
473
+ }
474
+
475
+ _findAssociatedForm(component) {
476
+ return findAssociatedForm(component);
477
+ }
478
+ }
479
+
480
+ HTMLElement.prototype.attachInternals = function attachInternals() {
481
+ if (this.hasOwnProperty(symbols.internals)) {
482
+ throw new DOMException('Invalid operation');
483
+ } else if (! this.tagName.includes('-')) {
484
+ throw new DOMException('Cannot call attachInternals on built-in elements.');
485
+ } else {
486
+ return new ElementInternals(this, symbols.key);
487
+ }
488
+ };
489
+
490
+ globalThis.ElementInternals = ElementInternals;
491
+ }
492
+
493
+ /**
494
+ * Add `states` to `ElementInternals`
495
+ * Uses `._state--foo` instead of `:--foo` though
496
+ * Requires Iterator Helpers (`./iterator.js`)
497
+ */
498
+ if ('ElementInternals' in globalThis && ! ('CustomStateSet' in globalThis)) {
499
+ const prefix = '_state';
500
+ const protectedData = new WeakMap();
501
+ const getCName = state => {
502
+ if (! state.toString().startsWith('--')) {
503
+ throw new DOMException(`Failed to execute 'add' on 'CustomStateSet': The specified value '${state}' must start with '--'.`);
504
+ } else {
505
+ return `${prefix}${state}`;
506
+ }
507
+ };
508
+
509
+ const {
510
+ value, writable, configurable, enumerable,
511
+ } = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'attachInternals');
512
+
513
+ class CustomStateSet {
514
+ constructor(el, key) {
515
+ if (key !== symbols.key) {
516
+ throw new TypeError('Illegal Constructor');
517
+ } else if (! (el instanceof HTMLElement)) {
518
+ throw new TypeError('el must be an HTMLElement');
519
+ } else {
520
+ protectedData.set(this, el);
521
+ this.add('--custom-states-polyfilled');
522
+ }
523
+ }
524
+
525
+ get _polyfilled() {
526
+ return true;
527
+ }
528
+
529
+ get size() {
530
+ return [...this.values()].length;
531
+ }
532
+
533
+ add(state) {
534
+ protectedData.get(this).classList.add(getCName(state));
535
+ }
536
+
537
+ has(state) {
538
+ return protectedData.get(this).classList.contains(getCName(state));
539
+ }
540
+
541
+ delete(state) {
542
+ const c = getCName(state);
543
+
544
+ if (protectedData.get(this).classList.contains(c)) {
545
+ protectedData.get(this).classList.remove(c);
546
+ return true;
547
+ } else {
548
+ return false;
549
+ }
550
+ }
551
+
552
+ clear() {
553
+ this.values().forEach(state => this.delete(state));
554
+ }
555
+
556
+ keys() {
557
+ return this.values();
558
+ }
559
+
560
+ values() {
561
+ const states = protectedData.get(this).classList.values()
562
+ .filter(c => c.startsWith(`${prefix}--`));
563
+
564
+ return states.map(c => c.substr(prefix.length));
565
+ }
566
+
567
+ entries() {
568
+ return this.values().map(c => [c, c]);
569
+ }
570
+
571
+ forEach(callbackFn, thisArg) {
572
+ this.values().forEach(state => callbackFn.call(thisArg || this, state, state, this));
573
+ }
574
+
575
+ [Symbol.toStringTag]() {
576
+ return 'CustomStateSet';
577
+ }
578
+
579
+ [Symbol.iterator]() {
580
+ return this.values();
581
+ }
582
+ }
583
+
584
+ Object.defineProperty(HTMLElement.prototype, 'attachInternals', {
585
+ value: function() {
586
+ const internals = value.call(this);
587
+
588
+ Object.defineProperty(internals, symbols.element, {
589
+ value: this,
590
+ enumerable: false,
591
+ writable: false,
592
+ configurable: false,
593
+ });
594
+
595
+ Object.defineProperty(internals, 'states', {
596
+ value: new CustomStateSet(this, symbols.key),
597
+ configurable: true,
598
+ enumberable: true,
599
+ });
600
+
601
+ if (Object.is(internals.shadowRoot, null) && ! Object.is(this.shadowRoot, null)) {
602
+ Object.defineProperty(internals, 'shadowRoot', {
603
+ value: this.shadowRoot,
604
+ configurable: true,
605
+ enumerable: true,
606
+ });
607
+ }
608
+
609
+ return internals;
610
+ },
611
+ writable, configurable, enumerable,
612
+ });
613
+
614
+ globalThis.CustomStateSet = CustomStateSet;
615
+ shimAria(ElementInternals.prototype);
616
+ }
package/errors.js ADDED
@@ -0,0 +1,21 @@
1
+ import { errorToEvent } from './assets/error.js';
2
+
3
+ if (! globalThis.hasOwnProperty('AggregateError')) {
4
+ globalThis.AggregateError = class AggregateError extends Error {
5
+ constructor(errors, message) {
6
+ if (typeof message === 'undefined') {
7
+ super(errors);
8
+ this.errors = [];
9
+ } else {
10
+ super(message);
11
+ this.errors = errors;
12
+ }
13
+ }
14
+ };
15
+ }
16
+
17
+ if (! (globalThis.reportError instanceof Function)) {
18
+ globalThis.reportError = function reportError(error) {
19
+ globalThis.dispatchEvent(errorToEvent(error));
20
+ };
21
+ }
package/function.js ADDED
@@ -0,0 +1,31 @@
1
+ (function() {
2
+ 'use strict';
3
+
4
+ if (! (Function.prototype.once instanceof Function)) {
5
+ const funcs = new WeakMap();
6
+
7
+ /**
8
+ * @see https://github.com/tc39/proposal-function-once
9
+ */
10
+ Function.prototype.once = function once(thisArg) {
11
+ const callback = this;
12
+ return function(...args) {
13
+ if (funcs.has(callback)) {
14
+ return funcs.get(callback);
15
+ } else if (callback.constructor.name === 'AsyncFunction') {
16
+ const retVal = callback.apply(thisArg || callback, args).catch(err => {
17
+ funcs.delete(callback);
18
+ throw err;
19
+ });
20
+
21
+ funcs.set(callback, retVal);
22
+ return retVal;
23
+ } else if (callback instanceof Function) {
24
+ const retVal = callback.apply(thisArg || callback, args);
25
+ funcs.set(callback, retVal);
26
+ return retVal;
27
+ }
28
+ };
29
+ };
30
+ }
31
+ })();
package/globalThis.js ADDED
@@ -0,0 +1,36 @@
1
+ (function() {
2
+ 'use strict';
3
+
4
+ if (typeof globalThis === 'undefined') {
5
+ /* global global: true */
6
+ if (typeof self !== 'undefined') {
7
+ Object.defineProperty(self, 'globalThis', {
8
+ enumerable: false,
9
+ writable: true,
10
+ configurable: true,
11
+ value: self,
12
+ });
13
+ } else if (typeof window !== 'undefined') {
14
+ Object.defineProperty(Window.prototype, 'globalThis', {
15
+ enumerable: false,
16
+ writable: true,
17
+ configurable: true,
18
+ value: window,
19
+ });
20
+ } else if (typeof global !== 'undefined') {
21
+ Object.defineProperty(global, 'globalThis', {
22
+ enumerable: false,
23
+ writable: true,
24
+ configurable: true,
25
+ value: global,
26
+ });
27
+ } else {
28
+ Object.defineProperty(this, 'globalThis', {
29
+ enumerable: false,
30
+ writable: true,
31
+ configurable: true,
32
+ value: this,
33
+ });
34
+ }
35
+ }
36
+ })();