quickwin 2026.5.2-3.145209
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/README.md +6 -0
- package/examples/pdf_preview.js +440 -0
- package/examples/pdf_preview.ts +470 -0
- package/examples/preact_demo.js +35 -0
- package/examples/preact_demo.tsx +49 -0
- package/examples/tray_demo.js +75 -0
- package/examples/tray_demo.tsx +79 -0
- package/lib/fetch.js +746 -0
- package/lib/fetch.ts +811 -0
- package/lib/polyfill.js +500 -0
- package/lib/polyfill.ts +454 -0
- package/lib/preact/hooks.js +287 -0
- package/lib/preact/hooks.ts +330 -0
- package/lib/preact/jsx-runtime.js +1 -0
- package/lib/preact/jsx-runtime.ts +2 -0
- package/lib/preact/jsx.d.ts +36 -0
- package/lib/preact/layout.js +153 -0
- package/lib/preact/layout.ts +183 -0
- package/lib/preact/preact.js +54 -0
- package/lib/preact/preact.ts +133 -0
- package/lib/preact/props.js +99 -0
- package/lib/preact/props.ts +119 -0
- package/lib/preact/render.js +320 -0
- package/lib/preact/render.ts +353 -0
- package/lib/websocket.js +540 -0
- package/lib/websocket.ts +574 -0
- package/package.json +32 -0
- package/quickwin.d.ts +657 -0
- package/test/add.wasm +0 -0
- package/test/complex.wasm +0 -0
- package/test/complex_imports.wasm +0 -0
- package/test/global_imports.wasm +0 -0
- package/test/import_func.wasm +0 -0
- package/test/imports.wasm +0 -0
- package/test/run.js +86 -0
- package/test/run.ts +90 -0
- package/test/sjlj.wasm +0 -0
- package/test/test_basic.js +7 -0
- package/test/test_basic.ts +9 -0
- package/test/test_brotli.js +48 -0
- package/test/test_brotli.ts +52 -0
- package/test/test_fetch_cache.js +131 -0
- package/test/test_fetch_cache.ts +141 -0
- package/test/test_ffi.js +157 -0
- package/test/test_ffi.ts +174 -0
- package/test/test_frame_encoding.js +128 -0
- package/test/test_frame_encoding.ts +132 -0
- package/test/test_helper.js +84 -0
- package/test/test_helper.ts +80 -0
- package/test/test_http_import.js +78 -0
- package/test/test_http_import.ts +74 -0
- package/test/test_mupdf_render.js +69 -0
- package/test/test_mupdf_render.ts +74 -0
- package/test/test_mupdf_twice.js +77 -0
- package/test/test_mupdf_twice.ts +81 -0
- package/test/test_mupdf_wasm.js +33 -0
- package/test/test_mupdf_wasm.ts +30 -0
- package/test/test_net_event.js +63 -0
- package/test/test_net_event.ts +59 -0
- package/test/test_net_fetch.js +153 -0
- package/test/test_net_fetch.ts +131 -0
- package/test/test_net_websocket.js +158 -0
- package/test/test_net_websocket.ts +144 -0
- package/test/test_polyfill.js +58 -0
- package/test/test_polyfill.ts +60 -0
- package/test/test_url.js +173 -0
- package/test/test_url.ts +183 -0
- package/test/test_wasm_basic.js +82 -0
- package/test/test_wasm_basic.ts +70 -0
- package/test/test_wasm_import_global.js +41 -0
- package/test/test_wasm_import_global.ts +39 -0
- package/test/test_wasm_sjlj.js +153 -0
- package/test/test_wasm_sjlj.ts +134 -0
- package/test/test_wasm_types.js +96 -0
- package/test/test_wasm_types.ts +108 -0
- package/test/types.wasm +0 -0
- package/tsconfig.json +18 -0
- package/vendor/mupdf-wasm/mupdf-wasm.d.ts +571 -0
- package/vendor/mupdf-wasm/mupdf-wasm.js +2749 -0
- package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
- package/vendor/mupdf-wasm/mupdf.d.ts +939 -0
- package/vendor/mupdf-wasm/mupdf.js +3317 -0
- package/win-mingw64.exe +0 -0
package/lib/polyfill.js
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import * as os from 'os';
|
|
2
|
+
// 1. window — triggers Emscripten browser path
|
|
3
|
+
if (typeof globalThis.window === 'undefined')
|
|
4
|
+
globalThis.window = globalThis;
|
|
5
|
+
// 2. TextDecoder polyfill
|
|
6
|
+
if (typeof globalThis.TextDecoder === 'undefined') {
|
|
7
|
+
globalThis.TextDecoder = class TextDecoder {
|
|
8
|
+
encoding = 'utf-8';
|
|
9
|
+
decode(buffer) {
|
|
10
|
+
if (!buffer)
|
|
11
|
+
return '';
|
|
12
|
+
const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
13
|
+
let out = '';
|
|
14
|
+
for (let i = 0; i < bytes.length;) {
|
|
15
|
+
const b = bytes[i++];
|
|
16
|
+
if (b < 0x80) {
|
|
17
|
+
out += String.fromCharCode(b);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
let c;
|
|
21
|
+
if (b < 0xE0) {
|
|
22
|
+
c = b & 0x1F;
|
|
23
|
+
c = (c << 6) | (bytes[i++] & 0x3F);
|
|
24
|
+
}
|
|
25
|
+
else if (b < 0xF0) {
|
|
26
|
+
c = b & 0x0F;
|
|
27
|
+
c = (c << 6) | (bytes[i++] & 0x3F);
|
|
28
|
+
c = (c << 6) | (bytes[i++] & 0x3F);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
c = b & 0x07;
|
|
32
|
+
c = (c << 6) | (bytes[i++] & 0x3F);
|
|
33
|
+
c = (c << 6) | (bytes[i++] & 0x3F);
|
|
34
|
+
c = (c << 6) | (bytes[i++] & 0x3F);
|
|
35
|
+
}
|
|
36
|
+
if (c <= 0xFFFF)
|
|
37
|
+
out += String.fromCharCode(c);
|
|
38
|
+
else {
|
|
39
|
+
c -= 0x10000;
|
|
40
|
+
out += String.fromCharCode(0xD800 | (c >> 10), 0xDC00 | (c & 0x3FF));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// 3. setTimeout polyfill — bridge to os.setTimeout
|
|
48
|
+
if (typeof globalThis.setTimeout === 'undefined') {
|
|
49
|
+
globalThis.setTimeout = (fn, ms, ...args) => {
|
|
50
|
+
return os.setTimeout(() => fn(...args), ms);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// 4. TextEncoder polyfill
|
|
54
|
+
if (typeof globalThis.TextEncoder === 'undefined') {
|
|
55
|
+
globalThis.TextEncoder = class TextEncoder {
|
|
56
|
+
encoding = 'utf-8';
|
|
57
|
+
encode(input) {
|
|
58
|
+
if (!input)
|
|
59
|
+
return new Uint8Array(0);
|
|
60
|
+
const bytes = [];
|
|
61
|
+
for (let i = 0; i < input.length; i++) {
|
|
62
|
+
let c = input.charCodeAt(i);
|
|
63
|
+
if (c < 0x80) {
|
|
64
|
+
bytes.push(c);
|
|
65
|
+
}
|
|
66
|
+
else if (c < 0x800) {
|
|
67
|
+
bytes.push(0xC0 | (c >> 6), 0x80 | (c & 0x3F));
|
|
68
|
+
}
|
|
69
|
+
else if (c < 0xD800 || c >= 0xE000) {
|
|
70
|
+
bytes.push(0xE0 | (c >> 12), 0x80 | ((c >> 6) & 0x3F), 0x80 | (c & 0x3F));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
i++;
|
|
74
|
+
const c2 = input.charCodeAt(i);
|
|
75
|
+
c = 0x10000 + ((c & 0x3FF) << 10) | (c2 & 0x3FF);
|
|
76
|
+
bytes.push(0xF0 | (c >> 18), 0x80 | ((c >> 12) & 0x3F), 0x80 | ((c >> 6) & 0x3F), 0x80 | (c & 0x3F));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return new Uint8Array(bytes);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// 5. console.error polyfill — QuickJS only has console.log
|
|
84
|
+
if (typeof console.error === 'undefined') {
|
|
85
|
+
console.error = (...args) => { console.log(...args); };
|
|
86
|
+
}
|
|
87
|
+
// ── SHA-1 ──
|
|
88
|
+
function sha1Bytes(bytes) {
|
|
89
|
+
const len = bytes.length;
|
|
90
|
+
const ml = len * 8;
|
|
91
|
+
bytes.push(0x80);
|
|
92
|
+
while (bytes.length % 64 !== 56) {
|
|
93
|
+
bytes.push(0);
|
|
94
|
+
}
|
|
95
|
+
bytes.push(0);
|
|
96
|
+
bytes.push(0);
|
|
97
|
+
bytes.push(0);
|
|
98
|
+
bytes.push(0);
|
|
99
|
+
bytes.push((ml >>> 24) & 0xFF);
|
|
100
|
+
bytes.push((ml >>> 16) & 0xFF);
|
|
101
|
+
bytes.push((ml >>> 8) & 0xFF);
|
|
102
|
+
bytes.push(ml & 0xFF);
|
|
103
|
+
let h0 = 0x67452301, h1 = 0xEFCDAB89;
|
|
104
|
+
let h2 = 0x98BADCFE, h3 = 0x10325476, h4 = 0xC3D2E1F0;
|
|
105
|
+
const rotl = (x, n) => ((x << n) | (x >>> (32 - n))) >>> 0;
|
|
106
|
+
for (let i = 0; i < bytes.length; i += 64) {
|
|
107
|
+
const w = [];
|
|
108
|
+
for (let t = 0; t < 16; t++) {
|
|
109
|
+
w[t] = (bytes[i + 4 * t] << 24) | (bytes[i + 4 * t + 1] << 16) |
|
|
110
|
+
(bytes[i + 4 * t + 2] << 8) | bytes[i + 4 * t + 3];
|
|
111
|
+
}
|
|
112
|
+
for (let t = 16; t < 80; t++) {
|
|
113
|
+
w[t] = rotl(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
|
|
114
|
+
}
|
|
115
|
+
let a = h0, b = h1, c = h2, d = h3, e = h4;
|
|
116
|
+
for (let t = 0; t < 80; t++) {
|
|
117
|
+
let f, k;
|
|
118
|
+
if (t < 20) {
|
|
119
|
+
f = (b & c) | (~b & d);
|
|
120
|
+
k = 0x5A827999;
|
|
121
|
+
}
|
|
122
|
+
else if (t < 40) {
|
|
123
|
+
f = b ^ c ^ d;
|
|
124
|
+
k = 0x6ED9EBA1;
|
|
125
|
+
}
|
|
126
|
+
else if (t < 60) {
|
|
127
|
+
f = (b & c) | (b & d) | (c & d);
|
|
128
|
+
k = 0x8F1BBCDC;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
f = b ^ c ^ d;
|
|
132
|
+
k = 0xCA62C1D6;
|
|
133
|
+
}
|
|
134
|
+
const temp = (rotl(a, 5) + f + e + k + w[t]) >>> 0;
|
|
135
|
+
e = d;
|
|
136
|
+
d = c;
|
|
137
|
+
c = rotl(b, 30);
|
|
138
|
+
b = a;
|
|
139
|
+
a = temp;
|
|
140
|
+
}
|
|
141
|
+
h0 = (h0 + a) >>> 0;
|
|
142
|
+
h1 = (h1 + b) >>> 0;
|
|
143
|
+
h2 = (h2 + c) >>> 0;
|
|
144
|
+
h3 = (h3 + d) >>> 0;
|
|
145
|
+
h4 = (h4 + e) >>> 0;
|
|
146
|
+
}
|
|
147
|
+
const result = new Uint8Array(20);
|
|
148
|
+
const w32 = (off, v) => {
|
|
149
|
+
result[off] = (v >>> 24) & 0xFF;
|
|
150
|
+
result[off + 1] = (v >>> 16) & 0xFF;
|
|
151
|
+
result[off + 2] = (v >>> 8) & 0xFF;
|
|
152
|
+
result[off + 3] = v & 0xFF;
|
|
153
|
+
};
|
|
154
|
+
w32(0, h0);
|
|
155
|
+
w32(4, h1);
|
|
156
|
+
w32(8, h2);
|
|
157
|
+
w32(12, h3);
|
|
158
|
+
w32(16, h4);
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
// ── Base64 ──
|
|
162
|
+
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
163
|
+
function b64Encode(data) {
|
|
164
|
+
let r = '';
|
|
165
|
+
for (let i = 0; i < data.length; i += 3) {
|
|
166
|
+
const b0 = data[i], b1 = i + 1 < data.length ? data[i + 1] : 0, b2 = i + 2 < data.length ? data[i + 2] : 0;
|
|
167
|
+
r += B64[b0 >> 2] + B64[((b0 & 3) << 4) | (b1 >> 4)];
|
|
168
|
+
r += i + 1 < data.length ? B64[((b1 & 15) << 2) | (b2 >> 6)] : '=';
|
|
169
|
+
r += i + 2 < data.length ? B64[b2 & 63] : '=';
|
|
170
|
+
}
|
|
171
|
+
return r;
|
|
172
|
+
}
|
|
173
|
+
function b64Decode(str) {
|
|
174
|
+
str = str.replace(/[^A-Za-z0-9+/=]/g, '');
|
|
175
|
+
const bytes = [];
|
|
176
|
+
for (let i = 0; i < str.length; i += 4) {
|
|
177
|
+
const c0 = B64.indexOf(str[i]), c1 = B64.indexOf(str[i + 1]);
|
|
178
|
+
const c2 = B64.indexOf(str[i + 2]), c3 = B64.indexOf(str[i + 3]);
|
|
179
|
+
bytes.push((c0 << 2) | (c1 >> 4));
|
|
180
|
+
if (c2 >= 0)
|
|
181
|
+
bytes.push(((c1 & 15) << 4) | (c2 >> 2));
|
|
182
|
+
if (c3 >= 0)
|
|
183
|
+
bytes.push(((c2 & 3) << 6) | c3);
|
|
184
|
+
}
|
|
185
|
+
return new Uint8Array(bytes);
|
|
186
|
+
}
|
|
187
|
+
// ── btoa / atob ──
|
|
188
|
+
if (typeof globalThis.btoa === 'undefined') {
|
|
189
|
+
globalThis.btoa = (data) => {
|
|
190
|
+
const bytes = new Uint8Array(data.length);
|
|
191
|
+
for (let i = 0; i < data.length; i++)
|
|
192
|
+
bytes[i] = data.charCodeAt(i) & 0xFF;
|
|
193
|
+
return b64Encode(bytes);
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
if (typeof globalThis.atob === 'undefined') {
|
|
197
|
+
globalThis.atob = (data) => {
|
|
198
|
+
const bytes = b64Decode(data);
|
|
199
|
+
let r = '';
|
|
200
|
+
for (let i = 0; i < bytes.length; i++)
|
|
201
|
+
r += String.fromCharCode(bytes[i]);
|
|
202
|
+
return r;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function _encode(s) { return encodeURIComponent(s); }
|
|
206
|
+
function _decode(s) {
|
|
207
|
+
try {
|
|
208
|
+
return decodeURIComponent(s.replace(/\+/g, ' '));
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return s;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function _normalizePath(path) {
|
|
215
|
+
if (!path)
|
|
216
|
+
return '/';
|
|
217
|
+
const parts = path.split('/');
|
|
218
|
+
const out = [];
|
|
219
|
+
let hasRoot = path[0] === '/';
|
|
220
|
+
if (hasRoot)
|
|
221
|
+
out.push('');
|
|
222
|
+
for (const p of parts) {
|
|
223
|
+
if (p === '' || p === '.')
|
|
224
|
+
continue;
|
|
225
|
+
if (p === '..') {
|
|
226
|
+
const last = out[out.length - 1];
|
|
227
|
+
if (last !== undefined && last !== '')
|
|
228
|
+
out.pop();
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
out.push(p);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (path.endsWith('/') && out[out.length - 1] !== '')
|
|
235
|
+
out.push('');
|
|
236
|
+
const result = out.join('/');
|
|
237
|
+
if (hasRoot && !result.startsWith('/'))
|
|
238
|
+
return '/' + result;
|
|
239
|
+
return result || '/';
|
|
240
|
+
}
|
|
241
|
+
function _parseURL(url) {
|
|
242
|
+
const r = { scheme: '', user: '', pass: '', host: '', port: '', path: '/', query: '', fragment: '' };
|
|
243
|
+
const fi = url.indexOf('#');
|
|
244
|
+
if (fi >= 0) {
|
|
245
|
+
r.fragment = url.slice(fi + 1);
|
|
246
|
+
url = url.slice(0, fi);
|
|
247
|
+
}
|
|
248
|
+
const qi = url.indexOf('?');
|
|
249
|
+
if (qi >= 0) {
|
|
250
|
+
r.query = url.slice(qi + 1);
|
|
251
|
+
url = url.slice(0, qi);
|
|
252
|
+
}
|
|
253
|
+
const sm = url.match(/^([a-zA-Z][a-zA-Z0-9+\-.]*):(.*)$/);
|
|
254
|
+
if (sm) {
|
|
255
|
+
r.scheme = sm[1].toLowerCase();
|
|
256
|
+
url = sm[2];
|
|
257
|
+
}
|
|
258
|
+
if (url.startsWith('//')) {
|
|
259
|
+
url = url.slice(2);
|
|
260
|
+
const si = url.indexOf('/');
|
|
261
|
+
let auth;
|
|
262
|
+
if (si < 0) {
|
|
263
|
+
auth = url;
|
|
264
|
+
url = '';
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
auth = url.slice(0, si);
|
|
268
|
+
url = url.slice(si);
|
|
269
|
+
}
|
|
270
|
+
const ai = auth.lastIndexOf('@');
|
|
271
|
+
if (ai >= 0) {
|
|
272
|
+
const ui = auth.slice(0, ai);
|
|
273
|
+
auth = auth.slice(ai + 1);
|
|
274
|
+
const ci = ui.indexOf(':');
|
|
275
|
+
if (ci >= 0) {
|
|
276
|
+
r.user = _decode(ui.slice(0, ci));
|
|
277
|
+
r.pass = _decode(ui.slice(ci + 1));
|
|
278
|
+
}
|
|
279
|
+
else
|
|
280
|
+
r.user = _decode(ui);
|
|
281
|
+
}
|
|
282
|
+
if (auth.startsWith('[')) {
|
|
283
|
+
const cb = auth.indexOf(']');
|
|
284
|
+
r.host = auth.slice(1, cb).toLowerCase();
|
|
285
|
+
const pp = auth.slice(cb + 1);
|
|
286
|
+
if (pp.startsWith(':'))
|
|
287
|
+
r.port = pp.slice(1);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const ci = auth.lastIndexOf(':');
|
|
291
|
+
if (ci >= 0 && ci === auth.lastIndexOf(':')) {
|
|
292
|
+
r.host = auth.slice(0, ci).toLowerCase();
|
|
293
|
+
r.port = auth.slice(ci + 1);
|
|
294
|
+
}
|
|
295
|
+
else
|
|
296
|
+
r.host = auth.toLowerCase();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
r.path = url;
|
|
300
|
+
if (r.host && !r.path.startsWith('/'))
|
|
301
|
+
r.path = '/' + r.path;
|
|
302
|
+
return r;
|
|
303
|
+
}
|
|
304
|
+
class URLSearchParamsImpl {
|
|
305
|
+
_list = [];
|
|
306
|
+
constructor(init) {
|
|
307
|
+
if (typeof init === 'string') {
|
|
308
|
+
const s = init.startsWith('?') ? init.slice(1) : init;
|
|
309
|
+
if (!s)
|
|
310
|
+
return;
|
|
311
|
+
for (const p of s.split('&')) {
|
|
312
|
+
const eq = p.indexOf('=');
|
|
313
|
+
if (eq < 0) {
|
|
314
|
+
this._list.push([_decode(p), '']);
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
this._list.push([_decode(p.slice(0, eq)), _decode(p.slice(eq + 1))]);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else if (init) {
|
|
321
|
+
if (Array.isArray(init))
|
|
322
|
+
for (const [k, v] of init)
|
|
323
|
+
this._list.push([String(k), String(v)]);
|
|
324
|
+
else
|
|
325
|
+
for (const k of Object.keys(init))
|
|
326
|
+
this._list.push([k, String(init[k])]);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
append(key, value) { this._list.push([key, value]); }
|
|
330
|
+
delete(key) { this._list = this._list.filter(([k]) => k !== key); }
|
|
331
|
+
get(key) { for (const [k, v] of this._list)
|
|
332
|
+
if (k === key)
|
|
333
|
+
return v; return null; }
|
|
334
|
+
getAll(key) { return this._list.filter(([k]) => k === key).map(([, v]) => v); }
|
|
335
|
+
has(key) { return this._list.some(([k]) => k === key); }
|
|
336
|
+
set(key, value) {
|
|
337
|
+
let f = false;
|
|
338
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
339
|
+
if (this._list[i][0] === key) {
|
|
340
|
+
if (!f) {
|
|
341
|
+
this._list[i][1] = value;
|
|
342
|
+
f = true;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
this._list.splice(i, 1);
|
|
346
|
+
i--;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (!f)
|
|
351
|
+
this._list.push([key, value]);
|
|
352
|
+
}
|
|
353
|
+
sort() { this._list.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0); }
|
|
354
|
+
forEach(fn) { for (const [k, v] of this._list)
|
|
355
|
+
fn(v, k); }
|
|
356
|
+
*keys() { for (const [k] of this._list)
|
|
357
|
+
yield k; }
|
|
358
|
+
*values() { for (const [, v] of this._list)
|
|
359
|
+
yield v; }
|
|
360
|
+
*entries() { for (const item of this._list)
|
|
361
|
+
yield [item[0], item[1]]; }
|
|
362
|
+
*[Symbol.iterator]() { for (const item of this._list)
|
|
363
|
+
yield item; }
|
|
364
|
+
toString() { return this._list.map(([k, v]) => _encode(k) + '=' + _encode(v)).join('&'); }
|
|
365
|
+
get size() { return this._list.length; }
|
|
366
|
+
}
|
|
367
|
+
if (typeof globalThis.URLSearchParams === 'undefined') {
|
|
368
|
+
globalThis.URLSearchParams = URLSearchParamsImpl;
|
|
369
|
+
}
|
|
370
|
+
class URLImpl {
|
|
371
|
+
_scheme = '';
|
|
372
|
+
_username = '';
|
|
373
|
+
_password = '';
|
|
374
|
+
_hostname = '';
|
|
375
|
+
_port = '';
|
|
376
|
+
_pathname = '/';
|
|
377
|
+
_query = '';
|
|
378
|
+
_fragment = '';
|
|
379
|
+
_searchParams = new URLSearchParamsImpl();
|
|
380
|
+
constructor(url, base) {
|
|
381
|
+
let p = _parseURL(url);
|
|
382
|
+
if (p.scheme) {
|
|
383
|
+
this._apply(p);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (base === undefined)
|
|
387
|
+
throw new TypeError('Invalid URL');
|
|
388
|
+
const b = new URLImpl(base);
|
|
389
|
+
if (p.host) {
|
|
390
|
+
p.scheme = b._scheme;
|
|
391
|
+
this._apply(p);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (!p.path && !p.query) {
|
|
395
|
+
this._apply({
|
|
396
|
+
scheme: b._scheme, user: b._username, pass: b._password,
|
|
397
|
+
host: b._hostname, port: b._port,
|
|
398
|
+
path: b._pathname, query: b._query, fragment: p.fragment || ''
|
|
399
|
+
});
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
p.scheme = b._scheme;
|
|
403
|
+
if (!p.user)
|
|
404
|
+
p.user = b._username;
|
|
405
|
+
if (!p.pass)
|
|
406
|
+
p.pass = b._password;
|
|
407
|
+
if (!p.host)
|
|
408
|
+
p.host = b._hostname;
|
|
409
|
+
if (!p.port)
|
|
410
|
+
p.port = b._port;
|
|
411
|
+
if (!p.fragment)
|
|
412
|
+
p.fragment = '';
|
|
413
|
+
if (p.path && !p.path.startsWith('/')) {
|
|
414
|
+
const bd = b._pathname.substring(0, b._pathname.lastIndexOf('/') + 1);
|
|
415
|
+
p.path = _normalizePath(bd + p.path);
|
|
416
|
+
}
|
|
417
|
+
else if (!p.path) {
|
|
418
|
+
p.path = b._pathname;
|
|
419
|
+
if (!p.query)
|
|
420
|
+
p.query = b._query;
|
|
421
|
+
}
|
|
422
|
+
this._apply(p);
|
|
423
|
+
}
|
|
424
|
+
_apply(p) {
|
|
425
|
+
this._scheme = p.scheme;
|
|
426
|
+
this._username = p.user;
|
|
427
|
+
this._password = p.pass;
|
|
428
|
+
this._hostname = p.host;
|
|
429
|
+
this._port = p.port;
|
|
430
|
+
this._pathname = _normalizePath(p.path || '/');
|
|
431
|
+
this._query = p.query;
|
|
432
|
+
this._fragment = p.fragment;
|
|
433
|
+
this._searchParams = new URLSearchParamsImpl(this._query);
|
|
434
|
+
}
|
|
435
|
+
get href() { return this.toString(); }
|
|
436
|
+
get protocol() { return this._scheme + ':'; }
|
|
437
|
+
get hostname() { return this._hostname; }
|
|
438
|
+
get port() { return this._port; }
|
|
439
|
+
get pathname() { return this._pathname; }
|
|
440
|
+
get search() { return this._query ? '?' + this._query : ''; }
|
|
441
|
+
get hash() { return this._fragment ? '#' + this._fragment : ''; }
|
|
442
|
+
get host() {
|
|
443
|
+
const h = this._hostname;
|
|
444
|
+
const ipv6 = h.includes(':');
|
|
445
|
+
return (ipv6 ? '[' + h + ']' : h) + (this._port ? ':' + this._port : '');
|
|
446
|
+
}
|
|
447
|
+
get origin() {
|
|
448
|
+
const h = this._hostname;
|
|
449
|
+
const ipv6 = h.includes(':');
|
|
450
|
+
return this._scheme + '://' + (ipv6 ? '[' + h + ']' : h) + (this._port ? ':' + this._port : '');
|
|
451
|
+
}
|
|
452
|
+
get username() { return this._username; }
|
|
453
|
+
get password() { return this._password; }
|
|
454
|
+
get searchParams() { return this._searchParams; }
|
|
455
|
+
toString() {
|
|
456
|
+
let s = this._scheme + ':';
|
|
457
|
+
const special = ['http', 'https', 'ws', 'wss', 'ftp', 'file'];
|
|
458
|
+
if (this._hostname || (special.includes(this._scheme) && this._pathname.startsWith('/'))) {
|
|
459
|
+
s += '//';
|
|
460
|
+
if (this._username) {
|
|
461
|
+
s += _encode(this._username);
|
|
462
|
+
if (this._password)
|
|
463
|
+
s += ':' + _encode(this._password);
|
|
464
|
+
s += '@';
|
|
465
|
+
}
|
|
466
|
+
s += this._hostname;
|
|
467
|
+
if (this._port)
|
|
468
|
+
s += ':' + this._port;
|
|
469
|
+
}
|
|
470
|
+
s += this._pathname;
|
|
471
|
+
if (this._query)
|
|
472
|
+
s += '?' + this._query;
|
|
473
|
+
if (this._fragment)
|
|
474
|
+
s += '#' + this._fragment;
|
|
475
|
+
return s;
|
|
476
|
+
}
|
|
477
|
+
toJSON() { return this.toString(); }
|
|
478
|
+
}
|
|
479
|
+
if (typeof globalThis.URL === 'undefined') {
|
|
480
|
+
globalThis.URL = URLImpl;
|
|
481
|
+
}
|
|
482
|
+
if (typeof globalThis.crypto === 'undefined') {
|
|
483
|
+
globalThis.crypto = {
|
|
484
|
+
getRandomValues: (array) => {
|
|
485
|
+
const view = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
|
|
486
|
+
for (let i = 0; i < view.length; i++)
|
|
487
|
+
view[i] = (Math.random() * 256) | 0;
|
|
488
|
+
return array;
|
|
489
|
+
},
|
|
490
|
+
subtle: {
|
|
491
|
+
digest: (algorithm, data) => {
|
|
492
|
+
if (algorithm.toUpperCase() !== 'SHA-1')
|
|
493
|
+
return Promise.reject(new Error('Digest: ' + algorithm + ' not supported'));
|
|
494
|
+
const bytes = data instanceof Uint8Array ? Array.from(data) : Array.from(new Uint8Array(data));
|
|
495
|
+
const hash = sha1Bytes(bytes);
|
|
496
|
+
return Promise.resolve(hash.buffer);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
}
|