@shgysk8zer0/polyfills 0.3.0 → 0.3.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 +19 -0
- package/README.md +1 -1
- package/all.min.js +14 -14
- package/all.min.js.map +1 -1
- package/array.js +336 -234
- package/assets/SanitizerConfigW3C.js +215 -631
- package/assets/sanitizerUtils.js +17 -4
- package/element.js +117 -0
- package/iterator.js +39 -0
- package/math.js +61 -56
- package/package.json +1 -1
- package/popover.css +25 -0
- package/popover.js +118 -0
package/array.js
CHANGED
|
@@ -1,267 +1,369 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* @SEE https://github.com/tc39/proposal-relative-indexing-method#polyfill
|
|
3
|
+
* @SEE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
|
|
4
|
+
*/
|
|
27
5
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
6
|
+
const SHIM_TARGETS = [Array, String, globalThis.Int8Array, globalThis.Uint8Array,
|
|
7
|
+
globalThis.Uint8ClampedArray, globalThis.Int16Array, globalThis.Uint16Array,
|
|
8
|
+
globalThis.Int32Array, globalThis.Uint32Array, globalThis.Float32Array,
|
|
9
|
+
globalThis.Float64Array, globalThis.BigInt64Array, globalThis.BigUint64Array,
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
if (! (Array.prototype.flat instanceof Function)) {
|
|
13
|
+
Array.prototype.flat = function(depth = 1) {
|
|
14
|
+
const result = [];
|
|
15
|
+
depth = Math.min(Number.MAX_SAFE_INTEGER, Math.max(0, depth));
|
|
32
16
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
const flattenFn = (item, depth) => {
|
|
18
|
+
if (Array.isArray(item) && depth >= 0) {
|
|
19
|
+
item.forEach(i => flattenFn(i, depth - 1));
|
|
20
|
+
} else {
|
|
21
|
+
result.push(item);
|
|
22
|
+
}
|
|
36
23
|
};
|
|
37
|
-
}
|
|
38
24
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
flattenFn(this, Number.isNaN(depth) ? 0 : depth);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
42
29
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
if (! (Array.prototype.flatMap instanceof Function)) {
|
|
31
|
+
Array.prototype.flatMap = function(cb, thisArg) {
|
|
32
|
+
return this.map(cb, thisArg).flat(1);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
if (! (Array.prototype.findLast instanceof Function)) {
|
|
37
|
+
Array.prototype.findLast = function(callback, thisArg) {
|
|
38
|
+
let found = undefined;
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
configurable: false,
|
|
57
|
-
get: function() {
|
|
58
|
-
return Math.max(0, this.length - 1);
|
|
40
|
+
this.forEach((item, index, arr) => {
|
|
41
|
+
if (callback.call(thisArg, item, index, arr)) {
|
|
42
|
+
found = item;
|
|
59
43
|
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
44
|
+
}, thisArg);
|
|
62
45
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
configurable: false,
|
|
67
|
-
get: function() {
|
|
68
|
-
return this[this.lastIndex];
|
|
69
|
-
},
|
|
70
|
-
set: function(val) {
|
|
71
|
-
this[this.lastIndex] = val;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
46
|
+
return found;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
75
49
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
50
|
+
if(! ('lastIndex' in Array.prototype)) {
|
|
51
|
+
Object.defineProperty(Array.prototype, 'lastIndex', {
|
|
52
|
+
enumerable: false,
|
|
53
|
+
configurable: false,
|
|
54
|
+
get: function() {
|
|
55
|
+
return Math.max(0, this.length - 1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
85
59
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
60
|
+
if(! ('lastItem' in Array.prototype)) {
|
|
61
|
+
Object.defineProperty(Array.prototype, 'lastItem', {
|
|
62
|
+
enumerable: false,
|
|
63
|
+
configurable: false,
|
|
64
|
+
get: function() {
|
|
65
|
+
return this[this.lastIndex];
|
|
66
|
+
},
|
|
67
|
+
set: function(val) {
|
|
68
|
+
this[this.lastIndex] = val;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
89
72
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (n < 0) n += this.length;
|
|
94
|
-
if (n < 0 || n >= this.length) return undefined;
|
|
95
|
-
return this[n];
|
|
96
|
-
};
|
|
73
|
+
if (! (Array.prototype.findLastIndex instanceof Function)) {
|
|
74
|
+
Array.prototype.findLastIndex = function(callback, thisArg) {
|
|
75
|
+
let found = -1;
|
|
97
76
|
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
value: at,
|
|
102
|
-
writable: true,
|
|
103
|
-
enumerable: false,
|
|
104
|
-
configurable: true
|
|
105
|
-
});
|
|
77
|
+
this.forEach((item, index, arr) => {
|
|
78
|
+
if (callback.call(thisArg, item, index, arr)) {
|
|
79
|
+
found = index;
|
|
106
80
|
}
|
|
81
|
+
}, thisArg);
|
|
82
|
+
|
|
83
|
+
return found;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (! (Array.prototype.at instanceof Function)) {
|
|
88
|
+
const at = function at(n) {
|
|
89
|
+
n = Math.trunc(n) || 0;
|
|
90
|
+
if (n < 0) n += this.length;
|
|
91
|
+
if (n < 0 || n >= this.length) return undefined;
|
|
92
|
+
return this[n];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
for (const C of SHIM_TARGETS) {
|
|
96
|
+
if (typeof C !== 'undefined') {
|
|
97
|
+
Object.defineProperty(C.prototype, 'at', {
|
|
98
|
+
value: at,
|
|
99
|
+
writable: true,
|
|
100
|
+
enumerable: false,
|
|
101
|
+
configurable: true
|
|
102
|
+
});
|
|
107
103
|
}
|
|
108
104
|
}
|
|
105
|
+
}
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
107
|
+
/**
|
|
108
|
+
* @deprecated [moved to `Object.groupBy()`]
|
|
109
|
+
* @see https://github.com/tc39/proposal-array-grouping
|
|
110
|
+
*/
|
|
111
|
+
if (! (Array.prototype.group instanceof Function) && Object.groupBy instanceof Function) {
|
|
112
|
+
Array.prototype.group = function group(callback) {
|
|
113
|
+
console.warn('`Array.group()` is deprecated. Please use `Object.groupBy()` instead.');
|
|
114
|
+
return Object.groupBy(this, callback);
|
|
115
|
+
};
|
|
116
|
+
}
|
|
120
117
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
/**
|
|
119
|
+
* @deprecated [moved to `Object.groupBy()`]
|
|
120
|
+
*/
|
|
121
|
+
if (! (Array.prototype.groupBy instanceof Function) && Object.groupBy instanceof Function) {
|
|
122
|
+
Array.prototype.groupBy = function groupBy(callback) {
|
|
123
|
+
console.warn('`Array.goupBy()` is deprecated. Please use `Object.groupBy()` instead.');
|
|
124
|
+
return Object.groupBy(this, callback);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
128
|
+
/**
|
|
129
|
+
* @see https://github.com/tc39/proposal-array-grouping
|
|
130
|
+
* @deprecated [moved to `Map.groupBy()`]
|
|
131
|
+
* @requires `Map.prototype.emplace`
|
|
132
|
+
*/
|
|
133
|
+
if (! (Array.prototype.groupToMap instanceof Function) && (Map.groupBy instanceof Function)) {
|
|
134
|
+
Array.prototype.groupToMap = function groupToMap(callback) {
|
|
135
|
+
console.warn('`Array.groupToMap()` is deprecated. Please use `Map.groupBy()` instead.');
|
|
136
|
+
return Map.groupBy(this, callback);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
142
139
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
140
|
+
/**
|
|
141
|
+
* @deprecated [moved to `Map.groupBy()`]
|
|
142
|
+
*/
|
|
143
|
+
if (Map.groupBy instanceof Function) {
|
|
144
|
+
Array.prototype.groupByToMap = function groupByToMap(callback) {
|
|
145
|
+
console.warn('`Array.groupByToMap()` is deprecated. Please use `Map.groupBy()` instead.');
|
|
146
|
+
return Map.groupBy(this, callback);
|
|
147
|
+
};
|
|
148
|
+
}
|
|
152
149
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
/**
|
|
151
|
+
* @see https://github.com/tc39/proposal-array-from-async
|
|
152
|
+
*/
|
|
153
|
+
if (! (Array.fromAsync instanceof Function)) {
|
|
154
|
+
Array.fromAsync = async function fromAsync(items, mapFn, thisArg = globalThis) {
|
|
155
|
+
let arr = [];
|
|
159
156
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
for await (const item of items) {
|
|
158
|
+
arr.push(await item);
|
|
159
|
+
}
|
|
163
160
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
return Array.from(arr, mapFn, thisArg);
|
|
162
|
+
};
|
|
163
|
+
}
|
|
167
164
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
165
|
+
/**
|
|
166
|
+
* @see https://github.com/tc39/proposal-array-equality/
|
|
167
|
+
*/
|
|
168
|
+
if (! (Array.prototype.equals instanceof Function)) {
|
|
169
|
+
Array.prototype.equals = function equals(arr) {
|
|
170
|
+
if (this === arr) {
|
|
171
|
+
return true;
|
|
172
|
+
} else if (! Array.isArray(arr)) {
|
|
173
|
+
return false;
|
|
174
|
+
} else if (this.length !== arr.length) {
|
|
175
|
+
return false;
|
|
176
|
+
} else {
|
|
177
|
+
return this.every((item, i) => {
|
|
178
|
+
const val = arr[i];
|
|
179
|
+
if (Array.isArray(item)) {
|
|
180
|
+
return Array.isArray(val) && item.equals(val);
|
|
181
|
+
} else {
|
|
182
|
+
return Object.is(item, val);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* @see https://github.com/tc39/proposal-array-unique
|
|
190
|
+
*/
|
|
191
|
+
if (! (Array.prototype.uniqueBy instanceof Function)) {
|
|
192
|
+
Array.prototype.uniqueBy = function uniqueBy(arg) {
|
|
193
|
+
if (typeof arg === 'undefined') {
|
|
194
|
+
return [...new Set(this)];
|
|
195
|
+
} else if (typeof arg === 'string') {
|
|
196
|
+
const found = [];
|
|
197
|
+
|
|
198
|
+
return this.filter(obj => {
|
|
199
|
+
const key = obj[arg];
|
|
200
|
+
if (found.includes(key)) {
|
|
201
|
+
return false;
|
|
202
|
+
} else {
|
|
203
|
+
found.push(key);
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
} else if (arg instanceof Function) {
|
|
208
|
+
const found = [];
|
|
209
|
+
|
|
210
|
+
return this.filter((...args) => {
|
|
211
|
+
try {
|
|
212
|
+
const key = arg.apply(this, args);
|
|
213
|
+
|
|
214
|
+
if (typeof key !== 'string') {
|
|
215
|
+
return false;
|
|
216
|
+
} else if (found.includes(key)) {
|
|
204
217
|
return false;
|
|
205
218
|
} else {
|
|
206
219
|
found.push(key);
|
|
207
220
|
return true;
|
|
208
221
|
}
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return false;
|
|
219
|
-
} else if (found.includes(key)) {
|
|
220
|
-
return false;
|
|
221
|
-
} else {
|
|
222
|
-
found.push(key);
|
|
223
|
-
return true;
|
|
224
|
-
}
|
|
225
|
-
} catch(err) {
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
} else {
|
|
230
|
-
throw new TypeError('Not a valid argument for uniqueBy');
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
}
|
|
222
|
+
} catch(err) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
} else {
|
|
227
|
+
throw new TypeError('Not a valid argument for uniqueBy');
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
234
231
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
232
|
+
/**
|
|
233
|
+
* Change Array by copy proposal
|
|
234
|
+
* @Note: Not clear if should use `structedClone` or `[...this]` for copies
|
|
235
|
+
* @see https://github.com/tc39/proposal-change-array-by-copy
|
|
236
|
+
*/
|
|
237
|
+
if (! (Array.prototype.toReversed instanceof Function)) {
|
|
238
|
+
Array.prototype.toReversed = function toReversed() {
|
|
239
|
+
return [...this].reverse();
|
|
240
|
+
};
|
|
241
|
+
}
|
|
245
242
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
243
|
+
if (! (Array.prototype.toSorted instanceof Function)) {
|
|
244
|
+
Array.prototype.toSorted = function toSorted(cmpFn) {
|
|
245
|
+
return [...this].sort(cmpFn);
|
|
246
|
+
};
|
|
247
|
+
}
|
|
251
248
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
249
|
+
if (! (Array.prototype.toSpliced instanceof Function)) {
|
|
250
|
+
Array.prototype.toSpliced = function toSpliced(start, deleteCount, ...items) {
|
|
251
|
+
const cpy = [...this];
|
|
252
|
+
cpy.splice(start, deleteCount, ...items);
|
|
253
|
+
return cpy;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
259
256
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
257
|
+
if (! (Array.prototype.with instanceof Function)) {
|
|
258
|
+
Array.prototype.with = function (index, value) {
|
|
259
|
+
const cpy = [...this];
|
|
260
|
+
cpy[index] = value;
|
|
261
|
+
return cpy;
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (! (Array.isTemplateObject instanceof Function)) {
|
|
266
|
+
Array.isTemplateObject = function(target) {
|
|
267
|
+
if (! (
|
|
268
|
+
Array.isArray(target) && Array.isArray(target.raw)
|
|
269
|
+
&& Object.isFrozen(target) && Object.isFrozen(target.raw)
|
|
270
|
+
)) {
|
|
271
|
+
return false;
|
|
272
|
+
} else {
|
|
273
|
+
return target.length !== 0 && target.length === target.raw.length;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* @see https://github.com/tc39/proposal-arraybuffer-base64
|
|
280
|
+
*/
|
|
281
|
+
if (! (Uint8Array.prototype.toHex instanceof Function)) {
|
|
282
|
+
Uint8Array.prototype.toHex = function toHex() {
|
|
283
|
+
return Array.from(this).map(n => n.toString(16).padStart('0', 2)).join('');
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (! (Uint8Array.prototype.toBase64 instanceof Function)) {
|
|
288
|
+
Uint8Array.prototype.toBase64 = function toBase64({ alphabet = 'base64' } = {}) {
|
|
289
|
+
if (alphabet === 'base64') {
|
|
290
|
+
// @todo Figure out encoding specifics
|
|
291
|
+
return btoa(String.fromCodePoint(...this));
|
|
292
|
+
// return btoa(new TextDecoder().decode(this));
|
|
293
|
+
} else if (alphabet === 'base64url') {
|
|
294
|
+
return this.toBase64({ alphabet: 'base64' }).replaceAll('+', '-').replaceAll('/', '_');
|
|
295
|
+
} else {
|
|
296
|
+
throw new TypeError('expected alphabet to be either "base64" or "base64url');
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (! (Uint8Array.fromHex instanceof Function)) {
|
|
302
|
+
Uint8Array.fromHex = function fromHex(str) {
|
|
303
|
+
if (typeof str !== 'string') {
|
|
304
|
+
throw new TypeError('expected input to be a string');
|
|
305
|
+
} else if (! (str.length & 1) === 0) {
|
|
306
|
+
throw new SyntaxError('string should be an even number of characters');
|
|
307
|
+
} else {
|
|
308
|
+
return Uint8Array.from(
|
|
309
|
+
globalThis.Iterator.range(0, str.length, { step: 2 }),
|
|
310
|
+
i => parseInt(str.substring(i, i + 2), 16)
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (! (Uint8Array.fromBase64 instanceof Function)) {
|
|
317
|
+
Uint8Array.fromBase64 = function fromBase64(str, {
|
|
318
|
+
alphabet = 'base64',
|
|
319
|
+
lastChunkHandling = 'loose',
|
|
320
|
+
} = {}) {
|
|
321
|
+
if (typeof str !== 'string') {
|
|
322
|
+
throw new TypeError('expected input to be a string');
|
|
323
|
+
} else if (! ['base64', 'base64url'].includes(alphabet)) {
|
|
324
|
+
throw new TypeError('expected alphabet to be either "base64" or "base64url');
|
|
325
|
+
} else if (! ['loose', 'strict', 'stop-before-partial'].includes(lastChunkHandling)) {
|
|
326
|
+
throw new TypeError(`Invalid \`lastChunkHandling\`: "${lastChunkHandling}".`);
|
|
327
|
+
} else if (alphabet === 'base64') {
|
|
328
|
+
const lastChunkLength = str.length % 4;
|
|
329
|
+
|
|
330
|
+
if (lastChunkLength === 1) {
|
|
331
|
+
throw new TypeError('Invalid string length.');
|
|
332
|
+
} else if (lastChunkLength !== 0) {
|
|
333
|
+
switch(lastChunkHandling) {
|
|
334
|
+
case 'strict':
|
|
335
|
+
throw new SyntaxError('Missing padding.');
|
|
336
|
+
|
|
337
|
+
case 'loose':
|
|
338
|
+
return Uint8Array.fromBase64(str.padEnd(str.length + (4 - lastChunkLength), '='), {
|
|
339
|
+
alphabet: 'base64',
|
|
340
|
+
lastChunkHandling: 'strict',
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
case 'stop-before-partial':
|
|
344
|
+
return Uint8Array.fromBase64(str.slice(0, str.length - lastChunkLength), {
|
|
345
|
+
alphabet: 'base64',
|
|
346
|
+
lastChunkHandling: 'strict',
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Already checked for valid `lastChunkHandling`
|
|
350
|
+
}
|
|
351
|
+
} else {
|
|
352
|
+
return new TextEncoder().encode(atob(str));
|
|
353
|
+
}
|
|
354
|
+
} else {
|
|
355
|
+
return Uint8Array.fromBase64(
|
|
356
|
+
str.replaceAll('-', '+').replaceAll('_', '/'),
|
|
357
|
+
{ alphabet: 'base64', }
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// @todo Implement Uint8Array.fromBase64Into & Uint8Array.fromHexInto
|
|
364
|
+
// if (! (Uint8Array.fromBase64Into instanceof Function)) {
|
|
365
|
+
// Uint8Array.fromBase64Into = function fromBase64Into(str, target) {
|
|
366
|
+
// const { read, written } = new TextEncoder().encodeInto(atob(str), target);
|
|
367
|
+
// return { read, written, target };
|
|
368
|
+
// };
|
|
369
|
+
// }
|