@davidsouther/jiffies 2026.4.1 → 2026.24.1
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 +0 -3
- package/lib/esm/assert.d.ts +26 -0
- package/lib/esm/assert.js +38 -0
- package/lib/esm/awaitable.js +1 -0
- package/lib/esm/case.d.ts +1 -0
- package/lib/esm/case.js +5 -0
- package/lib/esm/components/accordion.d.ts +5 -0
- package/lib/esm/components/accordion.js +9 -0
- package/lib/esm/components/alert.d.ts +7 -0
- package/lib/esm/components/alert.js +31 -0
- package/lib/esm/components/button_bar.d.ts +8 -0
- package/lib/esm/components/button_bar.js +25 -0
- package/lib/esm/components/card.d.ts +8 -0
- package/lib/esm/components/card.js +31 -0
- package/lib/esm/components/children.d.ts +2 -0
- package/lib/esm/components/children.js +7 -0
- package/lib/esm/components/form.d.ts +5 -0
- package/lib/esm/components/form.js +13 -0
- package/lib/esm/components/index.d.ts +9 -0
- package/lib/esm/components/index.js +10 -0
- package/lib/esm/components/inline_edit.d.ts +12 -0
- package/lib/esm/components/inline_edit.js +48 -0
- package/lib/esm/components/link.d.ts +5 -0
- package/lib/esm/components/link.js +11 -0
- package/lib/esm/components/logger.d.ts +6 -0
- package/lib/esm/components/logger.js +22 -0
- package/lib/esm/components/modal.d.ts +2 -0
- package/lib/esm/components/modal.js +10 -0
- package/lib/esm/components/nav.d.ts +11 -0
- package/lib/esm/components/nav.js +27 -0
- package/lib/esm/components/property.d.ts +9 -0
- package/lib/esm/components/property.js +16 -0
- package/lib/esm/components/select.d.ts +10 -0
- package/lib/esm/components/select.js +3 -0
- package/lib/esm/components/tabs.d.ts +20 -0
- package/lib/esm/components/tabs.js +45 -0
- package/lib/esm/components/virtual_scroll.d.ts +42 -0
- package/lib/esm/components/virtual_scroll.js +94 -0
- package/lib/esm/debounce.d.ts +1 -0
- package/lib/esm/debounce.js +11 -0
- package/lib/esm/diff.d.ts +15 -0
- package/lib/esm/diff.js +50 -0
- package/lib/esm/display.d.ts +5 -0
- package/lib/esm/display.js +11 -0
- package/lib/esm/dom/css/border.d.ts +11 -0
- package/lib/esm/dom/css/border.js +27 -0
- package/lib/esm/dom/css/constants.d.ts +31 -0
- package/lib/esm/dom/css/constants.js +28 -0
- package/lib/esm/dom/css/core.d.ts +5 -0
- package/lib/esm/dom/css/core.js +24 -0
- package/lib/esm/dom/css/fstyle.d.ts +5 -0
- package/lib/esm/dom/css/fstyle.js +32 -0
- package/lib/esm/dom/css/sizing.d.ts +5 -0
- package/lib/esm/dom/css/sizing.js +10 -0
- package/lib/esm/dom/dom.d.ts +36 -0
- package/lib/esm/dom/dom.js +217 -0
- package/lib/esm/dom/fc.d.ts +10 -0
- package/lib/esm/dom/fc.js +32 -0
- package/lib/esm/dom/form/form.app.d.ts +1 -0
- package/lib/esm/dom/form/form.app.js +19 -0
- package/lib/esm/dom/form/form.d.ts +27 -0
- package/lib/esm/dom/form/form.js +65 -0
- package/lib/esm/dom/html.d.ts +112 -0
- package/{src/dom/html.ts → lib/esm/dom/html.js} +2 -14
- package/lib/esm/dom/hydrate.d.ts +39 -0
- package/lib/esm/dom/hydrate.js +187 -0
- package/lib/esm/dom/index.js +2 -0
- package/lib/esm/dom/navigation/index.d.ts +76 -0
- package/lib/esm/dom/navigation/index.js +292 -0
- package/lib/esm/dom/observable.d.ts +2 -0
- package/lib/esm/dom/observable.js +6 -0
- package/lib/esm/dom/provide.d.ts +3 -0
- package/lib/esm/dom/provide.js +7 -0
- package/lib/esm/dom/render.d.ts +8 -0
- package/lib/esm/dom/render.js +28 -0
- package/lib/esm/dom/router/link.d.ts +6 -0
- package/lib/esm/dom/router/link.js +3 -0
- package/lib/esm/dom/router/router.d.ts +13 -0
- package/lib/esm/dom/router/router.js +52 -0
- package/lib/esm/dom/svg.d.ts +64 -0
- package/{src/dom/svg.ts → lib/esm/dom/svg.js} +2 -15
- package/lib/esm/dom/types/css.d.ts +6590 -0
- package/lib/esm/dom/types/css.js +1 -0
- package/lib/esm/dom/types/dom.js +1 -0
- package/lib/esm/dom/types/html.d.ts +614 -0
- package/lib/esm/dom/types/html.js +1 -0
- package/lib/esm/dom/xml.d.ts +1 -0
- package/lib/esm/dom/xml.js +4 -0
- package/lib/esm/equal.d.ts +11 -0
- package/lib/esm/equal.js +43 -0
- package/lib/esm/fs.d.ts +72 -0
- package/lib/esm/fs.js +227 -0
- package/lib/esm/fs_node.d.ts +15 -0
- package/lib/esm/fs_node.js +45 -0
- package/lib/esm/generator.d.ts +1 -0
- package/lib/esm/generator.js +10 -0
- package/lib/esm/lock.d.ts +1 -0
- package/lib/esm/lock.js +23 -0
- package/lib/esm/log.d.ts +69 -0
- package/lib/esm/log.js +211 -0
- package/lib/esm/observable/event.d.ts +35 -0
- package/lib/esm/observable/event.js +46 -0
- package/lib/esm/observable/observable.d.ts +134 -0
- package/lib/esm/observable/observable.js +349 -0
- package/lib/esm/range.d.ts +1 -0
- package/lib/esm/range.js +7 -0
- package/lib/esm/result.d.ts +31 -0
- package/lib/esm/result.js +66 -0
- package/lib/esm/safe.d.ts +1 -0
- package/lib/esm/safe.js +10 -0
- package/lib/esm/server/http/apps.d.ts +5 -0
- package/lib/esm/server/http/apps.js +23 -0
- package/lib/esm/server/http/css.d.ts +5 -0
- package/lib/esm/server/http/css.js +43 -0
- package/lib/esm/server/http/index.d.ts +16 -0
- package/lib/esm/server/http/index.js +78 -0
- package/lib/esm/server/http/response.d.ts +4 -0
- package/lib/esm/server/http/response.js +43 -0
- package/lib/esm/server/http/sitemap.d.ts +2 -0
- package/lib/esm/server/http/sitemap.js +22 -0
- package/lib/esm/server/http/static.d.ts +2 -0
- package/lib/esm/server/http/static.js +22 -0
- package/lib/esm/server/http/typescript.d.ts +5 -0
- package/lib/esm/server/http/typescript.js +40 -0
- package/lib/esm/server/live-reload.d.ts +46 -0
- package/lib/esm/server/live-reload.js +161 -0
- package/lib/esm/server/main.d.ts +2 -0
- package/lib/esm/server/main.js +23 -0
- package/lib/esm/server/ws/frame.d.ts +2 -0
- package/lib/esm/server/ws/frame.js +35 -0
- package/lib/esm/server/ws/handshake.d.ts +4 -0
- package/lib/esm/server/ws/handshake.js +32 -0
- package/lib/esm/server/ws/index.d.ts +14 -0
- package/lib/esm/server/ws/index.js +68 -0
- package/lib/esm/ssg/bundle.d.ts +14 -0
- package/lib/esm/ssg/bundle.js +73 -0
- package/lib/esm/ssg/copy-public.d.ts +6 -0
- package/lib/esm/ssg/copy-public.js +34 -0
- package/lib/esm/ssg/discover.d.ts +15 -0
- package/lib/esm/ssg/discover.js +117 -0
- package/lib/esm/ssg/main.d.ts +2 -0
- package/lib/esm/ssg/main.js +122 -0
- package/lib/esm/ssg/rewrite.d.ts +9 -0
- package/lib/esm/ssg/rewrite.js +15 -0
- package/lib/esm/ssg/ssg.d.ts +26 -0
- package/lib/esm/ssg/ssg.js +84 -0
- package/lib/esm/transpile.d.mts +3 -0
- package/lib/esm/transpile.mjs +12 -0
- package/package.json +19 -10
- package/src/404.html +0 -14
- package/src/assert.ts +0 -56
- package/src/case.ts +0 -5
- package/src/components/_notes +0 -33
- package/src/components/button_bar.ts +0 -42
- package/src/components/inline_edit.ts +0 -78
- package/src/components/logger.ts +0 -35
- package/src/components/select.ts +0 -22
- package/src/components/test.ts +0 -5
- package/src/components/virtual_scroll.test.ts +0 -30
- package/src/components/virtual_scroll.ts +0 -199
- package/src/context.test.ts +0 -58
- package/src/context.ts +0 -67
- package/src/debounce.ts +0 -14
- package/src/diff.test.ts +0 -48
- package/src/diff.ts +0 -82
- package/src/display.ts +0 -18
- package/src/dom/README.md +0 -102
- package/src/dom/css/border.ts +0 -47
- package/src/dom/css/constants.ts +0 -34
- package/src/dom/css/core.ts +0 -28
- package/src/dom/css/fstyle.ts +0 -42
- package/src/dom/css/sizing.ts +0 -11
- package/src/dom/dom.ts +0 -183
- package/src/dom/fc.test.ts +0 -43
- package/src/dom/fc.ts +0 -80
- package/src/dom/form/form.app.ts +0 -50
- package/src/dom/form/form.ts +0 -82
- package/src/dom/form/index.html +0 -15
- package/src/dom/html.test.ts +0 -74
- package/src/dom/observable.test.ts +0 -43
- package/src/dom/observable.ts +0 -11
- package/src/dom/provide.ts +0 -11
- package/src/dom/router/link.ts +0 -14
- package/src/dom/router/router.ts +0 -72
- package/src/dom/test.ts +0 -11
- package/src/dom/types/css.ts +0 -10088
- package/src/dom/types/dom.ts +0 -0
- package/src/dom/types/html.ts +0 -629
- package/src/dom/xml.ts +0 -11
- package/src/equal.test.ts +0 -23
- package/src/equal.ts +0 -66
- package/src/favicon.ico +0 -0
- package/src/flags.test.ts +0 -43
- package/src/flags.ts +0 -53
- package/src/fs.test.ts +0 -106
- package/src/fs.ts +0 -300
- package/src/fs_node.ts +0 -57
- package/src/fs_win.test.ts +0 -11
- package/src/generator.test.ts +0 -27
- package/src/generator.ts +0 -12
- package/src/hooks/_notes +0 -6
- package/src/index.html +0 -82
- package/src/is_browser.js +0 -1
- package/src/lock.test.ts +0 -17
- package/src/lock.ts +0 -23
- package/src/log.ts +0 -155
- package/src/observable/_notes +0 -26
- package/src/observable/event.ts +0 -93
- package/src/observable/observable.test.ts +0 -73
- package/src/observable/observable.ts +0 -484
- package/src/pico/_variables.scss +0 -66
- package/src/pico/components/_accordion.scss +0 -112
- package/src/pico/components/_button-group.scss +0 -51
- package/src/pico/components/_card.scss +0 -47
- package/src/pico/components/_dropdown.scss +0 -203
- package/src/pico/components/_modal.scss +0 -181
- package/src/pico/components/_nav.scss +0 -79
- package/src/pico/components/_progress.scss +0 -70
- package/src/pico/components/_property.scss +0 -34
- package/src/pico/content/_button.scss +0 -152
- package/src/pico/content/_code.scss +0 -63
- package/src/pico/content/_embedded.scss +0 -0
- package/src/pico/content/_form-alt.scss +0 -276
- package/src/pico/content/_form.scss +0 -259
- package/src/pico/content/_misc.scss +0 -0
- package/src/pico/content/_table.scss +0 -28
- package/src/pico/content/_toggle.scss +0 -132
- package/src/pico/content/_typography.scss +0 -232
- package/src/pico/layout/_container.scss +0 -40
- package/src/pico/layout/_document.scss +0 -0
- package/src/pico/layout/_flex.scss +0 -46
- package/src/pico/layout/_grid.scss +0 -24
- package/src/pico/layout/_scroller.scss +0 -16
- package/src/pico/layout/_section.scss +0 -8
- package/src/pico/layout/_sectioning.scss +0 -55
- package/src/pico/pico.scss +0 -60
- package/src/pico/reset/_accessibility.scss +0 -34
- package/src/pico/reset/_button.scss +0 -17
- package/src/pico/reset/_code.scss +0 -15
- package/src/pico/reset/_document.scss +0 -48
- package/src/pico/reset/_embedded.scss +0 -39
- package/src/pico/reset/_form.scss +0 -97
- package/src/pico/reset/_misc.scss +0 -23
- package/src/pico/reset/_nav.scss +0 -5
- package/src/pico/reset/_progress.scss +0 -4
- package/src/pico/reset/_table.scss +0 -8
- package/src/pico/reset/_typography.scss +0 -25
- package/src/pico/themes/default/_colors.scss +0 -65
- package/src/pico/themes/default/_dark.scss +0 -148
- package/src/pico/themes/default/_light.scss +0 -149
- package/src/pico/themes/default/_styles.scss +0 -272
- package/src/pico/themes/default.scss +0 -34
- package/src/pico/utilities/_accessibility.scss +0 -3
- package/src/pico/utilities/_loading.scss +0 -52
- package/src/pico/utilities/_reduce-motion.scss +0 -27
- package/src/pico/utilities/_tooltip.scss +0 -101
- package/src/range.ts +0 -7
- package/src/result.test.ts +0 -101
- package/src/result.ts +0 -107
- package/src/safe.ts +0 -12
- package/src/scope/describe.ts +0 -81
- package/src/scope/display/console.ts +0 -26
- package/src/scope/display/dom.ts +0 -36
- package/src/scope/display/junit.ts +0 -64
- package/src/scope/execute.ts +0 -110
- package/src/scope/expect.ts +0 -169
- package/src/scope/fix.ts +0 -30
- package/src/scope/index.ts +0 -11
- package/src/scope/scope.ts +0 -21
- package/src/scope/state.ts +0 -13
- package/src/server/http/apps.ts +0 -26
- package/src/server/http/css.ts +0 -49
- package/src/server/http/index.ts +0 -127
- package/src/server/http/response.ts +0 -57
- package/src/server/http/sitemap.ts +0 -48
- package/src/server/http/static.ts +0 -30
- package/src/server/http/typescript.ts +0 -46
- package/src/server/main.ts +0 -23
- package/src/test.mjs +0 -33
- package/src/test_all.ts +0 -35
- package/src/transpile.mjs +0 -16
- package/src/zip/spec.txt +0 -3260
- package/tsconfig.json +0 -34
- /package/{src/awaitable.ts → lib/esm/awaitable.d.ts} +0 -0
- /package/{src/dom/index.ts → lib/esm/dom/index.d.ts} +0 -0
- /package/{src/dom/form/form.test.ts → lib/esm/dom/types/dom.d.ts} +0 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use client"; // The navigation runtime drives same-document transitions client side.
|
|
2
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
3
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return path;
|
|
9
|
+
};
|
|
10
|
+
import { start } from "../hydrate.js";
|
|
11
|
+
/**
|
|
12
|
+
* Registered `onNavigate` hooks, fired in registration order after every
|
|
13
|
+
* completed navigation. Module-level state only: this module installs no
|
|
14
|
+
* listeners, touches no DOM, and never hydrates or calls `start()` at import
|
|
15
|
+
* time (M1 plan Step 1 invariant). The static `../hydrate.ts` import does pull
|
|
16
|
+
* in `../dom.ts`, whose jsdom bootstrap runs only in windowless Node and is
|
|
17
|
+
* skipped under a browser or jsdom where `window` already exists — so importing
|
|
18
|
+
* `./index.ts` is side-effect-free in those environments.
|
|
19
|
+
*/
|
|
20
|
+
const navigateCallbacks = [];
|
|
21
|
+
/**
|
|
22
|
+
* Register `cb` to run after every in-app navigation completes (body swapped and
|
|
23
|
+
* hydration scheduled). Invariant: callbacks fire exactly once per navigation,
|
|
24
|
+
* in registration order, with the navigation's `NavigationContext`. Used by
|
|
25
|
+
* shell code such as a GA `page_view`.
|
|
26
|
+
*/
|
|
27
|
+
export function onNavigate(cb) {
|
|
28
|
+
navigateCallbacks.push(cb);
|
|
29
|
+
}
|
|
30
|
+
/** Hooks awaiting the first load, fired once during bootstrap in registration order. */
|
|
31
|
+
const firstLoadCallbacks = [];
|
|
32
|
+
/**
|
|
33
|
+
* The first-load context, set by `bootstrap()` once the initial page hydrates.
|
|
34
|
+
* `undefined` until then. Retained so an `onFirstLoad` registered AFTER first load
|
|
35
|
+
* (e.g. a shell module that imports the runtime lazily) still receives the event.
|
|
36
|
+
*/
|
|
37
|
+
let firstLoadContext;
|
|
38
|
+
/**
|
|
39
|
+
* Register `cb` to run once, when the initial page hydrates on first document load.
|
|
40
|
+
* Invariant: if registered BEFORE bootstrap, `cb` is queued and fired during
|
|
41
|
+
* bootstrap with the first-load context (`type: "first"`). If registered AFTER first
|
|
42
|
+
* load, `cb` is invoked immediately with the retained context, so a late
|
|
43
|
+
* registration never drops the initial event (design §1). Registering installs no
|
|
44
|
+
* listeners and touches no DOM (import-side-effect-free invariant).
|
|
45
|
+
*/
|
|
46
|
+
export function onFirstLoad(cb) {
|
|
47
|
+
if (firstLoadContext) {
|
|
48
|
+
cb(firstLoadContext);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
firstLoadCallbacks.push(cb);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Attribute marking a one-time "shell" node in `<head>` (a theme bootstrap, an
|
|
55
|
+
* analytics tag): the build emits it, and the head reconciler preserves any node
|
|
56
|
+
* carrying it by identity across navigations so its inline script never re-runs.
|
|
57
|
+
*/
|
|
58
|
+
const SHELL_ATTR = "data-shell";
|
|
59
|
+
/** True for a head node the reconciler must preserve in place across navigations. */
|
|
60
|
+
function isShell(node) {
|
|
61
|
+
return node instanceof Element && node.hasAttribute(SHELL_ATTR);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Abandon the same-document path for an ordinary full document load of `url`
|
|
65
|
+
* (design "Failure modes"). Returns `null` so a fetch caller can `return fullLoad(url)`
|
|
66
|
+
* to both trigger the load and signal "stop here" — the destination becomes a normal
|
|
67
|
+
* navigation, never a broken intermediate state.
|
|
68
|
+
*/
|
|
69
|
+
function fullLoad(url) {
|
|
70
|
+
window.location.assign(url.href);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Fetch `url` and parse its body text into a detached Document via the global
|
|
75
|
+
* DOMParser. Returns the parsed document, or `null` when the same-document path
|
|
76
|
+
* must be abandoned for a full load: a non-2xx response or a network error falls
|
|
77
|
+
* back to `fullLoad(url)` so the caller aborts before reconciling. Invariant: a
|
|
78
|
+
* returned document is detached — its nodes must be adopted with
|
|
79
|
+
* `document.importNode` before insertion into the live document.
|
|
80
|
+
*/
|
|
81
|
+
async function fetchDocument(url) {
|
|
82
|
+
let response;
|
|
83
|
+
try {
|
|
84
|
+
response = await fetch(url);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return fullLoad(url); // network error
|
|
88
|
+
}
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
return fullLoad(url); // non-2xx
|
|
91
|
+
}
|
|
92
|
+
const html = await response.text();
|
|
93
|
+
return new DOMParser().parseFromString(html, "text/html");
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Reconcile the live `<head>` against `destHead`. Preserves every existing
|
|
97
|
+
* `[data-shell]` node by identity; replaces all non-shell live nodes with
|
|
98
|
+
* `destHead`'s non-shell nodes (adopted into the live document). Applies the
|
|
99
|
+
* destination `<title>` via `document.title` and mirrors `<html lang>`. Leaves
|
|
100
|
+
* the destination `#__hydration` payload in place for the subsequent `start()`.
|
|
101
|
+
*/
|
|
102
|
+
function reconcileHead(destHead) {
|
|
103
|
+
const liveHead = window.document.head;
|
|
104
|
+
// Drop every live per-page node, leaving the [data-shell] nodes untouched —
|
|
105
|
+
// preserved by identity so their inline scripts (theme, analytics) never re-run.
|
|
106
|
+
for (const node of [...liveHead.childNodes]) {
|
|
107
|
+
if (!isShell(node))
|
|
108
|
+
node.remove();
|
|
109
|
+
}
|
|
110
|
+
// Adopt the destination's per-page nodes (title, metadata, the #__hydration
|
|
111
|
+
// payload) and append them. The destination's own shell nodes are dropped —
|
|
112
|
+
// the live ones already cover them.
|
|
113
|
+
for (const node of [...destHead.childNodes]) {
|
|
114
|
+
if (isShell(node))
|
|
115
|
+
continue;
|
|
116
|
+
liveHead.appendChild(window.document.importNode(node, true));
|
|
117
|
+
}
|
|
118
|
+
// Apply <title> through document.title so it takes effect immediately, and
|
|
119
|
+
// mirror <html lang> from the destination when it differs.
|
|
120
|
+
const destRoot = destHead.ownerDocument.documentElement;
|
|
121
|
+
window.document.title = destHead.ownerDocument.title;
|
|
122
|
+
if (destRoot.lang && destRoot.lang !== window.document.documentElement.lang) {
|
|
123
|
+
window.document.documentElement.lang = destRoot.lang;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Replace the live `<body>` children with `destBody`'s children, adopted via
|
|
128
|
+
* `document.importNode`. New element instances replace the old ones — a child
|
|
129
|
+
* replacement, not an in-place patch — so the destination's island is a fresh
|
|
130
|
+
* node. Any `<script type="module">` rides along inert: a script inserted via
|
|
131
|
+
* the DOM never executes on its own, which is why `importPageModules` imports it
|
|
132
|
+
* explicitly. (`destBody` is typed `HTMLElement` because `Document.body` is.)
|
|
133
|
+
*/
|
|
134
|
+
function swapBody(destBody) {
|
|
135
|
+
const adopted = [...destBody.childNodes].map((node) => window.document.importNode(node, true));
|
|
136
|
+
window.document.body.replaceChildren(...adopted);
|
|
137
|
+
}
|
|
138
|
+
/** Matches each inline `import "<spec>";` statement, capturing the specifier. */
|
|
139
|
+
const IMPORT_STATEMENT = /import\s+["']([^"']+)["']\s*;?/g;
|
|
140
|
+
/**
|
|
141
|
+
* Extract every `import "<spec>";` specifier from `root`'s
|
|
142
|
+
* `<script type="module">` elements and dynamically import each, awaiting all.
|
|
143
|
+
* The build emits inline `import` statements (not `src` attributes, matching
|
|
144
|
+
* src/ssg/rewrite.ts), and a script node inserted via the DOM never executes on
|
|
145
|
+
* its own, so the runtime imports the specifiers itself. The ES module cache
|
|
146
|
+
* dedupes chunks already loaded this session.
|
|
147
|
+
*/
|
|
148
|
+
async function importPageModules(root) {
|
|
149
|
+
const specifiers = [];
|
|
150
|
+
for (const script of root.querySelectorAll('script[type="module"]')) {
|
|
151
|
+
for (const match of (script.textContent ?? "").matchAll(IMPORT_STATEMENT)) {
|
|
152
|
+
specifiers.push(match[1]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
await Promise.all(specifiers.map((spec) => import(__rewriteRelativeImportExtension(spec))));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The shared same-document core the Navigation API interceptor funnels into
|
|
159
|
+
* (design §2). Fetches the destination's built HTML, reconciles `<head>`, swaps
|
|
160
|
+
* `<body>` — inside a View Transition when one is available — imports the
|
|
161
|
+
* destination's page modules, hydrates, then fires `onNavigate`. Resolves when
|
|
162
|
+
* hydration has been scheduled and hooks have fired. If `fetchDocument` fell back
|
|
163
|
+
* to a full load (non-2xx or network error), it returns `null` and this aborts
|
|
164
|
+
* without reconciling, swapping, or firing hooks.
|
|
165
|
+
*/
|
|
166
|
+
export async function navigate(url, options = {}) {
|
|
167
|
+
const target = new URL(url, window.location.href);
|
|
168
|
+
const destination = await fetchDocument(target);
|
|
169
|
+
if (destination === null)
|
|
170
|
+
return; // fell back to a full document load
|
|
171
|
+
reconcileHead(destination.head);
|
|
172
|
+
// Swap the body inside a same-document View Transition when the browser
|
|
173
|
+
// supports one AND has not already animated this navigation itself (design §2
|
|
174
|
+
// step 4). startViewTransition snapshots the live DOM, runs the swap callback
|
|
175
|
+
// to mutate it, then animates the before/after states; awaiting
|
|
176
|
+
// updateCallbackDone resumes once the swap has applied (the DOM is updated),
|
|
177
|
+
// before modules import and hydration run. Where startViewTransition is absent
|
|
178
|
+
// or the UA already transitioned (hasUAVisualTransition), the swap is applied
|
|
179
|
+
// directly — degraded to an abrupt replacement, never broken (design "Failure
|
|
180
|
+
// modes").
|
|
181
|
+
const doc = window.document;
|
|
182
|
+
const applySwap = () => swapBody(destination.body);
|
|
183
|
+
if (typeof doc.startViewTransition === "function" &&
|
|
184
|
+
!options.hasUAVisualTransition) {
|
|
185
|
+
await doc.startViewTransition(applySwap).updateCallbackDone;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
applySwap();
|
|
189
|
+
}
|
|
190
|
+
await importPageModules(window.document.body);
|
|
191
|
+
// Hydrate the swapped-in body: start() reads the destination #__hydration
|
|
192
|
+
// payload (placed by reconcileHead) and schedules each island's update().
|
|
193
|
+
start(window.document.body);
|
|
194
|
+
// Report the completed navigation. title reflects the reconciled <head>; url
|
|
195
|
+
// is the absolute target; type mirrors the navigation's entry kind (a "reload"
|
|
196
|
+
// or a direct navigate() with no event reports "push"). Hooks fire once each,
|
|
197
|
+
// in registration order.
|
|
198
|
+
const { navigationType } = options;
|
|
199
|
+
const context = {
|
|
200
|
+
url: target,
|
|
201
|
+
title: window.document.title,
|
|
202
|
+
type: navigationType === "push" ||
|
|
203
|
+
navigationType === "replace" ||
|
|
204
|
+
navigationType === "traverse"
|
|
205
|
+
? navigationType
|
|
206
|
+
: "push",
|
|
207
|
+
};
|
|
208
|
+
for (const cb of navigateCallbacks)
|
|
209
|
+
cb(context);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Install the navigation interceptor. The Navigation API is the sole interception
|
|
213
|
+
* mechanism: it delivers one `navigate` event for every same-document candidate —
|
|
214
|
+
* link click, programmatic navigation, and back/forward — so a single listener
|
|
215
|
+
* replaces a click handler plus a `popstate` listener, and the API owns history
|
|
216
|
+
* and scroll restoration (so the core stays `history.pushState`-free).
|
|
217
|
+
*
|
|
218
|
+
* The Navigation API is Baseline as of Jan 2026; this project targets evergreen
|
|
219
|
+
* browsers. Where it is absent there is NO interception: links perform normal
|
|
220
|
+
* full-document navigations — degraded (no shared-runtime hydration) but never
|
|
221
|
+
* broken. That minimal alternative is the entire fallback.
|
|
222
|
+
*
|
|
223
|
+
* Called by `bootstrap()` after `start()` and before firing `onFirstLoad`. The
|
|
224
|
+
* listener is added only here, never at module top level, so importing this module
|
|
225
|
+
* stays side-effect-free. Types come from `@types/dom-navigation` (folded into
|
|
226
|
+
* lib.dom as of TS 6.0); see the tracking task in `docs/developer/TASKS.md`.
|
|
227
|
+
*/
|
|
228
|
+
function installInterceptor() {
|
|
229
|
+
if (!("navigation" in window))
|
|
230
|
+
return;
|
|
231
|
+
window.navigation.addEventListener("navigate", (event) => {
|
|
232
|
+
// Decline (let the browser navigate natively) when the API cannot intercept
|
|
233
|
+
// — cross-origin, etc. — or for a hash-only, download, or non-GET (form)
|
|
234
|
+
// navigation. Form submissions are out of scope (design §2, Summary).
|
|
235
|
+
if (!event.canIntercept)
|
|
236
|
+
return;
|
|
237
|
+
if (event.hashChange)
|
|
238
|
+
return;
|
|
239
|
+
if (event.downloadRequest !== null)
|
|
240
|
+
return;
|
|
241
|
+
if (event.formData !== null)
|
|
242
|
+
return;
|
|
243
|
+
// Claim the navigation: run the shared core as the same-document transition.
|
|
244
|
+
// navigate() fetches, reconciles <head>, swaps <body> (inside a View
|
|
245
|
+
// Transition when the browser offers one and did not already animate this
|
|
246
|
+
// navigation), imports the page module, hydrates, and fires onNavigate. The
|
|
247
|
+
// API commits the history entry. hasUAVisualTransition and navigationType are
|
|
248
|
+
// threaded through because only this interception path sees the event.
|
|
249
|
+
const { url } = event.destination;
|
|
250
|
+
event.intercept({
|
|
251
|
+
handler: () => navigate(url, {
|
|
252
|
+
hasUAVisualTransition: event.hasUAVisualTransition,
|
|
253
|
+
navigationType: event.navigationType,
|
|
254
|
+
}),
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Bootstrap route hydration for the initial document. Explicit entry — NOT run at
|
|
260
|
+
* import time (the module stays side-effect-free; tests and the M3 injected entry
|
|
261
|
+
* decide when this runs). On call it:
|
|
262
|
+
* 1. `start(window.document.body)` — hydrate the server-rendered initial islands
|
|
263
|
+
* in place (reads the initial `#__hydration` payload already in <head>).
|
|
264
|
+
* 2. `installInterceptor()` — register the Navigation API `navigate` listener to
|
|
265
|
+
* capture subsequent in-app navigations, between `start()` and `onFirstLoad`.
|
|
266
|
+
* 3. Build the first-load `NavigationContext`: `url` from `window.location.href`,
|
|
267
|
+
* `title` from `document.title`, `type: "first"`. Store it in `firstLoadContext`.
|
|
268
|
+
* 4. Fire every queued `onFirstLoad` callback once, in registration order.
|
|
269
|
+
* Invariant: `onFirstLoad` fires exactly once per bootstrap.
|
|
270
|
+
*/
|
|
271
|
+
export async function bootstrap() {
|
|
272
|
+
// 1. Hydrate the server-rendered initial islands in place. start() reads the
|
|
273
|
+
// initial #__hydration payload already in <head> and schedules each update().
|
|
274
|
+
start(window.document.body);
|
|
275
|
+
// 2. Register the Navigation API interceptor so subsequent in-app navigations
|
|
276
|
+
// are captured. Between start() and firing onFirstLoad, per design §1.
|
|
277
|
+
installInterceptor();
|
|
278
|
+
// 3. Build and retain the first-load context (design §1). url is the initial
|
|
279
|
+
// location, title the current document title, type "first".
|
|
280
|
+
firstLoadContext = {
|
|
281
|
+
url: new URL(window.location.href),
|
|
282
|
+
title: window.document.title,
|
|
283
|
+
type: "first",
|
|
284
|
+
};
|
|
285
|
+
// 4. Fire every queued onFirstLoad callback once, in registration order, then
|
|
286
|
+
// clear the queue so the event fires exactly once per bootstrap. A callback
|
|
287
|
+
// registered AFTER this point fires immediately against firstLoadContext (see
|
|
288
|
+
// onFirstLoad), so a late registration never drops the initial event.
|
|
289
|
+
for (const cb of firstLoadCallbacks)
|
|
290
|
+
cb(firstLoadContext);
|
|
291
|
+
firstLoadCallbacks.length = 0;
|
|
292
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface DocumentOptions {
|
|
2
|
+
body: Node | Node[];
|
|
3
|
+
head?: Node | Node[];
|
|
4
|
+
lang?: string;
|
|
5
|
+
doctype?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function renderToString(node: Node | Node[]): string;
|
|
8
|
+
export declare function renderDocument({ body, head, lang, doctype, }: DocumentOptions): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { XHTML_NAMESPACE_URI } from "./dom.js";
|
|
2
|
+
export function renderToString(node) {
|
|
3
|
+
if (Array.isArray(node))
|
|
4
|
+
return node.map(renderToString).join("");
|
|
5
|
+
if (node.nodeType === 1) {
|
|
6
|
+
const el = node;
|
|
7
|
+
const html = el.outerHTML;
|
|
8
|
+
const ns = el.namespaceURI;
|
|
9
|
+
if (ns && ns !== XHTML_NAMESPACE_URI && !html.includes("xmlns=")) {
|
|
10
|
+
return html.replace(/^<([^\s>]+)/, `<$1 xmlns="${ns}"`);
|
|
11
|
+
}
|
|
12
|
+
return html;
|
|
13
|
+
}
|
|
14
|
+
if (node.nodeType === 11)
|
|
15
|
+
return Array.from(node.childNodes).map(renderToString).join("");
|
|
16
|
+
if (node.nodeType === 3) {
|
|
17
|
+
return (node.textContent ?? "")
|
|
18
|
+
.replace(/&/g, "&")
|
|
19
|
+
.replace(/</g, "<")
|
|
20
|
+
.replace(/>/g, ">");
|
|
21
|
+
}
|
|
22
|
+
return "";
|
|
23
|
+
}
|
|
24
|
+
export function renderDocument({ body, head, lang = "en", doctype = "<!doctype html>", }) {
|
|
25
|
+
const headStr = head != null ? renderToString(head) : "";
|
|
26
|
+
const bodyStr = renderToString(body);
|
|
27
|
+
return `${doctype}<html lang="${lang}"><head>${headStr}</head><body>${bodyStr}</body></html>`;
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DOMElement } from "../dom.ts";
|
|
2
|
+
import type { Link } from "./link.ts";
|
|
3
|
+
export interface Router {
|
|
4
|
+
current?: string;
|
|
5
|
+
navigate: (url: string) => (event: Event) => void;
|
|
6
|
+
(target: DOMElement): DOMElement;
|
|
7
|
+
}
|
|
8
|
+
export declare const Router: {
|
|
9
|
+
local(links: Link[], index: string): Router;
|
|
10
|
+
for(links: Link[], index: string, setGlobalRouter?: boolean): Router;
|
|
11
|
+
href(link: string): string;
|
|
12
|
+
navigate(href: string): (event: Event) => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const baseURI = `${window.document.baseURI}`;
|
|
2
|
+
const normalizeHref = () => {
|
|
3
|
+
return `${location.href}/` === baseURI ? baseURI : location.href;
|
|
4
|
+
};
|
|
5
|
+
let globalRouter;
|
|
6
|
+
export const Router = {
|
|
7
|
+
local(links, index) {
|
|
8
|
+
return Router.for(links, index, false);
|
|
9
|
+
},
|
|
10
|
+
for(links, index, setGlobalRouter = true) {
|
|
11
|
+
let target;
|
|
12
|
+
const partialRouter = (t) => {
|
|
13
|
+
target = t;
|
|
14
|
+
const href = normalizeHref();
|
|
15
|
+
const route = href === baseURI ? baseURI + index : href;
|
|
16
|
+
doNavigate(route);
|
|
17
|
+
window.addEventListener("popstate", () => {
|
|
18
|
+
doNavigate(location.href);
|
|
19
|
+
});
|
|
20
|
+
return target;
|
|
21
|
+
};
|
|
22
|
+
const doNavigate = (link) => {
|
|
23
|
+
link = link.replace(baseURI, "") || index;
|
|
24
|
+
if (link === partialRouter.current) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
partialRouter.current = link;
|
|
28
|
+
target.update((links.find(({ href }) => link.endsWith(href))?.target ??
|
|
29
|
+
(() => undefined))());
|
|
30
|
+
return true;
|
|
31
|
+
};
|
|
32
|
+
const navigate = (url) => {
|
|
33
|
+
return (event) => {
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
if (doNavigate(url || index)) {
|
|
36
|
+
history.pushState(null, "", url);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
partialRouter.navigate = navigate;
|
|
41
|
+
if (setGlobalRouter) {
|
|
42
|
+
globalRouter = partialRouter;
|
|
43
|
+
}
|
|
44
|
+
return partialRouter;
|
|
45
|
+
},
|
|
46
|
+
href(link) {
|
|
47
|
+
return `${baseURI}${link.replace(/^\//, "")}`;
|
|
48
|
+
},
|
|
49
|
+
navigate(href) {
|
|
50
|
+
return globalRouter?.navigate(href);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type DenormAttrs, type DenormChildren } from "./dom.ts";
|
|
2
|
+
export declare const a: (attrs?: DenormAttrs<SVGAElement>, ...children: DenormChildren[]) => Element;
|
|
3
|
+
export declare const animate: (attrs?: DenormAttrs<SVGAnimateElement>, ...children: DenormChildren[]) => Element;
|
|
4
|
+
export declare const animateMotion: (attrs?: DenormAttrs<SVGAnimateMotionElement>, ...children: DenormChildren[]) => Element;
|
|
5
|
+
export declare const animateTransform: (attrs?: DenormAttrs<SVGAnimateTransformElement>, ...children: DenormChildren[]) => Element;
|
|
6
|
+
export declare const circle: (attrs?: DenormAttrs<SVGCircleElement>, ...children: DenormChildren[]) => Element;
|
|
7
|
+
export declare const clipPath: (attrs?: DenormAttrs<SVGClipPathElement>, ...children: DenormChildren[]) => Element;
|
|
8
|
+
export declare const defs: (attrs?: DenormAttrs<SVGDefsElement>, ...children: DenormChildren[]) => Element;
|
|
9
|
+
export declare const desc: (attrs?: DenormAttrs<SVGDescElement>, ...children: DenormChildren[]) => Element;
|
|
10
|
+
export declare const ellipse: (attrs?: DenormAttrs<SVGEllipseElement>, ...children: DenormChildren[]) => Element;
|
|
11
|
+
export declare const feBlend: (attrs?: DenormAttrs<SVGFEBlendElement>, ...children: DenormChildren[]) => Element;
|
|
12
|
+
export declare const feColorMatrix: (attrs?: DenormAttrs<SVGFEColorMatrixElement>, ...children: DenormChildren[]) => Element;
|
|
13
|
+
export declare const feComponentTransfer: (attrs?: DenormAttrs<SVGFEComponentTransferElement>, ...children: DenormChildren[]) => Element;
|
|
14
|
+
export declare const feComposite: (attrs?: DenormAttrs<SVGFECompositeElement>, ...children: DenormChildren[]) => Element;
|
|
15
|
+
export declare const feConvolveMatrix: (attrs?: DenormAttrs<SVGFEConvolveMatrixElement>, ...children: DenormChildren[]) => Element;
|
|
16
|
+
export declare const feDiffuseLighting: (attrs?: DenormAttrs<SVGFEDiffuseLightingElement>, ...children: DenormChildren[]) => Element;
|
|
17
|
+
export declare const feDisplacementMap: (attrs?: DenormAttrs<SVGFEDisplacementMapElement>, ...children: DenormChildren[]) => Element;
|
|
18
|
+
export declare const feDistantLight: (attrs?: DenormAttrs<SVGFEDistantLightElement>, ...children: DenormChildren[]) => Element;
|
|
19
|
+
export declare const feDropShadow: (attrs?: DenormAttrs<SVGFEDropShadowElement>, ...children: DenormChildren[]) => Element;
|
|
20
|
+
export declare const feFlood: (attrs?: DenormAttrs<SVGFEFloodElement>, ...children: DenormChildren[]) => Element;
|
|
21
|
+
export declare const feFuncA: (attrs?: DenormAttrs<SVGFEFuncAElement>, ...children: DenormChildren[]) => Element;
|
|
22
|
+
export declare const feFuncB: (attrs?: DenormAttrs<SVGFEFuncBElement>, ...children: DenormChildren[]) => Element;
|
|
23
|
+
export declare const feFuncG: (attrs?: DenormAttrs<SVGFEFuncGElement>, ...children: DenormChildren[]) => Element;
|
|
24
|
+
export declare const feFuncR: (attrs?: DenormAttrs<SVGFEFuncRElement>, ...children: DenormChildren[]) => Element;
|
|
25
|
+
export declare const feGaussianBlur: (attrs?: DenormAttrs<SVGFEGaussianBlurElement>, ...children: DenormChildren[]) => Element;
|
|
26
|
+
export declare const feImage: (attrs?: DenormAttrs<SVGFEImageElement>, ...children: DenormChildren[]) => Element;
|
|
27
|
+
export declare const feMerge: (attrs?: DenormAttrs<SVGFEMergeElement>, ...children: DenormChildren[]) => Element;
|
|
28
|
+
export declare const feMergeNode: (attrs?: DenormAttrs<SVGFEMergeNodeElement>, ...children: DenormChildren[]) => Element;
|
|
29
|
+
export declare const feMorphology: (attrs?: DenormAttrs<SVGFEMorphologyElement>, ...children: DenormChildren[]) => Element;
|
|
30
|
+
export declare const feOffset: (attrs?: DenormAttrs<SVGFEOffsetElement>, ...children: DenormChildren[]) => Element;
|
|
31
|
+
export declare const fePointLight: (attrs?: DenormAttrs<SVGFEPointLightElement>, ...children: DenormChildren[]) => Element;
|
|
32
|
+
export declare const feSpecularLighting: (attrs?: DenormAttrs<SVGFESpecularLightingElement>, ...children: DenormChildren[]) => Element;
|
|
33
|
+
export declare const feSpotLight: (attrs?: DenormAttrs<SVGFESpotLightElement>, ...children: DenormChildren[]) => Element;
|
|
34
|
+
export declare const feTile: (attrs?: DenormAttrs<SVGFETileElement>, ...children: DenormChildren[]) => Element;
|
|
35
|
+
export declare const feTurbulence: (attrs?: DenormAttrs<SVGFETurbulenceElement>, ...children: DenormChildren[]) => Element;
|
|
36
|
+
export declare const filter: (attrs?: DenormAttrs<SVGFilterElement>, ...children: DenormChildren[]) => Element;
|
|
37
|
+
export declare const foreignObject: (attrs?: DenormAttrs<SVGForeignObjectElement>, ...children: DenormChildren[]) => Element;
|
|
38
|
+
export declare const g: (attrs?: DenormAttrs<SVGGElement>, ...children: DenormChildren[]) => Element;
|
|
39
|
+
export declare const image: (attrs?: DenormAttrs<SVGImageElement>, ...children: DenormChildren[]) => Element;
|
|
40
|
+
export declare const line: (attrs?: DenormAttrs<SVGLineElement>, ...children: DenormChildren[]) => Element;
|
|
41
|
+
export declare const linearGradient: (attrs?: DenormAttrs<SVGLinearGradientElement>, ...children: DenormChildren[]) => Element;
|
|
42
|
+
export declare const marker: (attrs?: DenormAttrs<SVGMarkerElement>, ...children: DenormChildren[]) => Element;
|
|
43
|
+
export declare const mask: (attrs?: DenormAttrs<SVGMaskElement>, ...children: DenormChildren[]) => Element;
|
|
44
|
+
export declare const metadata: (attrs?: DenormAttrs<SVGMetadataElement>, ...children: DenormChildren[]) => Element;
|
|
45
|
+
export declare const mpath: (attrs?: DenormAttrs<SVGMPathElement>, ...children: DenormChildren[]) => Element;
|
|
46
|
+
export declare const path: (attrs?: DenormAttrs<SVGPathElement>, ...children: DenormChildren[]) => Element;
|
|
47
|
+
export declare const pattern: (attrs?: DenormAttrs<SVGPatternElement>, ...children: DenormChildren[]) => Element;
|
|
48
|
+
export declare const polygon: (attrs?: DenormAttrs<SVGPolygonElement>, ...children: DenormChildren[]) => Element;
|
|
49
|
+
export declare const polyline: (attrs?: DenormAttrs<SVGPolylineElement>, ...children: DenormChildren[]) => Element;
|
|
50
|
+
export declare const radialGradient: (attrs?: DenormAttrs<SVGRadialGradientElement>, ...children: DenormChildren[]) => Element;
|
|
51
|
+
export declare const rect: (attrs?: DenormAttrs<SVGRectElement>, ...children: DenormChildren[]) => Element;
|
|
52
|
+
export declare const script: (attrs?: DenormAttrs<SVGScriptElement>, ...children: DenormChildren[]) => Element;
|
|
53
|
+
export declare const set: (attrs?: DenormAttrs<SVGSetElement>, ...children: DenormChildren[]) => Element;
|
|
54
|
+
export declare const stop: (attrs?: DenormAttrs<SVGStopElement>, ...children: DenormChildren[]) => Element;
|
|
55
|
+
export declare const style: (attrs?: DenormAttrs<SVGStyleElement>, ...children: DenormChildren[]) => Element;
|
|
56
|
+
export declare const svg: (attrs?: DenormAttrs<SVGSVGElement>, ...children: DenormChildren[]) => Element;
|
|
57
|
+
export declare const svgswitch: (attrs?: DenormAttrs<SVGSwitchElement>, ...children: DenormChildren[]) => Element;
|
|
58
|
+
export declare const symbol: (attrs?: DenormAttrs<SVGSymbolElement>, ...children: DenormChildren[]) => Element;
|
|
59
|
+
export declare const text: (attrs?: DenormAttrs<SVGTextElement>, ...children: DenormChildren[]) => Element;
|
|
60
|
+
export declare const textPath: (attrs?: DenormAttrs<SVGTextPathElement>, ...children: DenormChildren[]) => Element;
|
|
61
|
+
export declare const title: (attrs?: DenormAttrs<SVGTitleElement>, ...children: DenormChildren[]) => Element;
|
|
62
|
+
export declare const tspan: (attrs?: DenormAttrs<SVGTSpanElement>, ...children: DenormChildren[]) => Element;
|
|
63
|
+
export declare const use: (attrs?: DenormAttrs<SVGUseElement>, ...children: DenormChildren[]) => Element;
|
|
64
|
+
export declare const view: (attrs?: DenormAttrs<SVGViewElement>, ...children: DenormChildren[]) => Element;
|
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type DenormChildren,
|
|
4
|
-
SVG_NAMESPACE_URI,
|
|
5
|
-
up,
|
|
6
|
-
} from "./dom.js";
|
|
7
|
-
|
|
8
|
-
const makeSVGElement =
|
|
9
|
-
<K extends keyof SVGElementTagNameMap>(name: K) =>
|
|
10
|
-
(
|
|
11
|
-
attrs?: DenormAttrs<SVGElementTagNameMap[K]>,
|
|
12
|
-
...children: DenormChildren[]
|
|
13
|
-
) =>
|
|
14
|
-
up(document.createElementNS(SVG_NAMESPACE_URI, name), attrs, ...children);
|
|
15
|
-
|
|
1
|
+
import { SVG_NAMESPACE_URI, up, } from "./dom.js";
|
|
2
|
+
const makeSVGElement = (name) => (attrs, ...children) => up(window.document.createElementNS(SVG_NAMESPACE_URI, name), attrs, ...children);
|
|
16
3
|
export const a = makeSVGElement("a");
|
|
17
4
|
export const animate = makeSVGElement("animate");
|
|
18
5
|
export const animateMotion = makeSVGElement("animateMotion");
|