@symbo.ls/router 3.14.0 → 3.14.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/index.js +10 -3
- package/package.json +3 -3
- package/dist/cjs/index.js +0 -281
- package/dist/esm/index.js +0 -261
- package/dist/iife/index.js +0 -754
package/index.js
CHANGED
|
@@ -195,14 +195,21 @@ export const router = async (path, el, state = {}, options = {}) => {
|
|
|
195
195
|
lastPathname = pathname
|
|
196
196
|
|
|
197
197
|
// Route matching - support both simple and param-based
|
|
198
|
-
let route, content, params
|
|
198
|
+
let route, routePath, content, params
|
|
199
199
|
if (opts.useParamsMatching) {
|
|
200
200
|
const match = matchRoute(pathname, element.routes, opts.level)
|
|
201
|
-
route
|
|
201
|
+
// FRAMEWORK-2: state.route must reflect the matched pattern key
|
|
202
|
+
// (e.g. `/players/:id`), not the literal first URL segment, so
|
|
203
|
+
// consumers and devtools can branch on which route handler fired.
|
|
204
|
+
// The first-segment value is still exposed as `routePath` for the
|
|
205
|
+
// rare consumer that needs the URL piece directly.
|
|
206
|
+
route = match.key
|
|
207
|
+
routePath = match.routePath
|
|
202
208
|
content = match.content
|
|
203
209
|
params = match.params
|
|
204
210
|
} else {
|
|
205
211
|
route = getActiveRoute(opts.level, pathname)
|
|
212
|
+
routePath = route
|
|
206
213
|
content = element.routes[route || '/'] || element.routes['/*']
|
|
207
214
|
params = {}
|
|
208
215
|
}
|
|
@@ -243,7 +250,7 @@ export const router = async (path, el, state = {}, options = {}) => {
|
|
|
243
250
|
}
|
|
244
251
|
|
|
245
252
|
if (pathChanged || !hashChanged) {
|
|
246
|
-
const stateUpdate = { route, hash, debugging: false }
|
|
253
|
+
const stateUpdate = { route, routePath, hash, debugging: false }
|
|
247
254
|
if (Object.keys(params).length) stateUpdate.params = params
|
|
248
255
|
if (Object.keys(query).length) stateUpdate.query = query
|
|
249
256
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/router",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.1",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"prepublish": "npm run build && npm run copy:package:cjs"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@symbo.ls/element": "^3.14.
|
|
29
|
-
"@symbo.ls/utils": "^3.14.
|
|
28
|
+
"@symbo.ls/element": "^3.14.3",
|
|
29
|
+
"@symbo.ls/utils": "^3.14.2"
|
|
30
30
|
},
|
|
31
31
|
"gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
|
|
32
32
|
"devDependencies": {
|
package/dist/cjs/index.js
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var index_exports = {};
|
|
20
|
-
__export(index_exports, {
|
|
21
|
-
default: () => index_default,
|
|
22
|
-
getActiveRoute: () => getActiveRoute,
|
|
23
|
-
lastLevel: () => lastLevel,
|
|
24
|
-
lastPathname: () => lastPathname,
|
|
25
|
-
matchRoute: () => matchRoute,
|
|
26
|
-
parseQuery: () => parseQuery,
|
|
27
|
-
parseRoutePattern: () => parseRoutePattern,
|
|
28
|
-
router: () => router,
|
|
29
|
-
runGuards: () => runGuards
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(index_exports);
|
|
32
|
-
var import_utils = require("@symbo.ls/utils");
|
|
33
|
-
const paramPattern = /^:(.+)/;
|
|
34
|
-
const wildcardPattern = /^\*$/;
|
|
35
|
-
const routeCache = /* @__PURE__ */ new Map();
|
|
36
|
-
const parseRoutePattern = (pattern) => {
|
|
37
|
-
const cached = routeCache.get(pattern);
|
|
38
|
-
if (cached) return cached;
|
|
39
|
-
const segments = pattern.replace(/^\//, "").split("/");
|
|
40
|
-
const params = [];
|
|
41
|
-
let hasWildcard = false;
|
|
42
|
-
for (let i = 0; i < segments.length; i++) {
|
|
43
|
-
const match = segments[i].match(paramPattern);
|
|
44
|
-
if (match) {
|
|
45
|
-
params.push({ index: i, name: match[1] });
|
|
46
|
-
} else if (wildcardPattern.test(segments[i])) {
|
|
47
|
-
hasWildcard = true;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
const result = { segments, params, hasWildcard, pattern };
|
|
51
|
-
routeCache.set(pattern, result);
|
|
52
|
-
return result;
|
|
53
|
-
};
|
|
54
|
-
const matchRoute = (pathname, routes, level = 0) => {
|
|
55
|
-
const pathSegments = pathname.replace(/^\//, "").split("/").filter(Boolean);
|
|
56
|
-
const relevantSegments = pathSegments.slice(level);
|
|
57
|
-
const routePath = "/" + (relevantSegments[0] || "");
|
|
58
|
-
let bestMatch = null;
|
|
59
|
-
let bestScore = -1;
|
|
60
|
-
let matchedParams = {};
|
|
61
|
-
for (const key in routes) {
|
|
62
|
-
if (key === "/*") continue;
|
|
63
|
-
const parsed = parseRoutePattern(key);
|
|
64
|
-
const score = scoreMatch(relevantSegments, parsed);
|
|
65
|
-
if (score > bestScore) {
|
|
66
|
-
bestScore = score;
|
|
67
|
-
bestMatch = key;
|
|
68
|
-
matchedParams = extractParams(relevantSegments, parsed);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (!bestMatch && routes["/*"]) {
|
|
72
|
-
bestMatch = "/*";
|
|
73
|
-
}
|
|
74
|
-
return {
|
|
75
|
-
key: bestMatch,
|
|
76
|
-
content: bestMatch ? routes[bestMatch] : null,
|
|
77
|
-
params: matchedParams,
|
|
78
|
-
routePath
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
const scoreMatch = (pathSegments, parsed) => {
|
|
82
|
-
const { segments, hasWildcard } = parsed;
|
|
83
|
-
if (!hasWildcard && segments.length !== pathSegments.length && segments.length !== 1) {
|
|
84
|
-
if (segments.length > pathSegments.length) return -1;
|
|
85
|
-
}
|
|
86
|
-
let score = 0;
|
|
87
|
-
const len = Math.min(segments.length, pathSegments.length);
|
|
88
|
-
for (let i = 0; i < len; i++) {
|
|
89
|
-
if (segments[i] === pathSegments[i]) {
|
|
90
|
-
score += 3;
|
|
91
|
-
} else if (paramPattern.test(segments[i])) {
|
|
92
|
-
score += 1;
|
|
93
|
-
} else if (wildcardPattern.test(segments[i])) {
|
|
94
|
-
score += 0.5;
|
|
95
|
-
} else {
|
|
96
|
-
return -1;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return score;
|
|
100
|
-
};
|
|
101
|
-
const extractParams = (pathSegments, parsed) => {
|
|
102
|
-
const params = {};
|
|
103
|
-
for (const { index, name } of parsed.params) {
|
|
104
|
-
if (pathSegments[index]) {
|
|
105
|
-
params[name] = decodeURIComponent(pathSegments[index]);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return params;
|
|
109
|
-
};
|
|
110
|
-
const parseQuery = (search) => {
|
|
111
|
-
if (!search || search === "?") return {};
|
|
112
|
-
const params = {};
|
|
113
|
-
const searchParams = new URLSearchParams(search);
|
|
114
|
-
searchParams.forEach((value, key) => {
|
|
115
|
-
if (params[key] !== void 0) {
|
|
116
|
-
if (!Array.isArray(params[key])) params[key] = [params[key]];
|
|
117
|
-
params[key].push(value);
|
|
118
|
-
} else {
|
|
119
|
-
params[key] = value;
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
return params;
|
|
123
|
-
};
|
|
124
|
-
const runGuards = async (guards, context) => {
|
|
125
|
-
if (!guards || !guards.length) return true;
|
|
126
|
-
for (const guard of guards) {
|
|
127
|
-
const result = await guard(context);
|
|
128
|
-
if (result === false) return false;
|
|
129
|
-
if (typeof result === "string") return result;
|
|
130
|
-
}
|
|
131
|
-
return true;
|
|
132
|
-
};
|
|
133
|
-
const getActiveRoute = (level = 0, route) => {
|
|
134
|
-
if (!route) route = typeof import_utils.window !== "undefined" ? import_utils.window.location.pathname : "/";
|
|
135
|
-
const routeArray = route.split("/");
|
|
136
|
-
const activeRoute = routeArray[level + 1];
|
|
137
|
-
if (activeRoute) return `/${activeRoute}`;
|
|
138
|
-
};
|
|
139
|
-
let lastPathname;
|
|
140
|
-
let lastLevel = 0;
|
|
141
|
-
const normalizePath = (p) => !p || p === "srcdoc" || p === "about:srcdoc" ? "/" : p;
|
|
142
|
-
const defaultOptions = {
|
|
143
|
-
level: lastLevel,
|
|
144
|
-
pushState: true,
|
|
145
|
-
initialRender: false,
|
|
146
|
-
scrollToTop: true,
|
|
147
|
-
scrollToNode: false,
|
|
148
|
-
scrollNode: import_utils.document && import_utils.document.documentElement,
|
|
149
|
-
scrollBody: false,
|
|
150
|
-
useFragment: false,
|
|
151
|
-
updateState: true,
|
|
152
|
-
scrollToOffset: 0,
|
|
153
|
-
contentElementKey: "content",
|
|
154
|
-
scrollToOptions: { behavior: "smooth" },
|
|
155
|
-
useParamsMatching: true
|
|
156
|
-
};
|
|
157
|
-
const router = async (path, el, state = {}, options = {}) => {
|
|
158
|
-
const element = el || void 0;
|
|
159
|
-
const win = element?.context?.window || import_utils.window;
|
|
160
|
-
const doc = element?.context?.document || import_utils.document;
|
|
161
|
-
const opts = {
|
|
162
|
-
...defaultOptions,
|
|
163
|
-
...element.context.routerOptions,
|
|
164
|
-
...options
|
|
165
|
-
};
|
|
166
|
-
lastLevel = opts.lastLevel;
|
|
167
|
-
const ref = element.__ref;
|
|
168
|
-
if (opts.contentElementKey !== "content" && opts.contentElementKey !== ref.contentElementKey || !ref.contentElementKey) {
|
|
169
|
-
ref.contentElementKey = opts.contentElementKey || "content";
|
|
170
|
-
}
|
|
171
|
-
const contentElementKey = ref.contentElementKey || opts.contentElementKey || "content";
|
|
172
|
-
const origin = win.location.origin !== "null" ? win.location.origin : "http://localhost";
|
|
173
|
-
path = normalizePath(path);
|
|
174
|
-
const urlObj = new win.URL(origin + path);
|
|
175
|
-
const { pathname, search, hash } = urlObj;
|
|
176
|
-
const query = parseQuery(search);
|
|
177
|
-
const rootNode = element.node;
|
|
178
|
-
const hashChanged = hash && hash !== win.location.hash.slice(1);
|
|
179
|
-
const pathChanged = pathname !== lastPathname;
|
|
180
|
-
lastPathname = pathname;
|
|
181
|
-
let route, content, params;
|
|
182
|
-
if (opts.useParamsMatching) {
|
|
183
|
-
const match = matchRoute(pathname, element.routes, opts.level);
|
|
184
|
-
route = match.routePath;
|
|
185
|
-
content = match.content;
|
|
186
|
-
params = match.params;
|
|
187
|
-
} else {
|
|
188
|
-
route = getActiveRoute(opts.level, pathname);
|
|
189
|
-
content = element.routes[route || "/"] || element.routes["/*"];
|
|
190
|
-
params = {};
|
|
191
|
-
}
|
|
192
|
-
const scrollNode = opts.scrollToNode ? rootNode : opts.scrollNode;
|
|
193
|
-
if (element.state?.root?.debugging) {
|
|
194
|
-
element.state.root.debugging = false;
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
if (!content) {
|
|
198
|
-
if (opts.onNotFound) {
|
|
199
|
-
opts.onNotFound({ pathname, route, element });
|
|
200
|
-
} else if (!opts.silent) {
|
|
201
|
-
console.warn("[smbls/router] no content matched for path", pathname, "\u2014 available routes:", Object.keys(element.routes || {}));
|
|
202
|
-
}
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (opts.guards && opts.guards.length) {
|
|
206
|
-
const guardContext = { pathname, route, params, query, hash, element, state };
|
|
207
|
-
const guardResult = await runGuards(opts.guards, guardContext);
|
|
208
|
-
if (guardResult === false) return;
|
|
209
|
-
if (typeof guardResult === "string") {
|
|
210
|
-
return router(guardResult, el, state, { ...options, guards: [] });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
if (opts.pushState) {
|
|
214
|
-
try {
|
|
215
|
-
win.history.pushState(state, null, pathname + (search || "") + (hash || ""));
|
|
216
|
-
} catch (e) {
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
if (pathChanged || !hashChanged) {
|
|
220
|
-
const stateUpdate = { route, hash, debugging: false };
|
|
221
|
-
if (Object.keys(params).length) stateUpdate.params = params;
|
|
222
|
-
if (Object.keys(query).length) stateUpdate.query = query;
|
|
223
|
-
if (opts.updateState) {
|
|
224
|
-
element.state.update(
|
|
225
|
-
stateUpdate,
|
|
226
|
-
{ preventContentUpdate: true }
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
if (contentElementKey && opts.removeOldElement) {
|
|
230
|
-
element[contentElementKey].remove();
|
|
231
|
-
}
|
|
232
|
-
const originContent = element.__ref?.origin?.content;
|
|
233
|
-
const contentStyles = {};
|
|
234
|
-
if (originContent) {
|
|
235
|
-
for (const k in originContent) {
|
|
236
|
-
const v = originContent[k];
|
|
237
|
-
if (k === "__ref" || k === "props" || k === "node" || k === "parent" || k === "key") continue;
|
|
238
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "object" && v !== null && !v.node && !v.__ref) {
|
|
239
|
-
contentStyles[k] = v;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const nextContent = {
|
|
244
|
-
...contentStyles,
|
|
245
|
-
...typeof content === "object" ? content : { extends: content }
|
|
246
|
-
};
|
|
247
|
-
if (opts.useFragment) nextContent.tag = "fragment";
|
|
248
|
-
try {
|
|
249
|
-
element.set(nextContent, { contentElementKey });
|
|
250
|
-
} catch (err) {
|
|
251
|
-
console.error("[smbls/router] failed to render route content", pathname, err);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
if (opts.scrollToTop && scrollNode?.scrollTo) {
|
|
255
|
-
scrollNode.scrollTo({
|
|
256
|
-
...opts.scrollToOptions || {},
|
|
257
|
-
top: 0,
|
|
258
|
-
left: 0
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
if (opts.scrollToNode && content[contentElementKey]?.node?.scrollTo) {
|
|
262
|
-
content[contentElementKey].node.scrollTo({
|
|
263
|
-
...opts.scrollToOptions || {},
|
|
264
|
-
top: 0,
|
|
265
|
-
left: 0
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
if (hash) {
|
|
269
|
-
const activeNode = doc.getElementById(hash);
|
|
270
|
-
if (activeNode && scrollNode?.scrollTo) {
|
|
271
|
-
const top = activeNode.getBoundingClientRect().top + rootNode.scrollTop - (opts.scrollToOffset || 0);
|
|
272
|
-
scrollNode.scrollTo({
|
|
273
|
-
...opts.scrollToOptions || {},
|
|
274
|
-
top,
|
|
275
|
-
left: 0
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
(0, import_utils.triggerEventOn)("routeChanged", element, opts);
|
|
280
|
-
};
|
|
281
|
-
var index_default = router;
|
package/dist/esm/index.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
import { document, window, triggerEventOn } from "@symbo.ls/utils";
|
|
2
|
-
const paramPattern = /^:(.+)/;
|
|
3
|
-
const wildcardPattern = /^\*$/;
|
|
4
|
-
const routeCache = /* @__PURE__ */ new Map();
|
|
5
|
-
const parseRoutePattern = (pattern) => {
|
|
6
|
-
const cached = routeCache.get(pattern);
|
|
7
|
-
if (cached) return cached;
|
|
8
|
-
const segments = pattern.replace(/^\//, "").split("/");
|
|
9
|
-
const params = [];
|
|
10
|
-
let hasWildcard = false;
|
|
11
|
-
for (let i = 0; i < segments.length; i++) {
|
|
12
|
-
const match = segments[i].match(paramPattern);
|
|
13
|
-
if (match) {
|
|
14
|
-
params.push({ index: i, name: match[1] });
|
|
15
|
-
} else if (wildcardPattern.test(segments[i])) {
|
|
16
|
-
hasWildcard = true;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
const result = { segments, params, hasWildcard, pattern };
|
|
20
|
-
routeCache.set(pattern, result);
|
|
21
|
-
return result;
|
|
22
|
-
};
|
|
23
|
-
const matchRoute = (pathname, routes, level = 0) => {
|
|
24
|
-
const pathSegments = pathname.replace(/^\//, "").split("/").filter(Boolean);
|
|
25
|
-
const relevantSegments = pathSegments.slice(level);
|
|
26
|
-
const routePath = "/" + (relevantSegments[0] || "");
|
|
27
|
-
let bestMatch = null;
|
|
28
|
-
let bestScore = -1;
|
|
29
|
-
let matchedParams = {};
|
|
30
|
-
for (const key in routes) {
|
|
31
|
-
if (key === "/*") continue;
|
|
32
|
-
const parsed = parseRoutePattern(key);
|
|
33
|
-
const score = scoreMatch(relevantSegments, parsed);
|
|
34
|
-
if (score > bestScore) {
|
|
35
|
-
bestScore = score;
|
|
36
|
-
bestMatch = key;
|
|
37
|
-
matchedParams = extractParams(relevantSegments, parsed);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (!bestMatch && routes["/*"]) {
|
|
41
|
-
bestMatch = "/*";
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
key: bestMatch,
|
|
45
|
-
content: bestMatch ? routes[bestMatch] : null,
|
|
46
|
-
params: matchedParams,
|
|
47
|
-
routePath
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
const scoreMatch = (pathSegments, parsed) => {
|
|
51
|
-
const { segments, hasWildcard } = parsed;
|
|
52
|
-
if (!hasWildcard && segments.length !== pathSegments.length && segments.length !== 1) {
|
|
53
|
-
if (segments.length > pathSegments.length) return -1;
|
|
54
|
-
}
|
|
55
|
-
let score = 0;
|
|
56
|
-
const len = Math.min(segments.length, pathSegments.length);
|
|
57
|
-
for (let i = 0; i < len; i++) {
|
|
58
|
-
if (segments[i] === pathSegments[i]) {
|
|
59
|
-
score += 3;
|
|
60
|
-
} else if (paramPattern.test(segments[i])) {
|
|
61
|
-
score += 1;
|
|
62
|
-
} else if (wildcardPattern.test(segments[i])) {
|
|
63
|
-
score += 0.5;
|
|
64
|
-
} else {
|
|
65
|
-
return -1;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return score;
|
|
69
|
-
};
|
|
70
|
-
const extractParams = (pathSegments, parsed) => {
|
|
71
|
-
const params = {};
|
|
72
|
-
for (const { index, name } of parsed.params) {
|
|
73
|
-
if (pathSegments[index]) {
|
|
74
|
-
params[name] = decodeURIComponent(pathSegments[index]);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return params;
|
|
78
|
-
};
|
|
79
|
-
const parseQuery = (search) => {
|
|
80
|
-
if (!search || search === "?") return {};
|
|
81
|
-
const params = {};
|
|
82
|
-
const searchParams = new URLSearchParams(search);
|
|
83
|
-
searchParams.forEach((value, key) => {
|
|
84
|
-
if (params[key] !== void 0) {
|
|
85
|
-
if (!Array.isArray(params[key])) params[key] = [params[key]];
|
|
86
|
-
params[key].push(value);
|
|
87
|
-
} else {
|
|
88
|
-
params[key] = value;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
return params;
|
|
92
|
-
};
|
|
93
|
-
const runGuards = async (guards, context) => {
|
|
94
|
-
if (!guards || !guards.length) return true;
|
|
95
|
-
for (const guard of guards) {
|
|
96
|
-
const result = await guard(context);
|
|
97
|
-
if (result === false) return false;
|
|
98
|
-
if (typeof result === "string") return result;
|
|
99
|
-
}
|
|
100
|
-
return true;
|
|
101
|
-
};
|
|
102
|
-
const getActiveRoute = (level = 0, route) => {
|
|
103
|
-
if (!route) route = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
104
|
-
const routeArray = route.split("/");
|
|
105
|
-
const activeRoute = routeArray[level + 1];
|
|
106
|
-
if (activeRoute) return `/${activeRoute}`;
|
|
107
|
-
};
|
|
108
|
-
let lastPathname;
|
|
109
|
-
let lastLevel = 0;
|
|
110
|
-
const normalizePath = (p) => !p || p === "srcdoc" || p === "about:srcdoc" ? "/" : p;
|
|
111
|
-
const defaultOptions = {
|
|
112
|
-
level: lastLevel,
|
|
113
|
-
pushState: true,
|
|
114
|
-
initialRender: false,
|
|
115
|
-
scrollToTop: true,
|
|
116
|
-
scrollToNode: false,
|
|
117
|
-
scrollNode: document && document.documentElement,
|
|
118
|
-
scrollBody: false,
|
|
119
|
-
useFragment: false,
|
|
120
|
-
updateState: true,
|
|
121
|
-
scrollToOffset: 0,
|
|
122
|
-
contentElementKey: "content",
|
|
123
|
-
scrollToOptions: { behavior: "smooth" },
|
|
124
|
-
useParamsMatching: true
|
|
125
|
-
};
|
|
126
|
-
const router = async (path, el, state = {}, options = {}) => {
|
|
127
|
-
const element = el || void 0;
|
|
128
|
-
const win = element?.context?.window || window;
|
|
129
|
-
const doc = element?.context?.document || document;
|
|
130
|
-
const opts = {
|
|
131
|
-
...defaultOptions,
|
|
132
|
-
...element.context.routerOptions,
|
|
133
|
-
...options
|
|
134
|
-
};
|
|
135
|
-
lastLevel = opts.lastLevel;
|
|
136
|
-
const ref = element.__ref;
|
|
137
|
-
if (opts.contentElementKey !== "content" && opts.contentElementKey !== ref.contentElementKey || !ref.contentElementKey) {
|
|
138
|
-
ref.contentElementKey = opts.contentElementKey || "content";
|
|
139
|
-
}
|
|
140
|
-
const contentElementKey = ref.contentElementKey || opts.contentElementKey || "content";
|
|
141
|
-
const origin = win.location.origin !== "null" ? win.location.origin : "http://localhost";
|
|
142
|
-
path = normalizePath(path);
|
|
143
|
-
const urlObj = new win.URL(origin + path);
|
|
144
|
-
const { pathname, search, hash } = urlObj;
|
|
145
|
-
const query = parseQuery(search);
|
|
146
|
-
const rootNode = element.node;
|
|
147
|
-
const hashChanged = hash && hash !== win.location.hash.slice(1);
|
|
148
|
-
const pathChanged = pathname !== lastPathname;
|
|
149
|
-
lastPathname = pathname;
|
|
150
|
-
let route, content, params;
|
|
151
|
-
if (opts.useParamsMatching) {
|
|
152
|
-
const match = matchRoute(pathname, element.routes, opts.level);
|
|
153
|
-
route = match.routePath;
|
|
154
|
-
content = match.content;
|
|
155
|
-
params = match.params;
|
|
156
|
-
} else {
|
|
157
|
-
route = getActiveRoute(opts.level, pathname);
|
|
158
|
-
content = element.routes[route || "/"] || element.routes["/*"];
|
|
159
|
-
params = {};
|
|
160
|
-
}
|
|
161
|
-
const scrollNode = opts.scrollToNode ? rootNode : opts.scrollNode;
|
|
162
|
-
if (element.state?.root?.debugging) {
|
|
163
|
-
element.state.root.debugging = false;
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
if (!content) {
|
|
167
|
-
if (opts.onNotFound) {
|
|
168
|
-
opts.onNotFound({ pathname, route, element });
|
|
169
|
-
} else if (!opts.silent) {
|
|
170
|
-
console.warn("[smbls/router] no content matched for path", pathname, "\u2014 available routes:", Object.keys(element.routes || {}));
|
|
171
|
-
}
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
if (opts.guards && opts.guards.length) {
|
|
175
|
-
const guardContext = { pathname, route, params, query, hash, element, state };
|
|
176
|
-
const guardResult = await runGuards(opts.guards, guardContext);
|
|
177
|
-
if (guardResult === false) return;
|
|
178
|
-
if (typeof guardResult === "string") {
|
|
179
|
-
return router(guardResult, el, state, { ...options, guards: [] });
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (opts.pushState) {
|
|
183
|
-
try {
|
|
184
|
-
win.history.pushState(state, null, pathname + (search || "") + (hash || ""));
|
|
185
|
-
} catch (e) {
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (pathChanged || !hashChanged) {
|
|
189
|
-
const stateUpdate = { route, hash, debugging: false };
|
|
190
|
-
if (Object.keys(params).length) stateUpdate.params = params;
|
|
191
|
-
if (Object.keys(query).length) stateUpdate.query = query;
|
|
192
|
-
if (opts.updateState) {
|
|
193
|
-
element.state.update(
|
|
194
|
-
stateUpdate,
|
|
195
|
-
{ preventContentUpdate: true }
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
if (contentElementKey && opts.removeOldElement) {
|
|
199
|
-
element[contentElementKey].remove();
|
|
200
|
-
}
|
|
201
|
-
const originContent = element.__ref?.origin?.content;
|
|
202
|
-
const contentStyles = {};
|
|
203
|
-
if (originContent) {
|
|
204
|
-
for (const k in originContent) {
|
|
205
|
-
const v = originContent[k];
|
|
206
|
-
if (k === "__ref" || k === "props" || k === "node" || k === "parent" || k === "key") continue;
|
|
207
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "object" && v !== null && !v.node && !v.__ref) {
|
|
208
|
-
contentStyles[k] = v;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const nextContent = {
|
|
213
|
-
...contentStyles,
|
|
214
|
-
...typeof content === "object" ? content : { extends: content }
|
|
215
|
-
};
|
|
216
|
-
if (opts.useFragment) nextContent.tag = "fragment";
|
|
217
|
-
try {
|
|
218
|
-
element.set(nextContent, { contentElementKey });
|
|
219
|
-
} catch (err) {
|
|
220
|
-
console.error("[smbls/router] failed to render route content", pathname, err);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
if (opts.scrollToTop && scrollNode?.scrollTo) {
|
|
224
|
-
scrollNode.scrollTo({
|
|
225
|
-
...opts.scrollToOptions || {},
|
|
226
|
-
top: 0,
|
|
227
|
-
left: 0
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
if (opts.scrollToNode && content[contentElementKey]?.node?.scrollTo) {
|
|
231
|
-
content[contentElementKey].node.scrollTo({
|
|
232
|
-
...opts.scrollToOptions || {},
|
|
233
|
-
top: 0,
|
|
234
|
-
left: 0
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
if (hash) {
|
|
238
|
-
const activeNode = doc.getElementById(hash);
|
|
239
|
-
if (activeNode && scrollNode?.scrollTo) {
|
|
240
|
-
const top = activeNode.getBoundingClientRect().top + rootNode.scrollTop - (opts.scrollToOffset || 0);
|
|
241
|
-
scrollNode.scrollTo({
|
|
242
|
-
...opts.scrollToOptions || {},
|
|
243
|
-
top,
|
|
244
|
-
left: 0
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
triggerEventOn("routeChanged", element, opts);
|
|
249
|
-
};
|
|
250
|
-
var index_default = router;
|
|
251
|
-
export {
|
|
252
|
-
index_default as default,
|
|
253
|
-
getActiveRoute,
|
|
254
|
-
lastLevel,
|
|
255
|
-
lastPathname,
|
|
256
|
-
matchRoute,
|
|
257
|
-
parseQuery,
|
|
258
|
-
parseRoutePattern,
|
|
259
|
-
router,
|
|
260
|
-
runGuards
|
|
261
|
-
};
|
package/dist/iife/index.js
DELETED
|
@@ -1,754 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var DomqlRouter = (() => {
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __esm = (fn, res) => function __init() {
|
|
8
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
9
|
-
};
|
|
10
|
-
var __export = (target, all) => {
|
|
11
|
-
for (var name in all)
|
|
12
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
-
};
|
|
14
|
-
var __copyProps = (to, from, except, desc) => {
|
|
15
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
-
for (let key of __getOwnPropNames(from))
|
|
17
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
-
}
|
|
20
|
-
return to;
|
|
21
|
-
};
|
|
22
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
-
|
|
24
|
-
// ../../packages/utils/globals.js
|
|
25
|
-
var window2, document2;
|
|
26
|
-
var init_globals = __esm({
|
|
27
|
-
"../../packages/utils/globals.js"() {
|
|
28
|
-
"use strict";
|
|
29
|
-
window2 = globalThis;
|
|
30
|
-
document2 = window2.document;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// ../../packages/utils/node.js
|
|
35
|
-
var init_node = __esm({
|
|
36
|
-
"../../packages/utils/node.js"() {
|
|
37
|
-
"use strict";
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// ../../packages/utils/types.js
|
|
42
|
-
var isFunction;
|
|
43
|
-
var init_types = __esm({
|
|
44
|
-
"../../packages/utils/types.js"() {
|
|
45
|
-
"use strict";
|
|
46
|
-
isFunction = (arg) => typeof arg === "function";
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// ../../packages/utils/array.js
|
|
51
|
-
var init_array = __esm({
|
|
52
|
-
"../../packages/utils/array.js"() {
|
|
53
|
-
"use strict";
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// ../../packages/utils/string.js
|
|
58
|
-
var init_string = __esm({
|
|
59
|
-
"../../packages/utils/string.js"() {
|
|
60
|
-
"use strict";
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// ../../packages/utils/keys.js
|
|
65
|
-
var STATE_METHODS, PROPS_METHODS, METHODS, METHODS_EXL;
|
|
66
|
-
var init_keys = __esm({
|
|
67
|
-
"../../packages/utils/keys.js"() {
|
|
68
|
-
"use strict";
|
|
69
|
-
STATE_METHODS = /* @__PURE__ */ new Set([
|
|
70
|
-
"update",
|
|
71
|
-
"parse",
|
|
72
|
-
"clean",
|
|
73
|
-
"create",
|
|
74
|
-
"destroy",
|
|
75
|
-
"add",
|
|
76
|
-
"toggle",
|
|
77
|
-
"remove",
|
|
78
|
-
"apply",
|
|
79
|
-
"set",
|
|
80
|
-
"reset",
|
|
81
|
-
"replace",
|
|
82
|
-
"quietReplace",
|
|
83
|
-
"quietUpdate",
|
|
84
|
-
"applyReplace",
|
|
85
|
-
"applyFunction",
|
|
86
|
-
"keys",
|
|
87
|
-
"values",
|
|
88
|
-
"ref",
|
|
89
|
-
"rootUpdate",
|
|
90
|
-
"parentUpdate",
|
|
91
|
-
"parent",
|
|
92
|
-
"__element",
|
|
93
|
-
"__depends",
|
|
94
|
-
"__ref",
|
|
95
|
-
"__children",
|
|
96
|
-
"root",
|
|
97
|
-
"setByPath",
|
|
98
|
-
"setPathCollection",
|
|
99
|
-
"removeByPath",
|
|
100
|
-
"removePathCollection",
|
|
101
|
-
"getByPath"
|
|
102
|
-
]);
|
|
103
|
-
PROPS_METHODS = /* @__PURE__ */ new Set(["update", "__element"]);
|
|
104
|
-
METHODS = /* @__PURE__ */ new Set([
|
|
105
|
-
"set",
|
|
106
|
-
"reset",
|
|
107
|
-
"update",
|
|
108
|
-
"remove",
|
|
109
|
-
"updateContent",
|
|
110
|
-
"removeContent",
|
|
111
|
-
"lookup",
|
|
112
|
-
"lookdown",
|
|
113
|
-
"lookdownAll",
|
|
114
|
-
"getRef",
|
|
115
|
-
"getPath",
|
|
116
|
-
"setNodeStyles",
|
|
117
|
-
"spotByPath",
|
|
118
|
-
"keys",
|
|
119
|
-
"parse",
|
|
120
|
-
"setProps",
|
|
121
|
-
"parseDeep",
|
|
122
|
-
"variables",
|
|
123
|
-
"if",
|
|
124
|
-
"log",
|
|
125
|
-
"verbose",
|
|
126
|
-
"warn",
|
|
127
|
-
"error",
|
|
128
|
-
"call",
|
|
129
|
-
"nextElement",
|
|
130
|
-
"previousElement",
|
|
131
|
-
"getRootState",
|
|
132
|
-
"getRoot",
|
|
133
|
-
"getRootData",
|
|
134
|
-
"getRootContext",
|
|
135
|
-
"getContext",
|
|
136
|
-
"getQuery",
|
|
137
|
-
"getDB",
|
|
138
|
-
"getChildren",
|
|
139
|
-
"preventContentUpdate",
|
|
140
|
-
"preventContentRecreate"
|
|
141
|
-
]);
|
|
142
|
-
METHODS_EXL = /* @__PURE__ */ new Set([
|
|
143
|
-
"node",
|
|
144
|
-
"context",
|
|
145
|
-
"extends",
|
|
146
|
-
"__element",
|
|
147
|
-
"__ref",
|
|
148
|
-
...METHODS,
|
|
149
|
-
...STATE_METHODS,
|
|
150
|
-
...PROPS_METHODS
|
|
151
|
-
]);
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// ../../packages/utils/object.js
|
|
156
|
-
var init_object = __esm({
|
|
157
|
-
"../../packages/utils/object.js"() {
|
|
158
|
-
"use strict";
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// ../../packages/utils/key.js
|
|
163
|
-
var init_key = __esm({
|
|
164
|
-
"../../packages/utils/key.js"() {
|
|
165
|
-
"use strict";
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// ../../packages/utils/env.js
|
|
170
|
-
var init_env = __esm({
|
|
171
|
-
"../../packages/utils/env.js"() {
|
|
172
|
-
"use strict";
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// ../../packages/utils/function.js
|
|
177
|
-
var resolveHandler, runPluginHook;
|
|
178
|
-
var init_function = __esm({
|
|
179
|
-
"../../packages/utils/function.js"() {
|
|
180
|
-
"use strict";
|
|
181
|
-
resolveHandler = (handler, element) => {
|
|
182
|
-
if (typeof handler === "function") return handler;
|
|
183
|
-
const plugins = element?.context?.plugins;
|
|
184
|
-
if (!plugins) return handler;
|
|
185
|
-
for (const plugin of plugins) {
|
|
186
|
-
if (plugin.resolveHandler) {
|
|
187
|
-
const resolved = plugin.resolveHandler(handler, element);
|
|
188
|
-
if (typeof resolved === "function") return resolved;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return handler;
|
|
192
|
-
};
|
|
193
|
-
runPluginHook = (hookName, element, ...args) => {
|
|
194
|
-
const plugins = element?.context?.plugins;
|
|
195
|
-
if (!plugins) return false;
|
|
196
|
-
let handled = false;
|
|
197
|
-
for (const plugin of plugins) {
|
|
198
|
-
if (typeof plugin[hookName] === "function") {
|
|
199
|
-
plugin[hookName](element, ...args);
|
|
200
|
-
handled = true;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return handled;
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// ../../packages/utils/if.js
|
|
209
|
-
var init_if = __esm({
|
|
210
|
-
"../../packages/utils/if.js"() {
|
|
211
|
-
"use strict";
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// ../../packages/utils/log.js
|
|
216
|
-
var init_log = __esm({
|
|
217
|
-
"../../packages/utils/log.js"() {
|
|
218
|
-
"use strict";
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// ../../packages/utils/cookie.js
|
|
223
|
-
var isMobile;
|
|
224
|
-
var init_cookie = __esm({
|
|
225
|
-
"../../packages/utils/cookie.js"() {
|
|
226
|
-
"use strict";
|
|
227
|
-
isMobile = (() => typeof navigator === "undefined" ? false : /Mobi/.test(navigator.userAgent))();
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// ../../packages/utils/tags.js
|
|
232
|
-
var init_tags = __esm({
|
|
233
|
-
"../../packages/utils/tags.js"() {
|
|
234
|
-
"use strict";
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
// ../../packages/utils/extends.js
|
|
239
|
-
var init_extends = __esm({
|
|
240
|
-
"../../packages/utils/extends.js"() {
|
|
241
|
-
"use strict";
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// ../../packages/utils/component.js
|
|
246
|
-
var init_component = __esm({
|
|
247
|
-
"../../packages/utils/component.js"() {
|
|
248
|
-
"use strict";
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
// ../../packages/utils/props.js
|
|
253
|
-
var init_props = __esm({
|
|
254
|
-
"../../packages/utils/props.js"() {
|
|
255
|
-
"use strict";
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// ../../packages/utils/element.js
|
|
260
|
-
var init_element = __esm({
|
|
261
|
-
"../../packages/utils/element.js"() {
|
|
262
|
-
"use strict";
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
// ../../packages/utils/state.js
|
|
267
|
-
var init_state = __esm({
|
|
268
|
-
"../../packages/utils/state.js"() {
|
|
269
|
-
"use strict";
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
// ../../packages/utils/scope.js
|
|
274
|
-
var init_scope = __esm({
|
|
275
|
-
"../../packages/utils/scope.js"() {
|
|
276
|
-
"use strict";
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// ../../packages/utils/triggerEvent.js
|
|
281
|
-
var getOnOrPropsEvent, applyEvent, triggerEventOn;
|
|
282
|
-
var init_triggerEvent = __esm({
|
|
283
|
-
"../../packages/utils/triggerEvent.js"() {
|
|
284
|
-
"use strict";
|
|
285
|
-
init_types();
|
|
286
|
-
init_function();
|
|
287
|
-
getOnOrPropsEvent = (param, element) => {
|
|
288
|
-
const propKey = "on" + param.charAt(0).toUpperCase() + param.slice(1);
|
|
289
|
-
return element[propKey];
|
|
290
|
-
};
|
|
291
|
-
applyEvent = (param, element, state, context, options) => {
|
|
292
|
-
param = resolveHandler(param, element);
|
|
293
|
-
if (!isFunction(param)) return;
|
|
294
|
-
try {
|
|
295
|
-
const result = param.call(
|
|
296
|
-
element,
|
|
297
|
-
element,
|
|
298
|
-
state || element.state,
|
|
299
|
-
context || element.context,
|
|
300
|
-
options
|
|
301
|
-
);
|
|
302
|
-
if (result && typeof result.then === "function") {
|
|
303
|
-
result.catch((err) => {
|
|
304
|
-
element.error = err;
|
|
305
|
-
if (err instanceof ReferenceError) console.warn("[DOMQL] Async event warning:", err.message);
|
|
306
|
-
else console.error("[DOMQL] Async event error:", err);
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
return result;
|
|
310
|
-
} catch (err) {
|
|
311
|
-
element.error = err;
|
|
312
|
-
if (err instanceof ReferenceError) {
|
|
313
|
-
console.warn("[DOMQL] Event handler warning:", err.message);
|
|
314
|
-
} else {
|
|
315
|
-
console.error("[DOMQL] Event handler error:", err);
|
|
316
|
-
}
|
|
317
|
-
if (element.context?.strictMode) throw err;
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
triggerEventOn = (param, element, options) => {
|
|
321
|
-
if (!element) {
|
|
322
|
-
throw new Error("Element is required");
|
|
323
|
-
}
|
|
324
|
-
runPluginHook(param, element, options);
|
|
325
|
-
const appliedFunction = getOnOrPropsEvent(param, element);
|
|
326
|
-
if (appliedFunction) {
|
|
327
|
-
const { state, context } = element;
|
|
328
|
-
return applyEvent(appliedFunction, element, state, context, options);
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// ../../packages/utils/cache.js
|
|
335
|
-
var init_cache = __esm({
|
|
336
|
-
"../../packages/utils/cache.js"() {
|
|
337
|
-
"use strict";
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
// ../../packages/utils/methods.js
|
|
342
|
-
var init_methods = __esm({
|
|
343
|
-
"../../packages/utils/methods.js"() {
|
|
344
|
-
"use strict";
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
// ../../packages/utils/update.js
|
|
349
|
-
var init_update = __esm({
|
|
350
|
-
"../../packages/utils/update.js"() {
|
|
351
|
-
"use strict";
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
// ../../packages/utils/projectKeys.js
|
|
356
|
-
var init_projectKeys = __esm({
|
|
357
|
-
"../../packages/utils/projectKeys.js"() {
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
// ../../packages/utils/browser.js
|
|
362
|
-
var init_browser = __esm({
|
|
363
|
-
"../../packages/utils/browser.js"() {
|
|
364
|
-
"use strict";
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
// ../../packages/utils/cdn.js
|
|
369
|
-
var init_cdn = __esm({
|
|
370
|
-
"../../packages/utils/cdn.js"() {
|
|
371
|
-
"use strict";
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
// ../../packages/utils/date.js
|
|
376
|
-
var init_date = __esm({
|
|
377
|
-
"../../packages/utils/date.js"() {
|
|
378
|
-
"use strict";
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
// ../../packages/utils/detectHeight.js
|
|
383
|
-
var init_detectHeight = __esm({
|
|
384
|
-
"../../packages/utils/detectHeight.js"() {
|
|
385
|
-
"use strict";
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
// ../../packages/utils/fibonacci.js
|
|
390
|
-
var init_fibonacci = __esm({
|
|
391
|
-
"../../packages/utils/fibonacci.js"() {
|
|
392
|
-
"use strict";
|
|
393
|
-
}
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
// ../../packages/utils/files.js
|
|
397
|
-
var init_files = __esm({
|
|
398
|
-
"../../packages/utils/files.js"() {
|
|
399
|
-
"use strict";
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
// ../../packages/utils/load.js
|
|
404
|
-
var init_load = __esm({
|
|
405
|
-
"../../packages/utils/load.js"() {
|
|
406
|
-
"use strict";
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
// ../../packages/utils/metadata.js
|
|
411
|
-
var init_metadata = __esm({
|
|
412
|
-
"../../packages/utils/metadata.js"() {
|
|
413
|
-
"use strict";
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
// ../../packages/utils/scaling.js
|
|
418
|
-
var init_scaling = __esm({
|
|
419
|
-
"../../packages/utils/scaling.js"() {
|
|
420
|
-
"use strict";
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
// ../../packages/utils/sharedLibraries.js
|
|
425
|
-
var init_sharedLibraries = __esm({
|
|
426
|
-
"../../packages/utils/sharedLibraries.js"() {
|
|
427
|
-
"use strict";
|
|
428
|
-
}
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
// ../../packages/utils/string-extra.js
|
|
432
|
-
var init_string_extra = __esm({
|
|
433
|
-
"../../packages/utils/string-extra.js"() {
|
|
434
|
-
"use strict";
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
// ../../packages/utils/style.js
|
|
439
|
-
var init_style = __esm({
|
|
440
|
-
"../../packages/utils/style.js"() {
|
|
441
|
-
"use strict";
|
|
442
|
-
}
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
// ../../packages/utils/index.js
|
|
446
|
-
var init_utils = __esm({
|
|
447
|
-
"../../packages/utils/index.js"() {
|
|
448
|
-
"use strict";
|
|
449
|
-
init_key();
|
|
450
|
-
init_env();
|
|
451
|
-
init_types();
|
|
452
|
-
init_object();
|
|
453
|
-
init_function();
|
|
454
|
-
init_array();
|
|
455
|
-
init_node();
|
|
456
|
-
init_if();
|
|
457
|
-
init_log();
|
|
458
|
-
init_string();
|
|
459
|
-
init_globals();
|
|
460
|
-
init_cookie();
|
|
461
|
-
init_tags();
|
|
462
|
-
init_component();
|
|
463
|
-
init_props();
|
|
464
|
-
init_extends();
|
|
465
|
-
init_element();
|
|
466
|
-
init_state();
|
|
467
|
-
init_keys();
|
|
468
|
-
init_scope();
|
|
469
|
-
init_methods();
|
|
470
|
-
init_cache();
|
|
471
|
-
init_update();
|
|
472
|
-
init_triggerEvent();
|
|
473
|
-
init_projectKeys();
|
|
474
|
-
init_browser();
|
|
475
|
-
init_cdn();
|
|
476
|
-
init_date();
|
|
477
|
-
init_detectHeight();
|
|
478
|
-
init_fibonacci();
|
|
479
|
-
init_files();
|
|
480
|
-
init_load();
|
|
481
|
-
init_metadata();
|
|
482
|
-
init_scaling();
|
|
483
|
-
init_sharedLibraries();
|
|
484
|
-
init_string_extra();
|
|
485
|
-
init_style();
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
// index.js
|
|
490
|
-
var index_exports = {};
|
|
491
|
-
__export(index_exports, {
|
|
492
|
-
default: () => index_default,
|
|
493
|
-
getActiveRoute: () => getActiveRoute,
|
|
494
|
-
lastLevel: () => lastLevel,
|
|
495
|
-
lastPathname: () => lastPathname,
|
|
496
|
-
matchRoute: () => matchRoute,
|
|
497
|
-
parseQuery: () => parseQuery,
|
|
498
|
-
parseRoutePattern: () => parseRoutePattern,
|
|
499
|
-
router: () => router,
|
|
500
|
-
runGuards: () => runGuards
|
|
501
|
-
});
|
|
502
|
-
init_utils();
|
|
503
|
-
var paramPattern = /^:(.+)/;
|
|
504
|
-
var wildcardPattern = /^\*$/;
|
|
505
|
-
var routeCache = /* @__PURE__ */ new Map();
|
|
506
|
-
var parseRoutePattern = (pattern) => {
|
|
507
|
-
const cached = routeCache.get(pattern);
|
|
508
|
-
if (cached) return cached;
|
|
509
|
-
const segments = pattern.replace(/^\//, "").split("/");
|
|
510
|
-
const params = [];
|
|
511
|
-
let hasWildcard = false;
|
|
512
|
-
for (let i = 0; i < segments.length; i++) {
|
|
513
|
-
const match = segments[i].match(paramPattern);
|
|
514
|
-
if (match) {
|
|
515
|
-
params.push({ index: i, name: match[1] });
|
|
516
|
-
} else if (wildcardPattern.test(segments[i])) {
|
|
517
|
-
hasWildcard = true;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
const result = { segments, params, hasWildcard, pattern };
|
|
521
|
-
routeCache.set(pattern, result);
|
|
522
|
-
return result;
|
|
523
|
-
};
|
|
524
|
-
var matchRoute = (pathname, routes, level = 0) => {
|
|
525
|
-
const pathSegments = pathname.replace(/^\//, "").split("/").filter(Boolean);
|
|
526
|
-
const relevantSegments = pathSegments.slice(level);
|
|
527
|
-
const routePath = "/" + (relevantSegments[0] || "");
|
|
528
|
-
let bestMatch = null;
|
|
529
|
-
let bestScore = -1;
|
|
530
|
-
let matchedParams = {};
|
|
531
|
-
for (const key in routes) {
|
|
532
|
-
if (key === "/*") continue;
|
|
533
|
-
const parsed = parseRoutePattern(key);
|
|
534
|
-
const score = scoreMatch(relevantSegments, parsed);
|
|
535
|
-
if (score > bestScore) {
|
|
536
|
-
bestScore = score;
|
|
537
|
-
bestMatch = key;
|
|
538
|
-
matchedParams = extractParams(relevantSegments, parsed);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
if (!bestMatch && routes["/*"]) {
|
|
542
|
-
bestMatch = "/*";
|
|
543
|
-
}
|
|
544
|
-
return {
|
|
545
|
-
key: bestMatch,
|
|
546
|
-
content: bestMatch ? routes[bestMatch] : null,
|
|
547
|
-
params: matchedParams,
|
|
548
|
-
routePath
|
|
549
|
-
};
|
|
550
|
-
};
|
|
551
|
-
var scoreMatch = (pathSegments, parsed) => {
|
|
552
|
-
const { segments, hasWildcard } = parsed;
|
|
553
|
-
if (!hasWildcard && segments.length !== pathSegments.length && segments.length !== 1) {
|
|
554
|
-
if (segments.length > pathSegments.length) return -1;
|
|
555
|
-
}
|
|
556
|
-
let score = 0;
|
|
557
|
-
const len = Math.min(segments.length, pathSegments.length);
|
|
558
|
-
for (let i = 0; i < len; i++) {
|
|
559
|
-
if (segments[i] === pathSegments[i]) {
|
|
560
|
-
score += 3;
|
|
561
|
-
} else if (paramPattern.test(segments[i])) {
|
|
562
|
-
score += 1;
|
|
563
|
-
} else if (wildcardPattern.test(segments[i])) {
|
|
564
|
-
score += 0.5;
|
|
565
|
-
} else {
|
|
566
|
-
return -1;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
return score;
|
|
570
|
-
};
|
|
571
|
-
var extractParams = (pathSegments, parsed) => {
|
|
572
|
-
const params = {};
|
|
573
|
-
for (const { index, name } of parsed.params) {
|
|
574
|
-
if (pathSegments[index]) {
|
|
575
|
-
params[name] = decodeURIComponent(pathSegments[index]);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
return params;
|
|
579
|
-
};
|
|
580
|
-
var parseQuery = (search) => {
|
|
581
|
-
if (!search || search === "?") return {};
|
|
582
|
-
const params = {};
|
|
583
|
-
const searchParams = new URLSearchParams(search);
|
|
584
|
-
searchParams.forEach((value, key) => {
|
|
585
|
-
if (params[key] !== void 0) {
|
|
586
|
-
if (!Array.isArray(params[key])) params[key] = [params[key]];
|
|
587
|
-
params[key].push(value);
|
|
588
|
-
} else {
|
|
589
|
-
params[key] = value;
|
|
590
|
-
}
|
|
591
|
-
});
|
|
592
|
-
return params;
|
|
593
|
-
};
|
|
594
|
-
var runGuards = async (guards, context) => {
|
|
595
|
-
if (!guards || !guards.length) return true;
|
|
596
|
-
for (const guard of guards) {
|
|
597
|
-
const result = await guard(context);
|
|
598
|
-
if (result === false) return false;
|
|
599
|
-
if (typeof result === "string") return result;
|
|
600
|
-
}
|
|
601
|
-
return true;
|
|
602
|
-
};
|
|
603
|
-
var getActiveRoute = (level = 0, route) => {
|
|
604
|
-
if (!route) route = typeof window2 !== "undefined" ? window2.location.pathname : "/";
|
|
605
|
-
const routeArray = route.split("/");
|
|
606
|
-
const activeRoute = routeArray[level + 1];
|
|
607
|
-
if (activeRoute) return `/${activeRoute}`;
|
|
608
|
-
};
|
|
609
|
-
var lastPathname;
|
|
610
|
-
var lastLevel = 0;
|
|
611
|
-
var normalizePath = (p) => !p || p === "srcdoc" || p === "about:srcdoc" ? "/" : p;
|
|
612
|
-
var defaultOptions = {
|
|
613
|
-
level: lastLevel,
|
|
614
|
-
pushState: true,
|
|
615
|
-
initialRender: false,
|
|
616
|
-
scrollToTop: true,
|
|
617
|
-
scrollToNode: false,
|
|
618
|
-
scrollNode: document2 && document2.documentElement,
|
|
619
|
-
scrollBody: false,
|
|
620
|
-
useFragment: false,
|
|
621
|
-
updateState: true,
|
|
622
|
-
scrollToOffset: 0,
|
|
623
|
-
contentElementKey: "content",
|
|
624
|
-
scrollToOptions: { behavior: "smooth" },
|
|
625
|
-
useParamsMatching: true
|
|
626
|
-
};
|
|
627
|
-
var router = async (path, el, state = {}, options = {}) => {
|
|
628
|
-
const element = el || void 0;
|
|
629
|
-
const win = element?.context?.window || window2;
|
|
630
|
-
const doc = element?.context?.document || document2;
|
|
631
|
-
const opts = {
|
|
632
|
-
...defaultOptions,
|
|
633
|
-
...element.context.routerOptions,
|
|
634
|
-
...options
|
|
635
|
-
};
|
|
636
|
-
lastLevel = opts.lastLevel;
|
|
637
|
-
const ref = element.__ref;
|
|
638
|
-
if (opts.contentElementKey !== "content" && opts.contentElementKey !== ref.contentElementKey || !ref.contentElementKey) {
|
|
639
|
-
ref.contentElementKey = opts.contentElementKey || "content";
|
|
640
|
-
}
|
|
641
|
-
const contentElementKey = ref.contentElementKey || opts.contentElementKey || "content";
|
|
642
|
-
const origin = win.location.origin !== "null" ? win.location.origin : "http://localhost";
|
|
643
|
-
path = normalizePath(path);
|
|
644
|
-
const urlObj = new win.URL(origin + path);
|
|
645
|
-
const { pathname, search, hash } = urlObj;
|
|
646
|
-
const query = parseQuery(search);
|
|
647
|
-
const rootNode = element.node;
|
|
648
|
-
const hashChanged = hash && hash !== win.location.hash.slice(1);
|
|
649
|
-
const pathChanged = pathname !== lastPathname;
|
|
650
|
-
lastPathname = pathname;
|
|
651
|
-
let route, content, params;
|
|
652
|
-
if (opts.useParamsMatching) {
|
|
653
|
-
const match = matchRoute(pathname, element.routes, opts.level);
|
|
654
|
-
route = match.routePath;
|
|
655
|
-
content = match.content;
|
|
656
|
-
params = match.params;
|
|
657
|
-
} else {
|
|
658
|
-
route = getActiveRoute(opts.level, pathname);
|
|
659
|
-
content = element.routes[route || "/"] || element.routes["/*"];
|
|
660
|
-
params = {};
|
|
661
|
-
}
|
|
662
|
-
const scrollNode = opts.scrollToNode ? rootNode : opts.scrollNode;
|
|
663
|
-
if (element.state?.root?.debugging) {
|
|
664
|
-
element.state.root.debugging = false;
|
|
665
|
-
return;
|
|
666
|
-
}
|
|
667
|
-
if (!content) {
|
|
668
|
-
if (opts.onNotFound) {
|
|
669
|
-
opts.onNotFound({ pathname, route, element });
|
|
670
|
-
} else if (!opts.silent) {
|
|
671
|
-
console.warn("[smbls/router] no content matched for path", pathname, "\u2014 available routes:", Object.keys(element.routes || {}));
|
|
672
|
-
}
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
if (opts.guards && opts.guards.length) {
|
|
676
|
-
const guardContext = { pathname, route, params, query, hash, element, state };
|
|
677
|
-
const guardResult = await runGuards(opts.guards, guardContext);
|
|
678
|
-
if (guardResult === false) return;
|
|
679
|
-
if (typeof guardResult === "string") {
|
|
680
|
-
return router(guardResult, el, state, { ...options, guards: [] });
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
if (opts.pushState) {
|
|
684
|
-
try {
|
|
685
|
-
win.history.pushState(state, null, pathname + (search || "") + (hash || ""));
|
|
686
|
-
} catch (e) {
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
if (pathChanged || !hashChanged) {
|
|
690
|
-
const stateUpdate = { route, hash, debugging: false };
|
|
691
|
-
if (Object.keys(params).length) stateUpdate.params = params;
|
|
692
|
-
if (Object.keys(query).length) stateUpdate.query = query;
|
|
693
|
-
if (opts.updateState) {
|
|
694
|
-
element.state.update(
|
|
695
|
-
stateUpdate,
|
|
696
|
-
{ preventContentUpdate: true }
|
|
697
|
-
);
|
|
698
|
-
}
|
|
699
|
-
if (contentElementKey && opts.removeOldElement) {
|
|
700
|
-
element[contentElementKey].remove();
|
|
701
|
-
}
|
|
702
|
-
const originContent = element.__ref?.origin?.content;
|
|
703
|
-
const contentStyles = {};
|
|
704
|
-
if (originContent) {
|
|
705
|
-
for (const k in originContent) {
|
|
706
|
-
const v = originContent[k];
|
|
707
|
-
if (k === "__ref" || k === "props" || k === "node" || k === "parent" || k === "key") continue;
|
|
708
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "object" && v !== null && !v.node && !v.__ref) {
|
|
709
|
-
contentStyles[k] = v;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
const nextContent = {
|
|
714
|
-
...contentStyles,
|
|
715
|
-
...typeof content === "object" ? content : { extends: content }
|
|
716
|
-
};
|
|
717
|
-
if (opts.useFragment) nextContent.tag = "fragment";
|
|
718
|
-
try {
|
|
719
|
-
element.set(nextContent, { contentElementKey });
|
|
720
|
-
} catch (err) {
|
|
721
|
-
console.error("[smbls/router] failed to render route content", pathname, err);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
if (opts.scrollToTop && scrollNode?.scrollTo) {
|
|
725
|
-
scrollNode.scrollTo({
|
|
726
|
-
...opts.scrollToOptions || {},
|
|
727
|
-
top: 0,
|
|
728
|
-
left: 0
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
if (opts.scrollToNode && content[contentElementKey]?.node?.scrollTo) {
|
|
732
|
-
content[contentElementKey].node.scrollTo({
|
|
733
|
-
...opts.scrollToOptions || {},
|
|
734
|
-
top: 0,
|
|
735
|
-
left: 0
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
if (hash) {
|
|
739
|
-
const activeNode = doc.getElementById(hash);
|
|
740
|
-
if (activeNode && scrollNode?.scrollTo) {
|
|
741
|
-
const top = activeNode.getBoundingClientRect().top + rootNode.scrollTop - (opts.scrollToOffset || 0);
|
|
742
|
-
scrollNode.scrollTo({
|
|
743
|
-
...opts.scrollToOptions || {},
|
|
744
|
-
top,
|
|
745
|
-
left: 0
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
triggerEventOn("routeChanged", element, opts);
|
|
750
|
-
};
|
|
751
|
-
var index_default = router;
|
|
752
|
-
return __toCommonJS(index_exports);
|
|
753
|
-
})();
|
|
754
|
-
// @preserve-env
|