@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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/abort.js +194 -0
- package/all.js +30 -0
- package/animation.js +33 -0
- package/aom.js +43 -0
- package/appBadge.js +27 -0
- package/array.js +258 -0
- package/assets/CookieStore.js +230 -0
- package/assets/Lock.js +31 -0
- package/assets/LockManager.js +278 -0
- package/assets/Sanitizer.js +59 -0
- package/assets/SanitizerConfig.js +348 -0
- package/assets/SanitizerConfigBase.js +18 -0
- package/assets/SanitizerConfigEdge.js +335 -0
- package/assets/SanitizerConfigW3C.js +766 -0
- package/assets/Scheduler.js +124 -0
- package/assets/TextDecoder.js +83 -0
- package/assets/TextEncoder.js +41 -0
- package/assets/TrustedTypes.js +595 -0
- package/assets/attributes.js +15 -0
- package/assets/csp.js +29 -0
- package/assets/error.js +8 -0
- package/assets/sanitizerUtils.js +270 -0
- package/assets/trust.js +190 -0
- package/assets/utility.js +101 -0
- package/cookieStore.js +2 -0
- package/crypto.js +8 -0
- package/dialog.js +63 -0
- package/element.js +171 -0
- package/elementInternals.js +616 -0
- package/errors.js +21 -0
- package/function.js +31 -0
- package/globalThis.js +36 -0
- package/iterator.js +197 -0
- package/legacy/array.js +15 -0
- package/legacy/element.js +140 -0
- package/legacy/map.js +168 -0
- package/legacy/object.js +42 -0
- package/legacy.js +9 -0
- package/locks.js +33 -0
- package/map.js +32 -0
- package/match-media.js +58 -0
- package/math.js +69 -0
- package/navigator.js +55 -0
- package/number.js +14 -0
- package/package.json +52 -0
- package/performance.js +36 -0
- package/promise.js +70 -0
- package/sanitizer.js +3 -0
- package/scheduler.js +5 -0
- package/secure-context.js +31 -0
- package/set.js +73 -0
- package/share.js +17 -0
- package/symbols.js +9 -0
- package/textEncoder.js +16 -0
- package/trustedTypes.js +3 -0
- package/weakMap.js +28 -0
- package/window.js +85 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Chris Zuber
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/abort.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
if (! ('AbortSignal' in globalThis)) {
|
|
5
|
+
const symbols = {
|
|
6
|
+
signal: Symbol('signal'),
|
|
7
|
+
aborted: Symbol('aborted'),
|
|
8
|
+
reason: Symbol('reason'),
|
|
9
|
+
onabort: Symbol('onabort'),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
globalThis.AbortError = class AbortError extends Error {};
|
|
13
|
+
|
|
14
|
+
globalThis.AbortSignal = class AbortSignal extends EventTarget {
|
|
15
|
+
constructor() {
|
|
16
|
+
super();
|
|
17
|
+
|
|
18
|
+
Object.defineProperties(this,{
|
|
19
|
+
[symbols.aborted]: {
|
|
20
|
+
enumerable: false,
|
|
21
|
+
writable: true,
|
|
22
|
+
configurable: false,
|
|
23
|
+
value: false,
|
|
24
|
+
},
|
|
25
|
+
[symbols.reason]: {
|
|
26
|
+
enumerable: false,
|
|
27
|
+
writable: true,
|
|
28
|
+
configurable: false,
|
|
29
|
+
value: undefined,
|
|
30
|
+
},
|
|
31
|
+
[symbols.onabort]: {
|
|
32
|
+
enumerable: false,
|
|
33
|
+
writable: true,
|
|
34
|
+
configurable: false,
|
|
35
|
+
value: null,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
this.addEventListener('abort', event => {
|
|
40
|
+
if (this.onabort instanceof Function) {
|
|
41
|
+
this.onabort.call(this, event);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get aborted() {
|
|
47
|
+
return this[symbols.aborted];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get onabort() {
|
|
51
|
+
return this[symbols.onabort];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
set onabort(value) {
|
|
55
|
+
if (value instanceof Function) {
|
|
56
|
+
this[symbols.onabort] = value;
|
|
57
|
+
} else {
|
|
58
|
+
this[symbols.onabort] = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get reason() {
|
|
63
|
+
return this[symbols.reason];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
throwIfAborted() {
|
|
67
|
+
if (this.aborted) {
|
|
68
|
+
throw this.reason;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static abort(reason = new DOMException('Operation aborted')) {
|
|
73
|
+
const signal = new AbortSignal();
|
|
74
|
+
signal[symbols.aborted] = true;
|
|
75
|
+
signal[symbols.reason] = reason;
|
|
76
|
+
return signal;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
globalThis.AbortController = class AbortController {
|
|
81
|
+
constructor() {
|
|
82
|
+
this[symbols.signal] = new AbortSignal();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get signal() {
|
|
86
|
+
return this[symbols.signal];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
abort(reason = new DOMException('Operation aborted')) {
|
|
90
|
+
const signal = this.signal;
|
|
91
|
+
|
|
92
|
+
if (! signal.aborted) {
|
|
93
|
+
signal[symbols.aborted] = true;
|
|
94
|
+
signal[symbols.reason] = reason;
|
|
95
|
+
signal.dispatchEvent(new Event('abort'));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (! ('reason' in AbortSignal.prototype)) {
|
|
102
|
+
const reasons = new WeakMap();
|
|
103
|
+
const abort = AbortController.prototype.abort;
|
|
104
|
+
|
|
105
|
+
if (AbortSignal.abort instanceof Function) {
|
|
106
|
+
const staticAbort = AbortSignal.abort;
|
|
107
|
+
|
|
108
|
+
AbortSignal.abort = function(reason = new DOMException('Operation aborted')) {
|
|
109
|
+
const signal = staticAbort();
|
|
110
|
+
reasons.set(signal, reason);
|
|
111
|
+
return signal;
|
|
112
|
+
};
|
|
113
|
+
} else {
|
|
114
|
+
AbortSignal.abort = function abort(reason = new DOMException('Operation aborted')) {
|
|
115
|
+
const controller = new AbortController();
|
|
116
|
+
controller.abort(reason);
|
|
117
|
+
return controller.reason;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Object.defineProperty(AbortSignal.prototype, 'reason', {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
configurable: true,
|
|
124
|
+
get: function() {
|
|
125
|
+
if (reasons.has(this)) {
|
|
126
|
+
return reasons.get(this);
|
|
127
|
+
} else {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
AbortController.prototype.abort = function(reason = new DOMException('Operation aborted')) {
|
|
134
|
+
reasons.set(this.signal, reason);
|
|
135
|
+
abort.call(this);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (! (AbortSignal.prototype.throwIfAborted instanceof Function)) {
|
|
140
|
+
AbortSignal.prototype.throwIfAborted = function() {
|
|
141
|
+
if (this.aborted) {
|
|
142
|
+
throw this.reason;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (! (AbortSignal.timeout instanceof Function)) {
|
|
148
|
+
AbortSignal.timeout = function(ms) {
|
|
149
|
+
if (typeof ms === 'undefined') {
|
|
150
|
+
throw new TypeError('At least one 1 argument required but only 0 passed');
|
|
151
|
+
} else if (! Number.isFinite(ms)) {
|
|
152
|
+
throw new TypeError('Argument 1 is not a finite value, so it is out of range for unsigned long long.');
|
|
153
|
+
} else if (ms < 0) {
|
|
154
|
+
throw new TypeError('Argument 1 is out of range for unsigned long long.');
|
|
155
|
+
} else {
|
|
156
|
+
const controller = new AbortController();
|
|
157
|
+
setTimeout(() => controller.abort(new DOMException('The operation timed out.')), ms);
|
|
158
|
+
return controller.signal;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @see https://chromestatus.com/feature/5202879349522432
|
|
165
|
+
* @TODO How do I handle if a signal is already aborted
|
|
166
|
+
* @TODO Should controller abort on a TypeError
|
|
167
|
+
*/
|
|
168
|
+
if (! (AbortSignal.any instanceof Function)) {
|
|
169
|
+
AbortSignal.any = function(signals) {
|
|
170
|
+
if (! Array.isArray(signals)) {
|
|
171
|
+
throw new TypeError('Expected an array of signals');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const controller = new AbortController();
|
|
175
|
+
|
|
176
|
+
for (const signal of signals) {
|
|
177
|
+
if (! (signal instanceof AbortSignal)) {
|
|
178
|
+
const err = new TypeError('`signal` is not an `AbortSignal`');
|
|
179
|
+
controller.abort(err);
|
|
180
|
+
throw err;
|
|
181
|
+
} else if (signal.aborted) {
|
|
182
|
+
controller.abort(signal.reason || new DOMException('Operation aborted.'));
|
|
183
|
+
break;
|
|
184
|
+
} else {
|
|
185
|
+
signal.addEventListener('abort', ({ target }) => {
|
|
186
|
+
controller.abort(target.reason || new DOMException('Operation aborted.'));
|
|
187
|
+
}, { signal: controller.signal });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return controller.signal;
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
})();
|
package/all.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2023 Chris Zuber <admin@kernvalley.us>
|
|
3
|
+
*/
|
|
4
|
+
import './symbols.js';
|
|
5
|
+
import './array.js';
|
|
6
|
+
import './globalThis.js';
|
|
7
|
+
import './function.js';
|
|
8
|
+
import './number.js';
|
|
9
|
+
import './iterator.js';
|
|
10
|
+
import './math.js';
|
|
11
|
+
import './secure-context.js';
|
|
12
|
+
import './navigator.js';
|
|
13
|
+
import './performance.js';
|
|
14
|
+
import './abort.js';
|
|
15
|
+
import './errors.js';
|
|
16
|
+
import './match-media.js';
|
|
17
|
+
import './promise.js';
|
|
18
|
+
import './textEncoder.js';
|
|
19
|
+
import './crypto.js';
|
|
20
|
+
import './cookieStore.js';
|
|
21
|
+
import './animation.js';
|
|
22
|
+
import './trustedTypes.js';
|
|
23
|
+
import './sanitizer.js';
|
|
24
|
+
import './element.js';
|
|
25
|
+
import './set.js';
|
|
26
|
+
import './map.js';
|
|
27
|
+
import './weakMap.js';
|
|
28
|
+
import './window.js';
|
|
29
|
+
import './scheduler.js';
|
|
30
|
+
import './elementInternals.js';
|
package/animation.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
if (globalThis.hasOwnProperty('Animation') && ! Animation.prototype.hasOwnProperty('finished')) {
|
|
5
|
+
Object.defineProperty(Animation.prototype, 'finished', {
|
|
6
|
+
get: function() {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
if (this.playState === 'finished') {
|
|
9
|
+
resolve(this);
|
|
10
|
+
} else {
|
|
11
|
+
this.addEventListener('finish', () => resolve(this), { once: true });
|
|
12
|
+
this.addEventListener('error', event => reject(event), { once: true });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (globalThis.hasOwnProperty('Animation') && ! Animation.prototype.hasOwnProperty('ready')) {
|
|
20
|
+
Object.defineProperty(Animation.prototype, 'ready', {
|
|
21
|
+
get: function() {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
if (! this.pending) {
|
|
24
|
+
resolve(this);
|
|
25
|
+
} else {
|
|
26
|
+
this.addEventListener('ready', () => resolve(this), { once: true });
|
|
27
|
+
this.addEventListener('error', event => reject(event), { once: true });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
})();
|
package/aom.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const aria = {
|
|
2
|
+
ariaAtomic: 'aria-atomic',
|
|
3
|
+
ariaAutoComplete: 'aria-autocomplete',
|
|
4
|
+
ariaBusy: 'aria-busy',
|
|
5
|
+
ariaChecked: 'aria-checked',
|
|
6
|
+
ariaColCount: 'aria-colcount',
|
|
7
|
+
ariaColIndex: 'aria-colindex',
|
|
8
|
+
ariaColIndexText: 'aria-colindextext',
|
|
9
|
+
ariaColSpan: 'aria-colspan',
|
|
10
|
+
ariaCurrent: 'aria-current',
|
|
11
|
+
ariaDisabled: 'aria-disabled',
|
|
12
|
+
ariaExpanded: 'aria-expanded',
|
|
13
|
+
ariaHasPopup: 'aria-haspopup',
|
|
14
|
+
ariaHidden: 'aria-hidden',
|
|
15
|
+
ariaInvalid: 'aria-invalid',
|
|
16
|
+
ariaKeyShortcuts: 'aria-keyshortcuts',
|
|
17
|
+
ariaLabel: 'aria-label',
|
|
18
|
+
ariaLevel: 'aria-level',
|
|
19
|
+
ariaLive: 'aria-live',
|
|
20
|
+
ariaModal: 'aria-modal',
|
|
21
|
+
ariaMultiLine: 'aria-multiline',
|
|
22
|
+
ariaMultiSelectable: 'aria-multiselectable',
|
|
23
|
+
ariaOrientation: 'aria-orientation',
|
|
24
|
+
ariaPlaceholder: 'aria-placeholder',
|
|
25
|
+
ariaPosInSet: 'aria-posinset',
|
|
26
|
+
ariaPressed: 'aria-pressed',
|
|
27
|
+
ariaReadOnly: 'aria-readonly',
|
|
28
|
+
ariaRelevant: 'aria-relevant',
|
|
29
|
+
ariaRequired: 'aria-required',
|
|
30
|
+
ariaRoleDescription: 'aria-roledescription',
|
|
31
|
+
ariaRowCount: 'aria-rowcount',
|
|
32
|
+
ariaRowIndex: 'aria-rowindex',
|
|
33
|
+
ariaRowIndexText: 'aria-rowindextext',
|
|
34
|
+
ariaRowSpan: 'aria-rowspan',
|
|
35
|
+
ariaSelected: 'aria-selected',
|
|
36
|
+
ariaSetSize: 'aria-setsize',
|
|
37
|
+
ariaSort: 'aria-sort',
|
|
38
|
+
ariaValueMax: 'aria-valuemax',
|
|
39
|
+
ariaValueMin: 'aria-valuemin',
|
|
40
|
+
ariaValueNow: 'aria-valuenow',
|
|
41
|
+
ariaValueText: 'aria-valuetext',
|
|
42
|
+
role: 'role'
|
|
43
|
+
};
|
package/appBadge.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
if (! (navigator.setAppBadge instanceof Function)) {
|
|
5
|
+
navigator.setAppBadge = async (n) => {
|
|
6
|
+
if (! Number.isInteger(n)) {
|
|
7
|
+
throw new TypeError('Failed to execute \'setAppBadge\' on \'Navigator\': Value is not of type \'unsigned long long\'');
|
|
8
|
+
} else if (n < 0) {
|
|
9
|
+
throw new TypeError('Failed to execute \'setAppBadge\' on \'Navigator\': Value is outside the \'unsigned long long\' value range.');
|
|
10
|
+
} else if (n === 0) {
|
|
11
|
+
if (document.title.startsWith('(')) {
|
|
12
|
+
document.title = document.title.replace(/^\((\d{1,2}\+?)\)\s/, '');
|
|
13
|
+
}
|
|
14
|
+
} else if (n < 100) {
|
|
15
|
+
await navigator.clearAppBadge();
|
|
16
|
+
document.title = `(${n}) ${document.title}`;
|
|
17
|
+
} else {
|
|
18
|
+
await navigator.clearAppBadge();
|
|
19
|
+
document.title = `(99+) ${document.title}`;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (! (navigator.clearAppBadge instanceof Function)) {
|
|
25
|
+
navigator.clearAppBadge = () => navigator.setAppBadge(0);
|
|
26
|
+
}
|
|
27
|
+
})();
|
package/array.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @SEE https://github.com/tc39/proposal-relative-indexing-method#polyfill
|
|
6
|
+
* @SEE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const SHIM_TARGETS = [Array, String, globalThis.Int8Array, globalThis.Uint8Array,
|
|
10
|
+
globalThis.Uint8ClampedArray, globalThis.Int16Array, globalThis.Uint16Array,
|
|
11
|
+
globalThis.Int32Array, globalThis.Uint32Array, globalThis.Float32Array,
|
|
12
|
+
globalThis.Float64Array, globalThis.BigInt64Array, globalThis.BigUint64Array,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
if (! (Array.prototype.flat instanceof Function)) {
|
|
16
|
+
Array.prototype.flat = function(depth = 1) {
|
|
17
|
+
const result = [];
|
|
18
|
+
depth = Math.min(Number.MAX_SAFE_INTEGER, Math.max(0, depth));
|
|
19
|
+
|
|
20
|
+
const flattenFn = (item, depth) => {
|
|
21
|
+
if (Array.isArray(item) && depth >= 0) {
|
|
22
|
+
item.forEach(i => flattenFn(i, depth - 1));
|
|
23
|
+
} else {
|
|
24
|
+
result.push(item);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
flattenFn(this, Number.isNaN(depth) ? 0 : depth);
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (! (Array.prototype.flatMap instanceof Function)) {
|
|
34
|
+
Array.prototype.flatMap = function(cb, thisArg) {
|
|
35
|
+
return this.map(cb, thisArg).flat(1);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (! (Array.prototype.findLast instanceof Function)) {
|
|
40
|
+
Array.prototype.findLast = function(callback, thisArg) {
|
|
41
|
+
let found = undefined;
|
|
42
|
+
|
|
43
|
+
this.forEach((item, index, arr) => {
|
|
44
|
+
if (callback.call(thisArg, item, index, arr)) {
|
|
45
|
+
found = item;
|
|
46
|
+
}
|
|
47
|
+
}, thisArg);
|
|
48
|
+
|
|
49
|
+
return found;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (! (Array.prototype.findLastIndex instanceof Function)) {
|
|
54
|
+
Array.prototype.findLastIndex = function(callback, thisArg) {
|
|
55
|
+
let found = -1;
|
|
56
|
+
|
|
57
|
+
this.forEach((item, index, arr) => {
|
|
58
|
+
if (callback.call(thisArg, item, index, arr)) {
|
|
59
|
+
found = index;
|
|
60
|
+
}
|
|
61
|
+
}, thisArg);
|
|
62
|
+
|
|
63
|
+
return found;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (! (Array.prototype.at instanceof Function)) {
|
|
68
|
+
const at = function at(n) {
|
|
69
|
+
n = Math.trunc(n) || 0;
|
|
70
|
+
if (n < 0) n += this.length;
|
|
71
|
+
if (n < 0 || n >= this.length) return undefined;
|
|
72
|
+
return this[n];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
for (const C of SHIM_TARGETS) {
|
|
76
|
+
if (typeof C !== 'undefined') {
|
|
77
|
+
Object.defineProperty(C.prototype, 'at', {
|
|
78
|
+
value: at,
|
|
79
|
+
writable: true,
|
|
80
|
+
enumerable: false,
|
|
81
|
+
configurable: true
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @see https://github.com/tc39/proposal-array-grouping
|
|
89
|
+
*/
|
|
90
|
+
if (! (Array.prototype.group instanceof Function)) {
|
|
91
|
+
Array.prototype.group = function group(callback, thisArg = globalThis) {
|
|
92
|
+
return this.reduce((groups, item, index, arr) => {
|
|
93
|
+
const key = callback.call(thisArg, item, index, arr);
|
|
94
|
+
|
|
95
|
+
if (! groups.hasOwnProperty(key)) {
|
|
96
|
+
groups[key] = [item];
|
|
97
|
+
} else {
|
|
98
|
+
groups[key].push(item);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return groups;
|
|
102
|
+
}, {});
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated [renamed to `group()`]
|
|
108
|
+
*/
|
|
109
|
+
Array.prototype.groupBy = function groupBy(...args) {
|
|
110
|
+
console.warn('`goupBy` is deprecated. Please use `group` instead.');
|
|
111
|
+
return this.group(...args);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @see https://github.com/tc39/proposal-array-grouping
|
|
116
|
+
* @requires `Map.prototype.emplace`
|
|
117
|
+
*/
|
|
118
|
+
if (! (Array.prototype.groupToMap instanceof Function) && (Map.prototype.emplace instanceof Function)) {
|
|
119
|
+
Array.prototype.groupToMap = function groupToMap(callback, thisArg = globalThis) {
|
|
120
|
+
return this.reduce((map, item, index, arr) => {
|
|
121
|
+
map.emplace(callback.call(thisArg, item, index, arr), {
|
|
122
|
+
insert: () => [item],
|
|
123
|
+
update: existing => {
|
|
124
|
+
existing.push(item);
|
|
125
|
+
return existing;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return map;
|
|
130
|
+
}, new Map());
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @deprecated [renamed to `groupToMap()`]
|
|
136
|
+
*/
|
|
137
|
+
if (Map.prototype.emplace instanceof Function) {
|
|
138
|
+
Array.prototype.groupByToMap = function groupByToMap(...args) {
|
|
139
|
+
console.warn('`goupByToMap` is deprecated. Please use `groupToMap` instead.');
|
|
140
|
+
return this.groupToMap(...args);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @see https://github.com/tc39/proposal-array-from-async
|
|
146
|
+
*/
|
|
147
|
+
if (! (Array.fromAsync instanceof Function)) {
|
|
148
|
+
Array.fromAsync = async function fromAsync(items, mapFn, thisArg = globalThis) {
|
|
149
|
+
let arr = [];
|
|
150
|
+
|
|
151
|
+
for await (const item of items) {
|
|
152
|
+
arr.push(await item);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return Array.from(arr, mapFn, thisArg);
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @see https://github.com/tc39/proposal-array-equality/
|
|
161
|
+
*/
|
|
162
|
+
if (! (Array.prototype.equals instanceof Function)) {
|
|
163
|
+
Array.prototype.equals = function equals(arr) {
|
|
164
|
+
if (this === arr) {
|
|
165
|
+
return true;
|
|
166
|
+
} else if (! Array.isArray(arr)) {
|
|
167
|
+
return false;
|
|
168
|
+
} else if (this.length !== arr.length) {
|
|
169
|
+
return false;
|
|
170
|
+
} else {
|
|
171
|
+
return this.every((item, i) => {
|
|
172
|
+
const val = arr[i];
|
|
173
|
+
if (Array.isArray(item)) {
|
|
174
|
+
return Array.isArray(val) && item.equals(val);
|
|
175
|
+
} else {
|
|
176
|
+
return Object.is(item, val);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* @see https://github.com/tc39/proposal-array-unique
|
|
184
|
+
*/
|
|
185
|
+
if (! (Array.prototype.uniqueBy instanceof Function)) {
|
|
186
|
+
Array.prototype.uniqueBy = function uniqueBy(arg) {
|
|
187
|
+
if (typeof arg === 'undefined') {
|
|
188
|
+
return [...new Set(this)];
|
|
189
|
+
} else if (typeof arg === 'string') {
|
|
190
|
+
const found = [];
|
|
191
|
+
|
|
192
|
+
return this.filter(obj => {
|
|
193
|
+
const key = obj[arg];
|
|
194
|
+
if (found.includes(key)) {
|
|
195
|
+
return false;
|
|
196
|
+
} else {
|
|
197
|
+
found.push(key);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
} else if (arg instanceof Function) {
|
|
202
|
+
const found = [];
|
|
203
|
+
|
|
204
|
+
return this.filter((...args) => {
|
|
205
|
+
try {
|
|
206
|
+
const key = arg.apply(this, args);
|
|
207
|
+
|
|
208
|
+
if (typeof key !== 'string') {
|
|
209
|
+
return false;
|
|
210
|
+
} else if (found.includes(key)) {
|
|
211
|
+
return false;
|
|
212
|
+
} else {
|
|
213
|
+
found.push(key);
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
} catch(err) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
} else {
|
|
221
|
+
throw new TypeError('Not a valid argument for uniqueBy');
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Change Array by copy proposal
|
|
228
|
+
* @Note: Not clear if should use `structedClone` or `[...this]` for copies
|
|
229
|
+
* @see https://github.com/tc39/proposal-change-array-by-copy
|
|
230
|
+
*/
|
|
231
|
+
if (! (Array.prototype.toReversed instanceof Function)) {
|
|
232
|
+
Array.prototype.toReversed = function toReversed() {
|
|
233
|
+
return [...this].reverse();
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (! (Array.prototype.toSorted instanceof Function)) {
|
|
238
|
+
Array.prototype.toSorted = function toSorted(cmpFn) {
|
|
239
|
+
return [...this].sort(cmpFn);
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (! (Array.prototype.toSpliced instanceof Function)) {
|
|
244
|
+
Array.prototype.toSpliced = function toSpliced(start, deleteCount, ...items) {
|
|
245
|
+
const cpy = [...this];
|
|
246
|
+
cpy.splice(start, deleteCount, ...items);
|
|
247
|
+
return cpy;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (! (Array.prototype.with instanceof Function)) {
|
|
252
|
+
Array.prototype.with = function (index, value) {
|
|
253
|
+
const cpy = [...this];
|
|
254
|
+
cpy[index] = value;
|
|
255
|
+
return cpy;
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
})();
|