aberdeen 1.17.0 → 2.0.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/src/aberdeen.d.ts +928 -944
- package/dist/src/aberdeen.js +1693 -1704
- package/dist/src/aberdeen.js.map +3 -3
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +10 -0
- package/dist/src/prediction.d.ts +7 -4
- package/dist/src/prediction.js +18 -23
- package/dist/src/prediction.js.map +3 -3
- package/dist/src/route.d.ts +112 -99
- package/dist/src/route.js +254 -254
- package/dist/src/route.js.map +3 -3
- package/dist/src/server-dom.d.ts +158 -0
- package/dist/src/server-dom.js +458 -0
- package/dist/src/server-dom.js.map +10 -0
- package/dist/src/server.d.ts +55 -0
- package/dist/src/server.js +25 -0
- package/dist/src/server.js.map +10 -0
- package/dist/src/transitions.js +7 -4
- package/dist/src/transitions.js.map +3 -3
- package/dist/tests/environment.d.ts +24 -0
- package/dist/tests/{fakedom.js → environment.js} +239 -288
- package/dist/tests/environment.js.map +11 -0
- package/dist/tests/helpers.d.ts +15 -3
- package/dist/tests/helpers.js +277 -306
- package/dist/tests/helpers.js.map +6 -5
- package/dist-docs/Tutorial/index.html +30 -30
- package/dist-docs/aberdeen/Aberdeen/index.html +350 -0
- package/dist-docs/aberdeen/InitOptions/index.html +4 -0
- package/dist-docs/aberdeen/KeyToString/index.html +2 -0
- package/dist-docs/aberdeen/PromiseProxy/index.html +6 -6
- package/dist-docs/aberdeen/SortKeyType/index.html +2 -0
- package/dist-docs/aberdeen/TargetType/index.html +2 -0
- package/dist-docs/aberdeen/ValueRef/index.html +2 -0
- package/dist-docs/aberdeen/WindowLike/index.html +5 -0
- package/dist-docs/aberdeen/{clone → createA}/index.html +10 -5
- package/dist-docs/aberdeen/index.html +13 -54
- package/dist-docs/assets/aberdeen/aberdeen.d.ts +928 -944
- package/dist-docs/assets/aberdeen/aberdeen.js +1693 -1704
- package/dist-docs/assets/aberdeen/aberdeen.js.map +3 -3
- package/dist-docs/assets/aberdeen/index.d.ts +12 -0
- package/dist-docs/assets/aberdeen/index.js +11 -0
- package/dist-docs/assets/aberdeen/index.js.map +10 -0
- package/dist-docs/assets/aberdeen/prediction.d.ts +7 -4
- package/dist-docs/assets/aberdeen/prediction.js +18 -23
- package/dist-docs/assets/aberdeen/prediction.js.map +3 -3
- package/dist-docs/assets/aberdeen/route.d.ts +112 -99
- package/dist-docs/assets/aberdeen/route.js +254 -254
- package/dist-docs/assets/aberdeen/route.js.map +3 -3
- package/dist-docs/assets/aberdeen/server-dom.d.ts +158 -0
- package/dist-docs/assets/aberdeen/server-dom.js +458 -0
- package/dist-docs/assets/aberdeen/server-dom.js.map +10 -0
- package/dist-docs/assets/aberdeen/server.d.ts +55 -0
- package/dist-docs/assets/aberdeen/server.js +25 -0
- package/dist-docs/assets/aberdeen/server.js.map +10 -0
- package/dist-docs/assets/aberdeen/transitions.js +7 -4
- package/dist-docs/assets/aberdeen/transitions.js.map +3 -3
- package/dist-docs/assets/navigation.js +1 -1
- package/dist-docs/assets/search.js +1 -1
- package/dist-docs/dispatcher/Dispatcher/index.html +5 -6
- package/dist-docs/dispatcher/MATCH_FAILED/index.html +2 -2
- package/dist-docs/dispatcher/MATCH_REST/index.html +2 -2
- package/dist-docs/dispatcher/index.html +2 -2
- package/dist-docs/hierarchy.html +1 -1
- package/dist-docs/index-1/index.html +2 -0
- package/dist-docs/index.html +2 -2
- package/dist-docs/media/CHANGELOG.md +14 -2
- package/dist-docs/modules.html +1 -1
- package/dist-docs/prediction/applyCanon/index.html +4 -3
- package/dist-docs/prediction/applyPrediction/index.html +4 -3
- package/dist-docs/prediction/index.html +2 -2
- package/dist-docs/route/Route/index.html +9 -9
- package/dist-docs/route/RouteApi/index.html +60 -0
- package/dist-docs/route/index.html +6 -15
- package/dist-docs/route/init/index.html +5 -0
- package/dist-docs/server/RenderToStringOptions/index.html +6 -0
- package/dist-docs/server/RenderToStringResult/index.html +6 -0
- package/dist-docs/server/index.html +4 -0
- package/dist-docs/server/renderToString/index.html +6 -0
- package/dist-docs/sitemap.xml +51 -155
- package/dist-docs/transitions/grow/index.html +2 -2
- package/dist-docs/transitions/index.html +2 -2
- package/dist-docs/transitions/shrink/index.html +2 -2
- package/package.json +17 -7
- package/skill/SKILL.md +28 -28
- package/skill/aberdeen.md +471 -3448
- package/skill/dispatcher.md +6 -16
- package/skill/prediction.md +17 -5
- package/skill/route.md +95 -77
- package/skill/transitions.md +3 -3
- package/src/aberdeen.ts +1226 -740
- package/src/index.ts +13 -0
- package/src/prediction.ts +25 -24
- package/src/route.ts +192 -142
- package/src/server-dom.ts +508 -0
- package/src/server.ts +74 -0
- package/src/transitions.ts +9 -3
- package/dist/tests/fakedom.d.ts +0 -9
- package/dist/tests/fakedom.js.map +0 -10
- package/dist-docs/aberdeen/A/index.html +0 -115
- package/dist-docs/aberdeen/CUSTOM_DUMP/index.html +0 -7
- package/dist-docs/aberdeen/NO_COPY/index.html +0 -2
- package/dist-docs/aberdeen/OPAQUE/index.html +0 -12
- package/dist-docs/aberdeen/clean/index.html +0 -11
- package/dist-docs/aberdeen/copy/index.html +0 -22
- package/dist-docs/aberdeen/count/index.html +0 -7
- package/dist-docs/aberdeen/cssVars/index.html +0 -11
- package/dist-docs/aberdeen/darkMode/index.html +0 -9
- package/dist-docs/aberdeen/default/index.html +0 -341
- package/dist-docs/aberdeen/derive/index.html +0 -18
- package/dist-docs/aberdeen/disableCreateDestroy/index.html +0 -6
- package/dist-docs/aberdeen/dump/index.html +0 -11
- package/dist-docs/aberdeen/insertCss/index.html +0 -30
- package/dist-docs/aberdeen/insertGlobalCss/index.html +0 -19
- package/dist-docs/aberdeen/invertString/index.html +0 -13
- package/dist-docs/aberdeen/isEmpty/index.html +0 -12
- package/dist-docs/aberdeen/map/index.html +0 -26
- package/dist-docs/aberdeen/merge/index.html +0 -11
- package/dist-docs/aberdeen/mount/index.html +0 -17
- package/dist-docs/aberdeen/multiMap/index.html +0 -28
- package/dist-docs/aberdeen/onEach/index.html +0 -19
- package/dist-docs/aberdeen/partition/index.html +0 -36
- package/dist-docs/aberdeen/peek/index.html +0 -40
- package/dist-docs/aberdeen/proxy/index.html +0 -35
- package/dist-docs/aberdeen/ref/index.html +0 -13
- package/dist-docs/aberdeen/runQueue/index.html +0 -13
- package/dist-docs/aberdeen/setErrorHandler/index.html +0 -16
- package/dist-docs/aberdeen/setSpacingCssVars/index.html +0 -8
- package/dist-docs/aberdeen/unmountAll/index.html +0 -5
- package/dist-docs/aberdeen/unproxy/index.html +0 -11
- package/dist-docs/route/back/index.html +0 -4
- package/dist-docs/route/current/index.html +0 -2
- package/dist-docs/route/go/index.html +0 -14
- package/dist-docs/route/interceptLinks/index.html +0 -8
- package/dist-docs/route/matchCurrent/index.html +0 -10
- package/dist-docs/route/persistScroll/index.html +0 -6
- package/dist-docs/route/push/index.html +0 -6
- package/dist-docs/route/setLog/index.html +0 -3
- package/dist-docs/route/up/index.html +0 -5
package/dist/tests/helpers.js
CHANGED
|
@@ -1,29 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
function __exportSetter(name, newValue) {
|
|
5
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
-
}
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, {
|
|
10
|
-
get: all[name],
|
|
11
|
-
enumerable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
set: __exportSetter.bind(all, name)
|
|
14
|
-
});
|
|
15
|
-
};
|
|
2
|
+
// tests/environment.ts
|
|
3
|
+
import { createA } from "aberdeen";
|
|
16
4
|
|
|
17
|
-
//
|
|
18
|
-
var exports_fakedom = {};
|
|
19
|
-
__export(exports_fakedom, {
|
|
20
|
-
setMediaQuery: () => setMediaQuery,
|
|
21
|
-
resetCounts: () => resetCounts,
|
|
22
|
-
resetBrowserState: () => resetBrowserState,
|
|
23
|
-
passTime: () => passTime,
|
|
24
|
-
getCounts: () => getCounts,
|
|
25
|
-
clearBody: () => clearBody
|
|
26
|
-
});
|
|
5
|
+
// src/server-dom.ts
|
|
27
6
|
var newCount = 0;
|
|
28
7
|
var changeCount = 0;
|
|
29
8
|
var resetCounts = function() {
|
|
@@ -32,13 +11,11 @@ var resetCounts = function() {
|
|
|
32
11
|
var getCounts = function() {
|
|
33
12
|
return { new: newCount, changed: changeCount };
|
|
34
13
|
};
|
|
35
|
-
var clearBody = function() {
|
|
36
|
-
document2.body.childNodes.length = 0;
|
|
37
|
-
};
|
|
38
14
|
|
|
39
15
|
class Node {
|
|
40
16
|
parentNode = null;
|
|
41
17
|
childNodes = [];
|
|
18
|
+
ownerDocument = null;
|
|
42
19
|
get nextSibling() {
|
|
43
20
|
return this.getSibling(1);
|
|
44
21
|
}
|
|
@@ -56,13 +33,15 @@ class Node {
|
|
|
56
33
|
}
|
|
57
34
|
}
|
|
58
35
|
|
|
59
|
-
class
|
|
36
|
+
class Element extends Node {
|
|
60
37
|
tagName;
|
|
61
38
|
namespaceURI;
|
|
62
39
|
_style = {};
|
|
63
40
|
attrs = {};
|
|
64
41
|
events = {};
|
|
65
42
|
_classList;
|
|
43
|
+
_scrollTop;
|
|
44
|
+
_scrollLeft;
|
|
66
45
|
constructor(tag, namespaceURI) {
|
|
67
46
|
super();
|
|
68
47
|
this.tagName = tag;
|
|
@@ -141,7 +120,7 @@ class Element2 extends Node {
|
|
|
141
120
|
});
|
|
142
121
|
}
|
|
143
122
|
get parentElement() {
|
|
144
|
-
if (this.parentNode instanceof
|
|
123
|
+
if (this.parentNode instanceof Element)
|
|
145
124
|
return this.parentNode;
|
|
146
125
|
return;
|
|
147
126
|
}
|
|
@@ -176,7 +155,7 @@ class Element2 extends Node {
|
|
|
176
155
|
}
|
|
177
156
|
_querySelectorAllRecursive(selector, results) {
|
|
178
157
|
for (const child of this.childNodes) {
|
|
179
|
-
if (child instanceof
|
|
158
|
+
if (child instanceof Element) {
|
|
180
159
|
if (child.tagName === selector) {
|
|
181
160
|
results.push(child);
|
|
182
161
|
}
|
|
@@ -187,7 +166,7 @@ class Element2 extends Node {
|
|
|
187
166
|
set innerHTML(html) {
|
|
188
167
|
this.childNodes = [];
|
|
189
168
|
if (html) {
|
|
190
|
-
let n = new
|
|
169
|
+
let n = new Element("fake-emulated-html");
|
|
191
170
|
n.textContent = html;
|
|
192
171
|
this.appendChild(n);
|
|
193
172
|
}
|
|
@@ -227,8 +206,6 @@ class Element2 extends Node {
|
|
|
227
206
|
set scrollLeft(value) {
|
|
228
207
|
this._scrollLeft = value;
|
|
229
208
|
}
|
|
230
|
-
_scrollTop;
|
|
231
|
-
_scrollLeft;
|
|
232
209
|
toString() {
|
|
233
210
|
let arr = [];
|
|
234
211
|
for (let [symbol, items, toKebab] of [["=", this.attrs, false], ["->", this, false], [":", this.style, true]]) {
|
|
@@ -284,7 +261,7 @@ class Element2 extends Node {
|
|
|
284
261
|
if (this.attrs.id === id)
|
|
285
262
|
return this;
|
|
286
263
|
for (let child of this.childNodes) {
|
|
287
|
-
if (child instanceof
|
|
264
|
+
if (child instanceof Element) {
|
|
288
265
|
let el = child.getElementById(id);
|
|
289
266
|
if (el)
|
|
290
267
|
return el;
|
|
@@ -293,225 +270,7 @@ class Element2 extends Node {
|
|
|
293
270
|
return;
|
|
294
271
|
}
|
|
295
272
|
}
|
|
296
|
-
var
|
|
297
|
-
createElement: (tag) => new Element2(tag, "http://www.w3.org/1999/xhtml"),
|
|
298
|
-
createElementNS: (namespaceURI, tag) => new Element2(tag, namespaceURI),
|
|
299
|
-
createTextNode: (text) => new TextNode(text),
|
|
300
|
-
head: new Element2("head", "http://www.w3.org/1999/xhtml"),
|
|
301
|
-
body: new Element2("body", "http://www.w3.org/1999/xhtml")
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
class FakeLocation {
|
|
305
|
-
_href = "http://localhost/";
|
|
306
|
-
get href() {
|
|
307
|
-
return this._href;
|
|
308
|
-
}
|
|
309
|
-
set href(value) {
|
|
310
|
-
if (value.startsWith("/")) {
|
|
311
|
-
const currentUrl = new URL(this._href);
|
|
312
|
-
this._href = `${currentUrl.protocol}//${currentUrl.host}${value}`;
|
|
313
|
-
} else {
|
|
314
|
-
this._href = value;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
get host() {
|
|
318
|
-
const url = new URL(this._href);
|
|
319
|
-
return url.host;
|
|
320
|
-
}
|
|
321
|
-
get pathname() {
|
|
322
|
-
const url = new URL(this._href);
|
|
323
|
-
return url.pathname;
|
|
324
|
-
}
|
|
325
|
-
set pathname(value) {
|
|
326
|
-
const url = new URL(this._href);
|
|
327
|
-
url.pathname = value;
|
|
328
|
-
this._href = url.href;
|
|
329
|
-
}
|
|
330
|
-
get search() {
|
|
331
|
-
const url = new URL(this._href);
|
|
332
|
-
return url.search;
|
|
333
|
-
}
|
|
334
|
-
set search(value) {
|
|
335
|
-
const url = new URL(this._href);
|
|
336
|
-
url.search = value;
|
|
337
|
-
this._href = url.href;
|
|
338
|
-
}
|
|
339
|
-
get hash() {
|
|
340
|
-
const url = new URL(this._href);
|
|
341
|
-
return url.hash;
|
|
342
|
-
}
|
|
343
|
-
set hash(value) {
|
|
344
|
-
const url = new URL(this._href);
|
|
345
|
-
url.hash = value;
|
|
346
|
-
this._href = url.href;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
class FakeHistory {
|
|
351
|
-
_state = null;
|
|
352
|
-
_entries = [];
|
|
353
|
-
_index = 0;
|
|
354
|
-
constructor() {
|
|
355
|
-
this._entries = [{ url: location.href, state: null }];
|
|
356
|
-
}
|
|
357
|
-
get state() {
|
|
358
|
-
return this._state;
|
|
359
|
-
}
|
|
360
|
-
pushState(state, title, url) {
|
|
361
|
-
this._entries = this._entries.slice(0, this._index + 1);
|
|
362
|
-
this._entries.push({ url, state });
|
|
363
|
-
this._index = this._entries.length - 1;
|
|
364
|
-
this._state = state;
|
|
365
|
-
location.href = url;
|
|
366
|
-
}
|
|
367
|
-
replaceState(state, title, url) {
|
|
368
|
-
this._entries[this._index] = { url, state };
|
|
369
|
-
this._state = state;
|
|
370
|
-
location.href = url;
|
|
371
|
-
}
|
|
372
|
-
go(delta) {
|
|
373
|
-
const newIndex = this._index + delta;
|
|
374
|
-
if (newIndex >= 0 && newIndex < this._entries.length) {
|
|
375
|
-
this._index = newIndex;
|
|
376
|
-
const entry = this._entries[this._index];
|
|
377
|
-
this._state = entry.state;
|
|
378
|
-
location.href = entry.url;
|
|
379
|
-
setTimeout(() => {
|
|
380
|
-
const event = {
|
|
381
|
-
type: "popstate",
|
|
382
|
-
state: this._state,
|
|
383
|
-
target: window,
|
|
384
|
-
preventDefault: () => {},
|
|
385
|
-
stopPropagation: () => {}
|
|
386
|
-
};
|
|
387
|
-
window.dispatchEvent(event);
|
|
388
|
-
}, 0);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
back() {
|
|
392
|
-
this.go(-1);
|
|
393
|
-
}
|
|
394
|
-
forward() {
|
|
395
|
-
this.go(1);
|
|
396
|
-
}
|
|
397
|
-
_reset() {
|
|
398
|
-
this._state = null;
|
|
399
|
-
this._entries = [{ url: location.href, state: null }];
|
|
400
|
-
this._index = 0;
|
|
401
|
-
}
|
|
402
|
-
_getLength() {
|
|
403
|
-
return this._entries.length;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
class FakeWindow {
|
|
408
|
-
_listeners = {};
|
|
409
|
-
addEventListener(type, listener) {
|
|
410
|
-
if (!this._listeners[type]) {
|
|
411
|
-
this._listeners[type] = new Set;
|
|
412
|
-
}
|
|
413
|
-
this._listeners[type].add(listener);
|
|
414
|
-
}
|
|
415
|
-
removeEventListener(type, listener) {
|
|
416
|
-
if (this._listeners[type]) {
|
|
417
|
-
this._listeners[type].delete(listener);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
dispatchEvent(event) {
|
|
421
|
-
const listeners = this._listeners[event.type];
|
|
422
|
-
if (listeners) {
|
|
423
|
-
for (const listener of listeners) {
|
|
424
|
-
listener.call(this, event);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
matchMedia(query) {
|
|
429
|
-
if (!mediaQueries.has(query)) {
|
|
430
|
-
mediaQueries.set(query, new MediaQueryList(query));
|
|
431
|
-
}
|
|
432
|
-
return mediaQueries.get(query);
|
|
433
|
-
}
|
|
434
|
-
_reset() {
|
|
435
|
-
this._listeners = {};
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
var location = new FakeLocation;
|
|
439
|
-
var history = new FakeHistory;
|
|
440
|
-
var window = new FakeWindow;
|
|
441
|
-
var resetBrowserState = function() {
|
|
442
|
-
location.href = "http://localhost/";
|
|
443
|
-
history._reset();
|
|
444
|
-
};
|
|
445
|
-
var timeouts = [];
|
|
446
|
-
var currentTime = 0;
|
|
447
|
-
var deferredErrors = [];
|
|
448
|
-
var realSetTimeout = global.setTimeout;
|
|
449
|
-
var realClearTimeout = global.clearTimeout;
|
|
450
|
-
function fireItem(item) {
|
|
451
|
-
const idx = timeouts.indexOf(item);
|
|
452
|
-
if (idx < 0)
|
|
453
|
-
return;
|
|
454
|
-
timeouts.splice(idx, 1);
|
|
455
|
-
if (item.time > currentTime)
|
|
456
|
-
currentTime = item.time;
|
|
457
|
-
item.func();
|
|
458
|
-
}
|
|
459
|
-
var setTimeout = function(func, time) {
|
|
460
|
-
const item = { func, time: time + currentTime, realId: undefined };
|
|
461
|
-
item.realId = realSetTimeout(() => {
|
|
462
|
-
try {
|
|
463
|
-
fireItem(item);
|
|
464
|
-
} catch (e) {
|
|
465
|
-
deferredErrors.push(e);
|
|
466
|
-
}
|
|
467
|
-
}, time);
|
|
468
|
-
timeouts.push(item);
|
|
469
|
-
};
|
|
470
|
-
var queueMicrotask = function(func) {
|
|
471
|
-
const item = { func, time: 0, realId: undefined };
|
|
472
|
-
item.realId = realSetTimeout(() => {
|
|
473
|
-
try {
|
|
474
|
-
fireItem(item);
|
|
475
|
-
} catch (e) {
|
|
476
|
-
deferredErrors.push(e);
|
|
477
|
-
}
|
|
478
|
-
}, 0);
|
|
479
|
-
timeouts.push(item);
|
|
480
|
-
};
|
|
481
|
-
var passTime = async function(ms = 0) {
|
|
482
|
-
let targetTime = currentTime + ms;
|
|
483
|
-
while (true) {
|
|
484
|
-
await new Promise((resolve) => realSetTimeout(resolve, 0));
|
|
485
|
-
if (deferredErrors.length) {
|
|
486
|
-
const err = deferredErrors.shift();
|
|
487
|
-
throw err;
|
|
488
|
-
}
|
|
489
|
-
if (!timeouts.length) {
|
|
490
|
-
let settled = false;
|
|
491
|
-
for (let r = 0;r < 5 && !settled; r++) {
|
|
492
|
-
await new Promise((resolve) => realSetTimeout(resolve, 0));
|
|
493
|
-
settled = timeouts.length > 0;
|
|
494
|
-
}
|
|
495
|
-
if (!settled)
|
|
496
|
-
break;
|
|
497
|
-
}
|
|
498
|
-
let smallestIdx = 0;
|
|
499
|
-
for (let idx = 1;idx < timeouts.length; idx++) {
|
|
500
|
-
if (timeouts[idx].time < timeouts[smallestIdx].time)
|
|
501
|
-
smallestIdx = idx;
|
|
502
|
-
}
|
|
503
|
-
let item = timeouts[smallestIdx];
|
|
504
|
-
if (item.time > targetTime)
|
|
505
|
-
break;
|
|
506
|
-
timeouts.splice(smallestIdx, 1);
|
|
507
|
-
realClearTimeout(item.realId);
|
|
508
|
-
if (item.time > currentTime)
|
|
509
|
-
currentTime = item.time;
|
|
510
|
-
await item.func();
|
|
511
|
-
}
|
|
512
|
-
currentTime = targetTime;
|
|
513
|
-
};
|
|
514
|
-
var IGNORE_OUTPUT = new Set("tagName-> attrs-> events-> childNodes-> parentNode-> class= namespaceURI->".split(" "));
|
|
273
|
+
var IGNORE_OUTPUT = new Set("tagName-> attrs-> events-> childNodes-> parentNode-> class= namespaceURI-> ownerDocument->".split(" "));
|
|
515
274
|
|
|
516
275
|
class TextNode extends Node {
|
|
517
276
|
textContent;
|
|
@@ -527,52 +286,271 @@ class TextNode extends Node {
|
|
|
527
286
|
this.parentNode?.removeChild(this);
|
|
528
287
|
}
|
|
529
288
|
}
|
|
530
|
-
|
|
531
|
-
|
|
289
|
+
var XHTML_NS = "http://www.w3.org/1999/xhtml";
|
|
290
|
+
function createDocument() {
|
|
291
|
+
const doc = {
|
|
292
|
+
createElement: (tag) => own(new Element(tag, XHTML_NS)),
|
|
293
|
+
createElementNS: (namespaceURI, tag) => own(new Element(tag, namespaceURI)),
|
|
294
|
+
createTextNode: (text) => own(new TextNode(text)),
|
|
295
|
+
head: new Element("head", XHTML_NS),
|
|
296
|
+
body: new Element("body", XHTML_NS),
|
|
297
|
+
defaultView: null
|
|
298
|
+
};
|
|
299
|
+
function own(node) {
|
|
300
|
+
node.ownerDocument = doc;
|
|
301
|
+
return node;
|
|
302
|
+
}
|
|
303
|
+
own(doc.head);
|
|
304
|
+
own(doc.body);
|
|
305
|
+
return doc;
|
|
532
306
|
}
|
|
307
|
+
var VOID_ELEMENTS = new Set("area base br col embed hr img input link meta param source track wbr".split(" "));
|
|
308
|
+
var RAW_TEXT_ELEMENTS = new Set(["script", "style"]);
|
|
533
309
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
310
|
+
// tests/environment.ts
|
|
311
|
+
var realSetTimeout = globalThis.setTimeout;
|
|
312
|
+
var realClearTimeout = globalThis.clearTimeout;
|
|
313
|
+
function createEnvironment() {
|
|
314
|
+
let timeouts = [];
|
|
315
|
+
let currentTime = 0;
|
|
316
|
+
let deferredErrors = [];
|
|
317
|
+
function fireItem(item) {
|
|
318
|
+
const idx = timeouts.indexOf(item);
|
|
319
|
+
if (idx < 0)
|
|
320
|
+
return;
|
|
321
|
+
timeouts.splice(idx, 1);
|
|
322
|
+
if (item.time > currentTime)
|
|
323
|
+
currentTime = item.time;
|
|
324
|
+
item.func();
|
|
325
|
+
}
|
|
326
|
+
const setTimeout = function(func, time = 0) {
|
|
327
|
+
const item = { func, time: time + currentTime, realId: undefined };
|
|
328
|
+
item.realId = realSetTimeout(() => {
|
|
329
|
+
try {
|
|
330
|
+
fireItem(item);
|
|
331
|
+
} catch (e) {
|
|
332
|
+
deferredErrors.push(e);
|
|
333
|
+
}
|
|
334
|
+
}, time);
|
|
335
|
+
timeouts.push(item);
|
|
336
|
+
};
|
|
337
|
+
const queueMicrotask = function(func) {
|
|
338
|
+
const item = { func, time: 0, realId: undefined };
|
|
339
|
+
item.realId = realSetTimeout(() => {
|
|
340
|
+
try {
|
|
341
|
+
fireItem(item);
|
|
342
|
+
} catch (e) {
|
|
343
|
+
deferredErrors.push(e);
|
|
344
|
+
}
|
|
345
|
+
}, 0);
|
|
346
|
+
timeouts.push(item);
|
|
347
|
+
};
|
|
348
|
+
const passTime = async function(ms = 0) {
|
|
349
|
+
let targetTime = currentTime + ms;
|
|
350
|
+
while (true) {
|
|
351
|
+
await new Promise((resolve) => realSetTimeout(resolve, 0));
|
|
352
|
+
if (deferredErrors.length) {
|
|
353
|
+
const err = deferredErrors.shift();
|
|
354
|
+
throw err;
|
|
355
|
+
}
|
|
356
|
+
if (!timeouts.length) {
|
|
357
|
+
let settled = false;
|
|
358
|
+
for (let r = 0;r < 5 && !settled; r++) {
|
|
359
|
+
await new Promise((resolve) => realSetTimeout(resolve, 0));
|
|
360
|
+
settled = timeouts.length > 0;
|
|
361
|
+
}
|
|
362
|
+
if (!settled)
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
let smallestIdx = 0;
|
|
366
|
+
for (let idx = 1;idx < timeouts.length; idx++) {
|
|
367
|
+
if (timeouts[idx].time < timeouts[smallestIdx].time)
|
|
368
|
+
smallestIdx = idx;
|
|
369
|
+
}
|
|
370
|
+
let item = timeouts[smallestIdx];
|
|
371
|
+
if (item.time > targetTime)
|
|
372
|
+
break;
|
|
373
|
+
timeouts.splice(smallestIdx, 1);
|
|
374
|
+
realClearTimeout(item.realId);
|
|
375
|
+
if (item.time > currentTime)
|
|
376
|
+
currentTime = item.time;
|
|
377
|
+
await item.func();
|
|
378
|
+
}
|
|
379
|
+
currentTime = targetTime;
|
|
380
|
+
};
|
|
381
|
+
const mediaQueries = new Map;
|
|
382
|
+
const mediaQueryPresets = new Map;
|
|
383
|
+
|
|
384
|
+
class MediaQueryList {
|
|
385
|
+
matches;
|
|
386
|
+
media;
|
|
387
|
+
listeners = new Set;
|
|
388
|
+
constructor(query) {
|
|
389
|
+
this.media = query;
|
|
390
|
+
const preset = mediaQueryPresets.get(query);
|
|
391
|
+
this.matches = preset !== undefined ? preset : query.includes("dark") ? false : true;
|
|
392
|
+
}
|
|
393
|
+
addEventListener(type, listener) {
|
|
394
|
+
if (type === "change")
|
|
395
|
+
this.listeners.add(listener);
|
|
396
|
+
}
|
|
397
|
+
removeEventListener(type, listener) {
|
|
398
|
+
if (type === "change")
|
|
399
|
+
this.listeners.delete(listener);
|
|
400
|
+
}
|
|
401
|
+
_trigger(matches) {
|
|
402
|
+
this.matches = matches;
|
|
403
|
+
for (const listener of this.listeners)
|
|
404
|
+
listener({ matches, media: this.media });
|
|
546
405
|
}
|
|
547
406
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
407
|
+
function setMediaQuery(query, matches) {
|
|
408
|
+
mediaQueryPresets.set(query, matches);
|
|
409
|
+
if (mediaQueries.has(query))
|
|
410
|
+
mediaQueries.get(query)._trigger(matches);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
class FakeLocation {
|
|
414
|
+
_href = "http://localhost/";
|
|
415
|
+
get href() {
|
|
416
|
+
return this._href;
|
|
417
|
+
}
|
|
418
|
+
set href(value) {
|
|
419
|
+
if (value.startsWith("/")) {
|
|
420
|
+
const currentUrl = new URL(this._href);
|
|
421
|
+
this._href = `${currentUrl.protocol}//${currentUrl.host}${value}`;
|
|
422
|
+
} else
|
|
423
|
+
this._href = value;
|
|
424
|
+
}
|
|
425
|
+
get host() {
|
|
426
|
+
return new URL(this._href).host;
|
|
427
|
+
}
|
|
428
|
+
get pathname() {
|
|
429
|
+
return new URL(this._href).pathname;
|
|
430
|
+
}
|
|
431
|
+
set pathname(value) {
|
|
432
|
+
const u = new URL(this._href);
|
|
433
|
+
u.pathname = value;
|
|
434
|
+
this._href = u.href;
|
|
435
|
+
}
|
|
436
|
+
get search() {
|
|
437
|
+
return new URL(this._href).search;
|
|
438
|
+
}
|
|
439
|
+
set search(value) {
|
|
440
|
+
const u = new URL(this._href);
|
|
441
|
+
u.search = value;
|
|
442
|
+
this._href = u.href;
|
|
443
|
+
}
|
|
444
|
+
get hash() {
|
|
445
|
+
return new URL(this._href).hash;
|
|
446
|
+
}
|
|
447
|
+
set hash(value) {
|
|
448
|
+
const u = new URL(this._href);
|
|
449
|
+
u.hash = value;
|
|
450
|
+
this._href = u.href;
|
|
551
451
|
}
|
|
552
452
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
453
|
+
|
|
454
|
+
class FakeHistory {
|
|
455
|
+
_state = null;
|
|
456
|
+
_entries = [{ url: "http://localhost/", state: null }];
|
|
457
|
+
_index = 0;
|
|
458
|
+
get state() {
|
|
459
|
+
return this._state;
|
|
460
|
+
}
|
|
461
|
+
pushState(state, _title, url) {
|
|
462
|
+
this._entries = this._entries.slice(0, this._index + 1);
|
|
463
|
+
this._entries.push({ url, state });
|
|
464
|
+
this._index = this._entries.length - 1;
|
|
465
|
+
this._state = state;
|
|
466
|
+
location.href = url;
|
|
467
|
+
}
|
|
468
|
+
replaceState(state, _title, url) {
|
|
469
|
+
this._entries[this._index] = { url, state };
|
|
470
|
+
this._state = state;
|
|
471
|
+
location.href = url;
|
|
472
|
+
}
|
|
473
|
+
go(delta) {
|
|
474
|
+
const newIndex = this._index + delta;
|
|
475
|
+
if (newIndex >= 0 && newIndex < this._entries.length) {
|
|
476
|
+
this._index = newIndex;
|
|
477
|
+
const entry = this._entries[this._index];
|
|
478
|
+
this._state = entry.state;
|
|
479
|
+
location.href = entry.url;
|
|
480
|
+
setTimeout(() => window.dispatchEvent({
|
|
481
|
+
type: "popstate",
|
|
482
|
+
state: this._state,
|
|
483
|
+
target: window,
|
|
484
|
+
preventDefault: () => {},
|
|
485
|
+
stopPropagation: () => {}
|
|
486
|
+
}), 0);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
back() {
|
|
490
|
+
this.go(-1);
|
|
491
|
+
}
|
|
492
|
+
forward() {
|
|
493
|
+
this.go(1);
|
|
558
494
|
}
|
|
559
495
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
496
|
+
|
|
497
|
+
class FakeWindow {
|
|
498
|
+
_listeners = {};
|
|
499
|
+
addEventListener(type, listener) {
|
|
500
|
+
(this._listeners[type] ||= new Set).add(listener);
|
|
501
|
+
}
|
|
502
|
+
removeEventListener(type, listener) {
|
|
503
|
+
this._listeners[type]?.delete(listener);
|
|
504
|
+
}
|
|
505
|
+
dispatchEvent(event) {
|
|
506
|
+
this._listeners[event.type]?.forEach((l) => l.call(this, event));
|
|
507
|
+
}
|
|
508
|
+
matchMedia(query) {
|
|
509
|
+
if (!mediaQueries.has(query))
|
|
510
|
+
mediaQueries.set(query, new MediaQueryList(query));
|
|
511
|
+
return mediaQueries.get(query);
|
|
512
|
+
}
|
|
567
513
|
}
|
|
514
|
+
const location = new FakeLocation;
|
|
515
|
+
const history = new FakeHistory;
|
|
516
|
+
const window = new FakeWindow;
|
|
517
|
+
const getComputedStyle = (el) => el._style;
|
|
518
|
+
const document = createDocument();
|
|
519
|
+
Object.assign(window, { document, Node, Element, TextNode, location, history, setTimeout, queueMicrotask, getComputedStyle });
|
|
520
|
+
document.defaultView = window;
|
|
521
|
+
const A = createA(window);
|
|
522
|
+
resetCounts();
|
|
523
|
+
return { A, window, document, location, history, setTimeout, passTime, setMediaQuery, getCounts, resetCounts };
|
|
568
524
|
}
|
|
569
|
-
var globals = { Node, Element: Element2, TextNode, document: document2, window, setTimeout, queueMicrotask, getComputedStyle, location, history, URLSearchParams };
|
|
570
|
-
Object.assign(global, globals);
|
|
571
|
-
Object.assign(window, globals);
|
|
572
525
|
|
|
573
526
|
// tests/helpers.ts
|
|
574
|
-
import { expect } from "bun:test";
|
|
575
|
-
|
|
527
|
+
import { expect, beforeEach } from "bun:test";
|
|
528
|
+
var env;
|
|
529
|
+
var A;
|
|
530
|
+
var window;
|
|
531
|
+
var document;
|
|
532
|
+
var location;
|
|
533
|
+
var history;
|
|
534
|
+
var setTimeout;
|
|
535
|
+
var passTime;
|
|
536
|
+
function newEnvironment() {
|
|
537
|
+
env = createEnvironment();
|
|
538
|
+
A = env.A;
|
|
539
|
+
window = env.window;
|
|
540
|
+
document = env.document;
|
|
541
|
+
location = env.location;
|
|
542
|
+
history = env.history;
|
|
543
|
+
setTimeout = env.setTimeout;
|
|
544
|
+
passTime = env.passTime;
|
|
545
|
+
}
|
|
546
|
+
newEnvironment();
|
|
547
|
+
beforeEach(newEnvironment);
|
|
548
|
+
function setMediaQuery(query, matches) {
|
|
549
|
+
env.setMediaQuery(query, matches);
|
|
550
|
+
}
|
|
551
|
+
function getCounts2() {
|
|
552
|
+
return env.getCounts();
|
|
553
|
+
}
|
|
576
554
|
function toDisplay(value) {
|
|
577
555
|
if (value instanceof Map) {
|
|
578
556
|
let results = [];
|
|
@@ -640,40 +618,33 @@ async function assertThrow(a, b) {
|
|
|
640
618
|
}
|
|
641
619
|
throw new AssertError(`exception expected`, undefined, `something containing "${a}"`, true);
|
|
642
620
|
}
|
|
643
|
-
var passTime2 = passTime;
|
|
644
621
|
function assertDomUpdates(expected) {
|
|
645
|
-
const counts = getCounts();
|
|
622
|
+
const counts = env.getCounts();
|
|
646
623
|
if (expected.new != null)
|
|
647
624
|
expect(counts.new).toEqual(expected.new);
|
|
648
625
|
if (expected.changed != null)
|
|
649
626
|
expect(counts.changed).toEqual(expected.changed);
|
|
650
627
|
}
|
|
651
|
-
async function reset() {
|
|
652
|
-
A.copy(A.cssVars, {});
|
|
653
|
-
A.unmountAll();
|
|
654
|
-
try {
|
|
655
|
-
await passTime(2001);
|
|
656
|
-
assertBody(``);
|
|
657
|
-
} finally {
|
|
658
|
-
clearBody();
|
|
659
|
-
}
|
|
660
|
-
resetCounts();
|
|
661
|
-
A.setErrorHandler();
|
|
662
|
-
}
|
|
663
628
|
export {
|
|
664
|
-
|
|
665
|
-
|
|
629
|
+
window,
|
|
630
|
+
setTimeout,
|
|
631
|
+
setMediaQuery,
|
|
632
|
+
passTime,
|
|
633
|
+
location,
|
|
634
|
+
history,
|
|
666
635
|
getCss,
|
|
636
|
+
getCounts2 as getCounts,
|
|
667
637
|
getBody,
|
|
668
|
-
|
|
638
|
+
document,
|
|
669
639
|
assertThrow,
|
|
670
640
|
assertDomUpdates,
|
|
671
641
|
assertCss,
|
|
672
642
|
assertContains,
|
|
673
643
|
assertBody,
|
|
674
644
|
assert,
|
|
675
|
-
AssertError
|
|
645
|
+
AssertError,
|
|
646
|
+
A
|
|
676
647
|
};
|
|
677
648
|
|
|
678
|
-
//# debugId=
|
|
649
|
+
//# debugId=E9E14C2775DDDF9564756E2164756E21
|
|
679
650
|
//# sourceMappingURL=helpers.js.map
|