lightview 2.3.7 → 2.3.8
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/docs/cdom.html +6 -5
- package/package.json +1 -1
- package/1769196538097-package.json +0 -43
- package/build_tmp/lightview-router.js +0 -185
- package/build_tmp/lightview-x.js +0 -1608
- package/build_tmp/lightview.js +0 -932
package/docs/cdom.html
CHANGED
|
@@ -1063,15 +1063,16 @@ const liveConfig = LightviewCDOM.hydrate(config);</code></pre>
|
|
|
1063
1063
|
</div>
|
|
1064
1064
|
|
|
1065
1065
|
<h3 id="helpers-dom">DOM & XPath</h3>
|
|
1066
|
-
<p>Structural navigation and manipulation
|
|
1066
|
+
<p>Structural navigation and manipulation. For fetching and mounting remote content, see the
|
|
1067
|
+
<a href="#helpers-network">mount()</a> helper in the Network section.
|
|
1068
|
+
</p>
|
|
1067
1069
|
<div class="code-block">
|
|
1068
1070
|
<pre><code>move(selector, location?), xpath(expression)</code></pre>
|
|
1069
1071
|
</div>
|
|
1070
1072
|
<p style="margin-top: 1rem;">
|
|
1071
|
-
|
|
1072
|
-
content
|
|
1073
|
-
|
|
1074
|
-
helper, it will automatically relocate itself upon mounting.
|
|
1073
|
+
While <code>move</code> is for local placement, <code>mount</code> is used for remote Hypermedia updates.
|
|
1074
|
+
It fetches content (cDOM, vDOM, or oDOM) and injects it into the DOM. If the content contains a
|
|
1075
|
+
<code>=move</code> helper, it will automatically relocate itself upon mounting.
|
|
1075
1076
|
</p>
|
|
1076
1077
|
<table class="api-table">
|
|
1077
1078
|
<thead>
|
package/package.json
CHANGED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "lightview",
|
|
3
|
-
"version": "2.3.7",
|
|
4
|
-
"description": "A lightweight reactive UI library with features of Bau, Juris, and HTMX",
|
|
5
|
-
"main": "lightview.js",
|
|
6
|
-
"workspaces": [
|
|
7
|
-
"jprx"
|
|
8
|
-
],
|
|
9
|
-
"directories": {
|
|
10
|
-
"doc": "docs"
|
|
11
|
-
},
|
|
12
|
-
"scripts": {
|
|
13
|
-
"dev": "wrangler pages dev . --port 3000",
|
|
14
|
-
"preview": "npm run build && wrangler pages dev ./dist --port 8788",
|
|
15
|
-
"build": "node build-bundles.mjs && node build.js",
|
|
16
|
-
"watch": "node build-bundles.mjs && node build.js --watch --env=dev",
|
|
17
|
-
"deploy": "npm run build && wrangler pages deploy dist",
|
|
18
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [],
|
|
21
|
-
"author": "Simon Y. Blackwell, AnyWhichWay LLC",
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"type": "commonjs",
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"@grucloud/bau": "^0.106.0",
|
|
26
|
-
"acorn": "^8.15.0",
|
|
27
|
-
"acorn-walk": "^8.3.4",
|
|
28
|
-
"htmx.org": "^2.0.8",
|
|
29
|
-
"jsdom": "^27.4.0",
|
|
30
|
-
"juris": "^0.9.0",
|
|
31
|
-
"react": "^19.2.3",
|
|
32
|
-
"terser": "^5.24.0",
|
|
33
|
-
"vite": "^5.0.0",
|
|
34
|
-
"vitest": "^4.0.16",
|
|
35
|
-
"wrangler": "^4.54.0"
|
|
36
|
-
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"expr-eval": "^2.0.2",
|
|
39
|
-
"jprx": "^1.3.1",
|
|
40
|
-
"linkedom": "^0.18.12",
|
|
41
|
-
"marked": "^17.0.1"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
(function() {
|
|
2
|
-
"use strict";
|
|
3
|
-
(() => {
|
|
4
|
-
const base = (shellPath) => {
|
|
5
|
-
if (typeof window === "undefined" || document.getElementById("content")) return;
|
|
6
|
-
const url = new URL(shellPath, globalThis.location.href);
|
|
7
|
-
url.searchParams.set("load", globalThis.location.pathname);
|
|
8
|
-
globalThis.location.href = url.toString();
|
|
9
|
-
};
|
|
10
|
-
const router = (options = {}) => {
|
|
11
|
-
const { base: base2 = "", contentEl, notFound, debug, onResponse, onStart } = options;
|
|
12
|
-
const chains = [];
|
|
13
|
-
const normalizePath = (p) => {
|
|
14
|
-
if (!p) return "/";
|
|
15
|
-
let hash = "";
|
|
16
|
-
if (p.includes("#")) {
|
|
17
|
-
[p, hash] = p.split("#");
|
|
18
|
-
hash = "#" + hash;
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
if (p.startsWith("http") || p.startsWith("//")) p = new URL(p, globalThis.location.origin).pathname;
|
|
22
|
-
} catch (e) {
|
|
23
|
-
}
|
|
24
|
-
if (base2 && p.startsWith(base2)) p = p.slice(base2.length);
|
|
25
|
-
return (p.replace(/\/+$/, "").replace(/^([^/])/, "/$1") || "/") + hash;
|
|
26
|
-
};
|
|
27
|
-
const createMatcher = (pattern) => {
|
|
28
|
-
if (typeof pattern === "function") return pattern;
|
|
29
|
-
return (ctx) => {
|
|
30
|
-
const { path } = ctx;
|
|
31
|
-
const pathOnly = path.split("#")[0];
|
|
32
|
-
if (pattern instanceof RegExp) {
|
|
33
|
-
const m2 = pathOnly.match(pattern);
|
|
34
|
-
return m2 ? { ...ctx, match: m2 } : null;
|
|
35
|
-
}
|
|
36
|
-
if (pattern === "*" || pattern === pathOnly) return { ...ctx, wildcard: pathOnly };
|
|
37
|
-
const keys = [];
|
|
38
|
-
const regexStr = "^" + pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\*/g, "(.*)").replace(/:([^/]+)/g, (_, k) => (keys.push(k), "([^/]+)")) + "$";
|
|
39
|
-
const m = pathOnly.match(new RegExp(regexStr));
|
|
40
|
-
if (m) {
|
|
41
|
-
const params = {};
|
|
42
|
-
keys.forEach((k, i) => params[k] = m[i + 1]);
|
|
43
|
-
return { ...ctx, params, wildcard: m[1] };
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
const createReplacer = (pat) => (ctx) => {
|
|
49
|
-
const [path, hash] = ctx.path.split("#");
|
|
50
|
-
return {
|
|
51
|
-
...ctx,
|
|
52
|
-
path: pat.replace(/\*|:([^/]+)/g, (m, k) => {
|
|
53
|
-
var _a;
|
|
54
|
-
return (k ? (_a = ctx.params) == null ? void 0 : _a[k] : ctx.wildcard) || m;
|
|
55
|
-
}) + (hash ? "#" + hash : "")
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
const fetchHandler = async (ctx) => {
|
|
59
|
-
try {
|
|
60
|
-
const pathOnly = ctx.path.split("#")[0];
|
|
61
|
-
const res = await fetch(pathOnly);
|
|
62
|
-
if (res.ok) return res;
|
|
63
|
-
} catch (e) {
|
|
64
|
-
if (debug) console.error("[Router] Fetch error:", e);
|
|
65
|
-
}
|
|
66
|
-
return null;
|
|
67
|
-
};
|
|
68
|
-
const use = (...args) => {
|
|
69
|
-
const chain = args.map((arg, i) => i === 0 && typeof arg !== "function" ? createMatcher(arg) : typeof arg === "string" ? createReplacer(arg) : arg);
|
|
70
|
-
if (contentEl && !chain.some((f) => f.name === "fetchHandler" || args.some((a) => typeof a === "function"))) chain.push(fetchHandler);
|
|
71
|
-
chains.push(chain);
|
|
72
|
-
return routerInstance;
|
|
73
|
-
};
|
|
74
|
-
const route = async (raw) => {
|
|
75
|
-
let ctx = { path: normalizePath(raw), contentEl };
|
|
76
|
-
if (debug) console.log(`[Router] Routing: ${ctx.path}`);
|
|
77
|
-
for (const chain of chains) {
|
|
78
|
-
let res = ctx, failed = false;
|
|
79
|
-
for (const fn of chain) {
|
|
80
|
-
try {
|
|
81
|
-
res = await fn(res);
|
|
82
|
-
if (res instanceof Response) return res;
|
|
83
|
-
if (!res) {
|
|
84
|
-
failed = true;
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
} catch (e) {
|
|
88
|
-
console.error("[Router] Chain error:", e);
|
|
89
|
-
failed = true;
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (!failed) ctx = typeof res === "string" ? { ...ctx, path: res } : { ...ctx, ...res };
|
|
94
|
-
}
|
|
95
|
-
return notFound ? notFound(ctx) : null;
|
|
96
|
-
};
|
|
97
|
-
const handleRequest = async (path) => {
|
|
98
|
-
var _a, _b;
|
|
99
|
-
if (onStart) onStart(path);
|
|
100
|
-
const internals = (_a = globalThis.Lightview) == null ? void 0 : _a.internals;
|
|
101
|
-
const scrollMap = (_b = internals == null ? void 0 : internals.saveScrolls) == null ? void 0 : _b.call(internals);
|
|
102
|
-
const res = await route(path);
|
|
103
|
-
if (!res) return console.warn(`[Router] No route: ${path}`);
|
|
104
|
-
if (res.ok && contentEl) {
|
|
105
|
-
contentEl.innerHTML = await res.text();
|
|
106
|
-
contentEl.querySelectorAll("script").forEach((s) => {
|
|
107
|
-
const n = document.createElement("script");
|
|
108
|
-
[...s.attributes].forEach((a) => n.setAttribute(a.name, a.value));
|
|
109
|
-
n.textContent = s.textContent;
|
|
110
|
-
s.replaceWith(n);
|
|
111
|
-
});
|
|
112
|
-
if ((internals == null ? void 0 : internals.restoreScrolls) && scrollMap) {
|
|
113
|
-
internals.restoreScrolls(scrollMap);
|
|
114
|
-
}
|
|
115
|
-
const urlParts = path.split("#");
|
|
116
|
-
const hash = urlParts.length > 1 ? "#" + urlParts[1] : "";
|
|
117
|
-
if (hash) {
|
|
118
|
-
requestAnimationFrame(() => {
|
|
119
|
-
requestAnimationFrame(() => {
|
|
120
|
-
const id = hash.slice(1);
|
|
121
|
-
const target = document.getElementById(id);
|
|
122
|
-
if (target) {
|
|
123
|
-
target.style.scrollMarginTop = "calc(var(--site-nav-height, 0px) + 2rem)";
|
|
124
|
-
target.scrollIntoView({ behavior: "smooth", block: "start", inline: "start" });
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (onResponse) await onResponse(res, path);
|
|
131
|
-
return res;
|
|
132
|
-
};
|
|
133
|
-
const navigate = (path) => {
|
|
134
|
-
const p = normalizePath(path);
|
|
135
|
-
return handleRequest(base2 + p).then((r) => {
|
|
136
|
-
let dest = (r == null ? void 0 : r.url) ? new URL(r.url, globalThis.location.origin).pathname : base2 + p;
|
|
137
|
-
if (p.includes("#") && !dest.includes("#")) {
|
|
138
|
-
dest += "#" + p.split("#")[1];
|
|
139
|
-
}
|
|
140
|
-
globalThis.history.pushState({ path: dest }, "", dest);
|
|
141
|
-
}).catch((e) => console.error("[Router] Nav error:", e));
|
|
142
|
-
};
|
|
143
|
-
const start = async () => {
|
|
144
|
-
const load = new URLSearchParams(globalThis.location.search).get("load");
|
|
145
|
-
globalThis.onpopstate = (e) => {
|
|
146
|
-
var _a;
|
|
147
|
-
return handleRequest(((_a = e.state) == null ? void 0 : _a.path) || normalizePath(globalThis.location.pathname + globalThis.location.hash));
|
|
148
|
-
};
|
|
149
|
-
document.onclick = (e) => {
|
|
150
|
-
const path = e.composedPath();
|
|
151
|
-
const a = path.find((el) => {
|
|
152
|
-
var _a;
|
|
153
|
-
return el.tagName === "A" && ((_a = el.hasAttribute) == null ? void 0 : _a.call(el, "href"));
|
|
154
|
-
});
|
|
155
|
-
if (!a || a.target === "_blank" || /^(http|#|mailto|tel)/.test(a.getAttribute("href"))) return;
|
|
156
|
-
const url = new URL(a.href, document.baseURI);
|
|
157
|
-
if (url.origin === globalThis.location.origin) {
|
|
158
|
-
e.preventDefault();
|
|
159
|
-
const fullPath = url.pathname + url.search + url.hash;
|
|
160
|
-
navigate(normalizePath(fullPath));
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
const init = load || normalizePath(globalThis.location.pathname + globalThis.location.hash);
|
|
164
|
-
globalThis.history.replaceState({ path: init }, "", base2 + init);
|
|
165
|
-
return handleRequest(init).then(() => routerInstance);
|
|
166
|
-
};
|
|
167
|
-
const routerInstance = { use, navigate, start };
|
|
168
|
-
return routerInstance;
|
|
169
|
-
};
|
|
170
|
-
const LightviewRouter = { base, router };
|
|
171
|
-
if (typeof module !== "undefined" && module.exports) module.exports = LightviewRouter;
|
|
172
|
-
else if (typeof window !== "undefined") {
|
|
173
|
-
globalThis.LightviewRouter = LightviewRouter;
|
|
174
|
-
try {
|
|
175
|
-
const script = document.currentScript;
|
|
176
|
-
if (script && script.src.includes("?")) {
|
|
177
|
-
const params = new URL(script.src).searchParams;
|
|
178
|
-
const b = params.get("base");
|
|
179
|
-
if (b) LightviewRouter.base(b);
|
|
180
|
-
}
|
|
181
|
-
} catch (e) {
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
})();
|
|
185
|
-
})();
|