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
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/transitions.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"const FADE_TIME = 400;\nconst GROW_SHRINK_TRANSITION = `margin ${FADE_TIME}ms ease-out, transform ${FADE_TIME}ms ease-out`;\n\nfunction getGrowShrinkProps(el: HTMLElement): Partial<CSSStyleDeclaration> {\n\tif (el.parentElement) {\n\t\tconst parentStyle = getComputedStyle(el.parentElement);\n\t\tconst isHorizontal =\n\t\t\tparentStyle.display === \"flex\" &&\n\t\t\t(parentStyle.flexDirection || \"\").startsWith(\"row\");\n\t\tif (isHorizontal) {\n\t\t\treturn {\n\t\t\t\tmarginLeft: `-${el.offsetWidth / 2}px`,\n\t\t\t\tmarginRight: `-${el.offsetWidth / 2}px`,\n\t\t\t\ttransform: \"scaleX(0)\",\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tmarginBottom: `-${el.offsetHeight / 2}px`,\n\t\tmarginTop: `-${el.offsetHeight / 2}px`,\n\t\ttransform: \"scaleY(0)\",\n\t};\n}\n\n/** Do a grow transition for the given element. This is meant to be used as a\n * handler for the `create` property.\n *\n * @param el The element to transition.\n *\n * The transition doesn't look great for table elements, and may have problems\n * for other specific cases as well.\n */\nexport async function grow(el: HTMLElement) {\n\tconst props = getGrowShrinkProps(el);\n\tObject.assign(el.style, props);\n\n\t// Make sure the layouting has been performed, to cause transitions to trigger\n\tel.offsetHeight;\n\n\tel.style.transition = GROW_SHRINK_TRANSITION;\n\tfor (const prop in props) el.style[prop] = \"\";\n\
|
|
5
|
+
"const FADE_TIME = 400;\nconst GROW_SHRINK_TRANSITION = `margin ${FADE_TIME}ms ease-out, transform ${FADE_TIME}ms ease-out`;\n\n// Resolve `getComputedStyle`/`setTimeout` from the element's own window (the one Aberdeen was\n// initialised with) rather than the global, so this works under any injected DOM.\nfunction windowOf(el: any): any {\n\treturn el?.ownerDocument?.defaultView ?? globalThis;\n}\n\nfunction getGrowShrinkProps(el: HTMLElement): Partial<CSSStyleDeclaration> {\n\tif (el.parentElement) {\n\t\tconst parentStyle = windowOf(el).getComputedStyle(el.parentElement);\n\t\tconst isHorizontal =\n\t\t\tparentStyle.display === \"flex\" &&\n\t\t\t(parentStyle.flexDirection || \"\").startsWith(\"row\");\n\t\tif (isHorizontal) {\n\t\t\treturn {\n\t\t\t\tmarginLeft: `-${el.offsetWidth / 2}px`,\n\t\t\t\tmarginRight: `-${el.offsetWidth / 2}px`,\n\t\t\t\ttransform: \"scaleX(0)\",\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tmarginBottom: `-${el.offsetHeight / 2}px`,\n\t\tmarginTop: `-${el.offsetHeight / 2}px`,\n\t\ttransform: \"scaleY(0)\",\n\t};\n}\n\n/** Do a grow transition for the given element. This is meant to be used as a\n * handler for the `create` property.\n *\n * @param el The element to transition.\n *\n * The transition doesn't look great for table elements, and may have problems\n * for other specific cases as well.\n */\nexport async function grow(el: HTMLElement) {\n\tconst props = getGrowShrinkProps(el);\n\tObject.assign(el.style, props);\n\n\t// Make sure the layouting has been performed, to cause transitions to trigger\n\tel.offsetHeight;\n\n\tel.style.transition = GROW_SHRINK_TRANSITION;\n\tfor (const prop in props) el.style[prop] = \"\";\n\twindowOf(el).setTimeout(() => {\n\t\t// Disable transitions.\n\t\tel.style.transition = \"\";\n\t}, FADE_TIME);\n}\n\n/** Do a shrink transition for the given element, and remove it from the DOM\n * afterwards. This is meant to be used as a handler for the `destroy` property.\n *\n * @param el The element to transition and remove.\n *\n * The transition doesn't look great for table elements, and may have problems\n * for other specific cases as well.\n */\nexport async function shrink(el: HTMLElement) {\n\t// Get original layout info\n\tconst props = getGrowShrinkProps(el);\n\n\t// Batch starting transitions in the write phase.\n\tel.style.transition = GROW_SHRINK_TRANSITION;\n\tObject.assign(el.style, props);\n\n\t// Remove the element after the transition is done.\n\twindowOf(el).setTimeout(() => {\n\t\tel.remove();\n\t}, FADE_TIME);\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA,IAAM,YAAY;AAClB,IAAM,yBAAyB,UAAU,mCAAmC;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAAA,IAAM,YAAY;AAClB,IAAM,yBAAyB,UAAU,mCAAmC;AAI5E,SAAS,QAAQ,CAAC,IAAc;AAAA,EAC/B,OAAO,IAAI,eAAe,eAAe;AAAA;AAG1C,SAAS,kBAAkB,CAAC,IAA+C;AAAA,EAC1E,IAAI,GAAG,eAAe;AAAA,IACrB,MAAM,cAAc,SAAS,EAAE,EAAE,iBAAiB,GAAG,aAAa;AAAA,IAClE,MAAM,eACL,YAAY,YAAY,WACvB,YAAY,iBAAiB,IAAI,WAAW,KAAK;AAAA,IACnD,IAAI,cAAc;AAAA,MACjB,OAAO;AAAA,QACN,YAAY,IAAI,GAAG,cAAc;AAAA,QACjC,aAAa,IAAI,GAAG,cAAc;AAAA,QAClC,WAAW;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AAAA,EACA,OAAO;AAAA,IACN,cAAc,IAAI,GAAG,eAAe;AAAA,IACpC,WAAW,IAAI,GAAG,eAAe;AAAA,IACjC,WAAW;AAAA,EACZ;AAAA;AAWD,eAAsB,IAAI,CAAC,IAAiB;AAAA,EAC3C,MAAM,QAAQ,mBAAmB,EAAE;AAAA,EACnC,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,EAG7B,GAAG;AAAA,EAEH,GAAG,MAAM,aAAa;AAAA,EACtB,WAAW,QAAQ;AAAA,IAAO,GAAG,MAAM,QAAQ;AAAA,EAC3C,SAAS,EAAE,EAAE,WAAW,MAAM;AAAA,IAE7B,GAAG,MAAM,aAAa;AAAA,KACpB,SAAS;AAAA;AAWb,eAAsB,MAAM,CAAC,IAAiB;AAAA,EAE7C,MAAM,QAAQ,mBAAmB,EAAE;AAAA,EAGnC,GAAG,MAAM,aAAa;AAAA,EACtB,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,EAG7B,SAAS,EAAE,EAAE,WAAW,MAAM;AAAA,IAC7B,GAAG,OAAO;AAAA,KACR,SAAS;AAAA;",
|
|
8
|
+
"debugId": "500B3AF69B932EE464756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Aberdeen } from "aberdeen";
|
|
2
|
+
import { Node, Element, TextNode } from "../src/server-dom.js";
|
|
3
|
+
export { Node, Element, TextNode };
|
|
4
|
+
export interface TestEnvironment {
|
|
5
|
+
A: Aberdeen;
|
|
6
|
+
window: any;
|
|
7
|
+
document: any;
|
|
8
|
+
location: any;
|
|
9
|
+
history: any;
|
|
10
|
+
/** The fake `setTimeout` of this environment (controlled by `passTime`). */
|
|
11
|
+
setTimeout: (func: () => void, time?: number) => void;
|
|
12
|
+
/** Fast-forward this environment's fake time, firing scheduled timers/microtasks. */
|
|
13
|
+
passTime: (ms?: number) => Promise<void>;
|
|
14
|
+
/** Preset a media-query match value (and notify listeners if already created). */
|
|
15
|
+
setMediaQuery: (query: string, matches: boolean) => void;
|
|
16
|
+
/** DOM operation counters (shared module-level, reset when the environment is created). */
|
|
17
|
+
getCounts: () => {
|
|
18
|
+
new: number;
|
|
19
|
+
changed: number;
|
|
20
|
+
};
|
|
21
|
+
resetCounts: () => void;
|
|
22
|
+
}
|
|
23
|
+
/** Create a fresh, fully isolated fake-browser environment with its own Aberdeen instance. */
|
|
24
|
+
export declare function createEnvironment(): TestEnvironment;
|
|
@@ -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
|
-
document.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
|
}
|
|
@@ -63,6 +40,8 @@ class Element extends Node {
|
|
|
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;
|
|
@@ -227,8 +206,6 @@ class Element 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]]) {
|
|
@@ -293,225 +270,7 @@ class Element extends Node {
|
|
|
293
270
|
return;
|
|
294
271
|
}
|
|
295
272
|
}
|
|
296
|
-
var
|
|
297
|
-
createElement: (tag) => new Element(tag, "http://www.w3.org/1999/xhtml"),
|
|
298
|
-
createElementNS: (namespaceURI, tag) => new Element(tag, namespaceURI),
|
|
299
|
-
createTextNode: (text) => new TextNode(text),
|
|
300
|
-
head: new Element("head", "http://www.w3.org/1999/xhtml"),
|
|
301
|
-
body: new Element("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,56 +286,248 @@ 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();
|
|
546
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 });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
function setMediaQuery(query, matches) {
|
|
408
|
+
mediaQueryPresets.set(query, matches);
|
|
409
|
+
if (mediaQueries.has(query))
|
|
410
|
+
mediaQueries.get(query)._trigger(matches);
|
|
547
411
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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, TextNode, document, window, setTimeout, queueMicrotask, getComputedStyle, location, history, URLSearchParams };
|
|
570
|
-
Object.assign(global, globals);
|
|
571
|
-
Object.assign(window, globals);
|
|
572
525
|
export {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
getCounts,
|
|
578
|
-
clearBody
|
|
526
|
+
createEnvironment,
|
|
527
|
+
TextNode,
|
|
528
|
+
Node,
|
|
529
|
+
Element
|
|
579
530
|
};
|
|
580
531
|
|
|
581
|
-
//# debugId=
|
|
582
|
-
//# sourceMappingURL=
|
|
532
|
+
//# debugId=B6E7B31869CE5FFC64756E2164756E21
|
|
533
|
+
//# sourceMappingURL=environment.js.map
|