routerino 2.3.4 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -6
- package/dist/routerino.js +366 -216
- package/dist/routerino.umd.cjs +1 -1
- package/package.json +2 -1
- package/routerino-forge.js +186 -54
- package/routerino-image.jsx +139 -56
- package/types/routerino.d.ts +12 -1
package/dist/routerino.js
CHANGED
|
@@ -1,93 +1,138 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useState as
|
|
1
|
+
import { jsx as m, jsxs as q, Fragment as V } from "react/jsx-runtime";
|
|
2
|
+
import { useState as M, useEffect as _, useMemo as X, createContext as Z, Component as J, useContext as Q } from "react";
|
|
3
3
|
import t from "prop-types";
|
|
4
|
-
const
|
|
5
|
-
function
|
|
6
|
-
const
|
|
7
|
-
return !!(
|
|
4
|
+
const Y = [480, 800, 1200, 1920], ee = "(max-width: 480px) 100vw, (max-width: 800px) 800px, (max-width: 1200px) 1200px, 1920px", H = /* @__PURE__ */ new Map();
|
|
5
|
+
function te(i, e = "") {
|
|
6
|
+
const c = i.toLowerCase(), n = e.toLowerCase();
|
|
7
|
+
return !!(c.includes("hero") || c.includes("banner") || n.includes("hero") || n.includes("banner") || n.includes("h-screen") || n.includes("h-full"));
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
const n =
|
|
11
|
-
return e.map((l) => `${n}-${l}w${
|
|
9
|
+
function O(i, e, c = null) {
|
|
10
|
+
const n = i.replace(/\.(jpe?g|png|webp)$/i, ""), f = c ? `.${c}` : i.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg";
|
|
11
|
+
return e.map((l) => `${n}-${l}w${f} ${l}w`).join(", ");
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function oe(i) {
|
|
14
14
|
const {
|
|
15
15
|
src: e = "",
|
|
16
|
-
alt:
|
|
16
|
+
alt: c = "",
|
|
17
17
|
priority: n,
|
|
18
|
-
widths:
|
|
19
|
-
sizes: l =
|
|
20
|
-
className:
|
|
21
|
-
style:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
widths: f = Y,
|
|
19
|
+
sizes: l = ee,
|
|
20
|
+
className: u = "",
|
|
21
|
+
style: F = {},
|
|
22
|
+
width: v,
|
|
23
|
+
height: $,
|
|
24
|
+
loading: A,
|
|
25
|
+
decoding: j = "async",
|
|
26
|
+
fetchpriority: d,
|
|
27
|
+
...k
|
|
28
|
+
} = i || {}, U = typeof window > "u", S = !U && typeof document < "u" && typeof HTMLElement < "u" && document.createElement("div") instanceof HTMLElement, x = S && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1"), W = n ?? te(e, u), a = A || (W ? "eager" : "lazy"), P = d || (W ? "high" : void 0), [E, C] = M(null);
|
|
29
|
+
_(() => {
|
|
30
|
+
if (!S || x || !e) return;
|
|
31
|
+
const r = new window.Image();
|
|
32
|
+
r.onload = () => {
|
|
33
|
+
C({
|
|
34
|
+
width: r.naturalWidth,
|
|
35
|
+
height: r.naturalHeight
|
|
36
|
+
});
|
|
37
|
+
}, r.src = e;
|
|
38
|
+
}, [e, S, x]);
|
|
39
|
+
const s = X(() => E ? f.filter((r) => E.width >= r) : f, [E, f]), [B, D] = M(null);
|
|
40
|
+
_(() => {
|
|
41
|
+
if (!S || x) return;
|
|
42
|
+
let r = !1;
|
|
43
|
+
return (async () => {
|
|
44
|
+
const y = e.replace(/\.(jpe?g|png|webp)$/i, ""), T = e.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg", R = [];
|
|
45
|
+
for (const L of s) {
|
|
46
|
+
const I = `${y}-${L}w${T}`;
|
|
47
|
+
if (H.has(I)) {
|
|
48
|
+
H.get(I) && R.push(L);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const K = await fetch(I, { method: "HEAD" });
|
|
53
|
+
H.set(I, K.ok), K.ok && R.push(L);
|
|
54
|
+
} catch {
|
|
55
|
+
H.set(I, !1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
r || D(
|
|
59
|
+
R.length > 0 ? R : s
|
|
60
|
+
);
|
|
61
|
+
})(), () => {
|
|
62
|
+
r = !0;
|
|
63
|
+
};
|
|
64
|
+
}, [e, s, S, x]);
|
|
65
|
+
const z = B ?? s, b = {};
|
|
66
|
+
v != null && (b.width = v), $ != null && (b.height = $), E && v == null && $ == null && (b.width = E.width, b.height = E.height);
|
|
67
|
+
const o = {
|
|
68
|
+
maxWidth: "100%",
|
|
69
|
+
height: "auto",
|
|
70
|
+
...F
|
|
71
|
+
};
|
|
72
|
+
if (x)
|
|
73
|
+
return /* @__PURE__ */ m(
|
|
29
74
|
"img",
|
|
30
75
|
{
|
|
31
76
|
src: e,
|
|
32
|
-
alt:
|
|
33
|
-
loading:
|
|
34
|
-
decoding:
|
|
35
|
-
fetchPriority:
|
|
36
|
-
className:
|
|
37
|
-
style:
|
|
38
|
-
...
|
|
77
|
+
alt: c,
|
|
78
|
+
loading: a,
|
|
79
|
+
decoding: j,
|
|
80
|
+
fetchPriority: P,
|
|
81
|
+
className: u,
|
|
82
|
+
style: o,
|
|
83
|
+
...b,
|
|
84
|
+
...k
|
|
39
85
|
}
|
|
40
86
|
);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
}, y.src = e;
|
|
51
|
-
}, [e, S]);
|
|
52
|
-
const b = T ? h.filter((y) => T.width >= y) : h, [c, k] = I(b);
|
|
53
|
-
O(() => {
|
|
54
|
-
(async () => {
|
|
55
|
-
if (typeof window > "u") {
|
|
56
|
-
k(b);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const U = e.replace(/\.(jpe?g|png|webp)$/i, ""), o = e.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg", a = [];
|
|
60
|
-
for (const w of b) {
|
|
61
|
-
const f = `${U}-${w}w${o}`;
|
|
62
|
-
try {
|
|
63
|
-
(await fetch(f, { method: "HEAD" })).ok && a.push(w);
|
|
64
|
-
} catch {
|
|
87
|
+
if (U)
|
|
88
|
+
return /* @__PURE__ */ q("picture", { "data-routerino-image": "true", "data-original-src": e, children: [
|
|
89
|
+
/* @__PURE__ */ m(
|
|
90
|
+
"source",
|
|
91
|
+
{
|
|
92
|
+
srcSet: O(e, f, "webp"),
|
|
93
|
+
type: "image/webp",
|
|
94
|
+
sizes: l
|
|
65
95
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
96
|
+
),
|
|
97
|
+
/* @__PURE__ */ m(
|
|
98
|
+
"img",
|
|
99
|
+
{
|
|
100
|
+
src: e,
|
|
101
|
+
alt: c,
|
|
102
|
+
srcSet: O(e, f),
|
|
103
|
+
sizes: l,
|
|
104
|
+
loading: a,
|
|
105
|
+
decoding: "async",
|
|
106
|
+
fetchPriority: P,
|
|
107
|
+
className: u,
|
|
108
|
+
style: o,
|
|
109
|
+
...b,
|
|
110
|
+
...k
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
] });
|
|
114
|
+
const p = O(e, z, "webp"), g = O(e, z);
|
|
71
115
|
return /* @__PURE__ */ q("picture", { "data-routerino-image": "true", "data-original-src": e, children: [
|
|
72
|
-
/* @__PURE__ */
|
|
73
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ m("source", { srcSet: p, type: "image/webp", sizes: l }),
|
|
117
|
+
/* @__PURE__ */ m(
|
|
74
118
|
"img",
|
|
75
119
|
{
|
|
76
120
|
src: e,
|
|
77
|
-
alt:
|
|
78
|
-
srcSet:
|
|
121
|
+
alt: c,
|
|
122
|
+
srcSet: g,
|
|
79
123
|
sizes: l,
|
|
80
|
-
loading:
|
|
81
|
-
decoding:
|
|
82
|
-
fetchPriority:
|
|
83
|
-
className:
|
|
84
|
-
style:
|
|
85
|
-
...
|
|
124
|
+
loading: a,
|
|
125
|
+
decoding: j,
|
|
126
|
+
fetchPriority: P,
|
|
127
|
+
className: u,
|
|
128
|
+
style: o,
|
|
129
|
+
...b,
|
|
130
|
+
...k
|
|
86
131
|
}
|
|
87
132
|
)
|
|
88
133
|
] });
|
|
89
134
|
}
|
|
90
|
-
|
|
135
|
+
oe.propTypes = {
|
|
91
136
|
/** Image source URL (required) */
|
|
92
137
|
src: t.string.isRequired,
|
|
93
138
|
/** Alt text for accessibility (required) */
|
|
@@ -102,6 +147,10 @@ B.propTypes = {
|
|
|
102
147
|
className: t.string,
|
|
103
148
|
/** Inline styles */
|
|
104
149
|
style: t.object,
|
|
150
|
+
/** Explicit width for CLS prevention */
|
|
151
|
+
width: t.number,
|
|
152
|
+
/** Explicit height for CLS prevention */
|
|
153
|
+
height: t.number,
|
|
105
154
|
/** Loading behavior (auto-set based on priority) */
|
|
106
155
|
loading: t.oneOf(["lazy", "eager"]),
|
|
107
156
|
/** Decode timing */
|
|
@@ -109,54 +158,121 @@ B.propTypes = {
|
|
|
109
158
|
/** Fetch priority (auto-set based on priority) */
|
|
110
159
|
fetchpriority: t.oneOf(["high", "low", "auto"])
|
|
111
160
|
};
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
161
|
+
const ne = [
|
|
162
|
+
".pdf",
|
|
163
|
+
".doc",
|
|
164
|
+
".docx",
|
|
165
|
+
".xls",
|
|
166
|
+
".xlsx",
|
|
167
|
+
".ppt",
|
|
168
|
+
".pptx",
|
|
169
|
+
".odt",
|
|
170
|
+
".ods",
|
|
171
|
+
".odp",
|
|
172
|
+
".rtf",
|
|
173
|
+
".csv",
|
|
174
|
+
".txt",
|
|
175
|
+
".md",
|
|
176
|
+
".png",
|
|
177
|
+
".jpg",
|
|
178
|
+
".jpeg",
|
|
179
|
+
".gif",
|
|
180
|
+
".svg",
|
|
181
|
+
".webp",
|
|
182
|
+
".avif",
|
|
183
|
+
".ico",
|
|
184
|
+
".bmp",
|
|
185
|
+
".tiff",
|
|
186
|
+
".tif",
|
|
187
|
+
".mp4",
|
|
188
|
+
".webm",
|
|
189
|
+
".ogv",
|
|
190
|
+
".mov",
|
|
191
|
+
".avi",
|
|
192
|
+
".mkv",
|
|
193
|
+
".flv",
|
|
194
|
+
".mp3",
|
|
195
|
+
".wav",
|
|
196
|
+
".ogg",
|
|
197
|
+
".flac",
|
|
198
|
+
".aac",
|
|
199
|
+
".m4a",
|
|
200
|
+
".wma",
|
|
201
|
+
".woff",
|
|
202
|
+
".woff2",
|
|
203
|
+
".ttf",
|
|
204
|
+
".eot",
|
|
205
|
+
".zip",
|
|
206
|
+
".tar",
|
|
207
|
+
".gz",
|
|
208
|
+
".bz2",
|
|
209
|
+
".7z",
|
|
210
|
+
".rar",
|
|
211
|
+
".xz",
|
|
212
|
+
".zst",
|
|
213
|
+
".epub",
|
|
214
|
+
".mobi",
|
|
215
|
+
".json",
|
|
216
|
+
".xml",
|
|
217
|
+
".yml",
|
|
218
|
+
".yaml",
|
|
219
|
+
".css",
|
|
220
|
+
".js",
|
|
221
|
+
".map",
|
|
222
|
+
".wasm"
|
|
223
|
+
], N = Z(null);
|
|
224
|
+
function ue() {
|
|
225
|
+
const i = Q(N);
|
|
226
|
+
if (!i)
|
|
116
227
|
throw new Error(
|
|
117
228
|
"useRouterino must be used within a Routerino router. Make sure your component is rendered inside a <Routerino> component."
|
|
118
229
|
);
|
|
119
|
-
return
|
|
230
|
+
return i;
|
|
120
231
|
}
|
|
121
|
-
function
|
|
122
|
-
|
|
123
|
-
|
|
232
|
+
function h({
|
|
233
|
+
tag: i = "meta",
|
|
234
|
+
soft: e = !1,
|
|
235
|
+
innerHTML: c,
|
|
236
|
+
...n
|
|
237
|
+
}) {
|
|
238
|
+
const f = Object.keys(n);
|
|
239
|
+
if (f.length < 1)
|
|
124
240
|
return console.error(
|
|
125
|
-
`[Routerino] updateHeadTag() received no attributes to set for ${
|
|
241
|
+
`[Routerino] updateHeadTag() received no attributes to set for ${i} tag`
|
|
126
242
|
);
|
|
127
|
-
let
|
|
128
|
-
for (let
|
|
129
|
-
`${
|
|
130
|
-
)), !
|
|
243
|
+
let l = null;
|
|
244
|
+
for (let u = 0; u < f.length && (f[u] !== "content" && (l = document.querySelector(
|
|
245
|
+
`${i}[${f[u]}='${n[f[u]]}']`
|
|
246
|
+
)), !l); u++)
|
|
131
247
|
;
|
|
132
|
-
|
|
248
|
+
l && e || (l || (l = document.createElement(i)), f.forEach((u) => l.setAttribute(u, n[u])), c !== void 0 && (l.innerHTML = c), document.querySelector("head").appendChild(l));
|
|
133
249
|
}
|
|
134
|
-
function
|
|
135
|
-
let
|
|
136
|
-
return n.forEach((l,
|
|
137
|
-
l.startsWith(":") && (
|
|
138
|
-
}),
|
|
250
|
+
function re({ routePattern: i, currentRoute: e }) {
|
|
251
|
+
let c = {}, n = i.split("/"), f = e.split("/");
|
|
252
|
+
return n.forEach((l, u) => {
|
|
253
|
+
l.startsWith(":") && (c[l.slice(1)] = f[u]);
|
|
254
|
+
}), c;
|
|
139
255
|
}
|
|
140
|
-
class
|
|
256
|
+
class G extends J {
|
|
141
257
|
constructor(e) {
|
|
142
258
|
super(e), this.state = { hasError: !1 };
|
|
143
259
|
}
|
|
144
260
|
static getDerivedStateFromError() {
|
|
145
261
|
return { hasError: !0 };
|
|
146
262
|
}
|
|
147
|
-
componentDidCatch(e,
|
|
263
|
+
componentDidCatch(e, c) {
|
|
148
264
|
this.props.debug && (console.group(
|
|
149
265
|
"%c[Routerino]%c Error Boundary Caught an Error",
|
|
150
266
|
"color: #ff6b6b; font-weight: bold",
|
|
151
267
|
"",
|
|
152
268
|
e
|
|
153
|
-
), console.error("[Routerino] Component Stack:",
|
|
269
|
+
), console.error("[Routerino] Component Stack:", c.componentStack), this.props.routePath && console.error("[Routerino] Failed Route:", this.props.routePath), console.error("[Routerino] Error occurred at:", (/* @__PURE__ */ new Date()).toISOString()), console.groupEnd()), document.title = this.props.errorTitleString, this.props.usePrerenderTags && h({ name: "prerender-status-code", content: "500" });
|
|
154
270
|
}
|
|
155
271
|
render() {
|
|
156
272
|
return this.state.hasError ? this.props.fallback : this.props.children;
|
|
157
273
|
}
|
|
158
274
|
}
|
|
159
|
-
|
|
275
|
+
G.propTypes = {
|
|
160
276
|
/** The child components to render when there's no error */
|
|
161
277
|
children: t.node,
|
|
162
278
|
/** The fallback UI to display when an error is caught */
|
|
@@ -170,66 +286,67 @@ M.propTypes = {
|
|
|
170
286
|
/** Whether to log debug messages to console (optional) */
|
|
171
287
|
debug: t.bool
|
|
172
288
|
};
|
|
173
|
-
function
|
|
174
|
-
routes:
|
|
289
|
+
function ie({
|
|
290
|
+
routes: i = [
|
|
175
291
|
{
|
|
176
292
|
path: "/",
|
|
177
|
-
element: /* @__PURE__ */
|
|
293
|
+
element: /* @__PURE__ */ m("p", { children: "This is the default route. Pass an array of routes to the Routerino component in order to configure your own pages. Each route is a dictionary with at least `path` and `element` defined." }),
|
|
178
294
|
title: "Routerino default route example",
|
|
179
295
|
description: "The default route example description.",
|
|
180
296
|
tags: [{ property: "og:locale", content: "en_US" }]
|
|
181
297
|
}
|
|
182
298
|
],
|
|
183
|
-
notFoundTemplate: e = /* @__PURE__ */ q(
|
|
184
|
-
/* @__PURE__ */
|
|
185
|
-
/* @__PURE__ */
|
|
299
|
+
notFoundTemplate: e = /* @__PURE__ */ q(V, { children: [
|
|
300
|
+
/* @__PURE__ */ m("p", { children: "No page found for this URL. [404]" }),
|
|
301
|
+
/* @__PURE__ */ m("p", { children: /* @__PURE__ */ m("a", { href: "/", children: "Home" }) })
|
|
186
302
|
] }),
|
|
187
|
-
notFoundTitle:
|
|
188
|
-
errorTemplate: n = /* @__PURE__ */ q(
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
-
/* @__PURE__ */
|
|
303
|
+
notFoundTitle: c = "Page not found [404]",
|
|
304
|
+
errorTemplate: n = /* @__PURE__ */ q(V, { children: [
|
|
305
|
+
/* @__PURE__ */ m("p", { children: "Page failed to load. [500]" }),
|
|
306
|
+
/* @__PURE__ */ m("p", { children: /* @__PURE__ */ m("a", { href: "/", children: "Home" }) })
|
|
191
307
|
] }),
|
|
192
|
-
errorTitle:
|
|
308
|
+
errorTitle: f = "Page error [500]",
|
|
193
309
|
useTrailingSlash: l = !0,
|
|
194
|
-
usePrerenderTags:
|
|
195
|
-
baseUrl:
|
|
196
|
-
title:
|
|
197
|
-
separator:
|
|
198
|
-
imageUrl:
|
|
199
|
-
touchIconUrl:
|
|
200
|
-
debug: d = !1
|
|
310
|
+
usePrerenderTags: u = !1,
|
|
311
|
+
baseUrl: F = null,
|
|
312
|
+
title: v = "",
|
|
313
|
+
separator: $ = " | ",
|
|
314
|
+
imageUrl: A = null,
|
|
315
|
+
touchIconUrl: j = null,
|
|
316
|
+
debug: d = !1,
|
|
317
|
+
ignorePatterns: k = []
|
|
201
318
|
}) {
|
|
202
|
-
const
|
|
319
|
+
const U = [f, v].filter(Boolean).join($), S = [c, v].filter(Boolean).join($);
|
|
203
320
|
try {
|
|
204
321
|
if (d) {
|
|
205
|
-
const o =
|
|
206
|
-
(
|
|
322
|
+
const o = i.map((g) => g.path), p = o.filter(
|
|
323
|
+
(g, r) => o.indexOf(g) !== r
|
|
207
324
|
);
|
|
208
|
-
|
|
325
|
+
p.length > 0 && (console.warn(
|
|
209
326
|
"%c[Routerino]%c Duplicate route paths detected:",
|
|
210
327
|
"color: #f59e0b; font-weight: bold",
|
|
211
328
|
"",
|
|
212
|
-
[...new Set(
|
|
329
|
+
[...new Set(p)]
|
|
213
330
|
), console.warn(
|
|
214
331
|
"%c[Routerino]%c The first matching route will be used",
|
|
215
332
|
"color: #f59e0b; font-weight: bold",
|
|
216
333
|
""
|
|
217
334
|
));
|
|
218
335
|
}
|
|
219
|
-
const [
|
|
220
|
-
|
|
336
|
+
const [x, W] = M(window?.location?.href ?? "/");
|
|
337
|
+
_(() => {
|
|
221
338
|
if (typeof window > "u" || typeof document > "u")
|
|
222
339
|
return;
|
|
223
|
-
const o = (
|
|
340
|
+
const o = (g) => {
|
|
224
341
|
d && console.debug(
|
|
225
342
|
"%c[Routerino]%c click occurred",
|
|
226
343
|
"color: #6b7280; font-weight: bold",
|
|
227
344
|
""
|
|
228
345
|
);
|
|
229
|
-
let
|
|
230
|
-
for (;
|
|
231
|
-
|
|
232
|
-
if (
|
|
346
|
+
let r = g.target;
|
|
347
|
+
for (; r.tagName !== "A" && r.parentElement; )
|
|
348
|
+
r = r.parentElement;
|
|
349
|
+
if (r.tagName !== "A") {
|
|
233
350
|
d && console.debug(
|
|
234
351
|
"%c[Routerino]%c no anchor tag found during click",
|
|
235
352
|
"color: #6b7280; font-weight: bold",
|
|
@@ -237,8 +354,10 @@ function Q({
|
|
|
237
354
|
);
|
|
238
355
|
return;
|
|
239
356
|
}
|
|
240
|
-
|
|
241
|
-
|
|
357
|
+
if (g.defaultPrevented || g.button !== 0 || g.ctrlKey || g.metaKey || g.shiftKey || g.altKey || r.getAttribute("target") === "_blank" || r.hasAttribute("download") || r.getAttribute("rel") === "external")
|
|
358
|
+
return;
|
|
359
|
+
const w = r.getAttribute("href") || r.href;
|
|
360
|
+
if (!w) {
|
|
242
361
|
d && console.debug(
|
|
243
362
|
"%c[Routerino]%c anchor tag has no href",
|
|
244
363
|
"color: #6b7280; font-weight: bold",
|
|
@@ -246,12 +365,12 @@ function Q({
|
|
|
246
365
|
);
|
|
247
366
|
return;
|
|
248
367
|
}
|
|
249
|
-
if (!/^(https?:\/\/|\/|\.\/|\.\.\/|[^:]+$)/i.test(
|
|
368
|
+
if (!/^(https?:\/\/|\/|\.\/|\.\.\/|[^:]+$)/i.test(w)) {
|
|
250
369
|
d && console.debug(
|
|
251
370
|
"%c[Routerino]%c skipping non-http URL:",
|
|
252
371
|
"color: #6b7280; font-weight: bold",
|
|
253
372
|
"",
|
|
254
|
-
|
|
373
|
+
w
|
|
255
374
|
);
|
|
256
375
|
return;
|
|
257
376
|
}
|
|
@@ -259,67 +378,97 @@ function Q({
|
|
|
259
378
|
"%c[Routerino]%c click target href:",
|
|
260
379
|
"color: #6b7280; font-weight: bold",
|
|
261
380
|
"",
|
|
262
|
-
|
|
381
|
+
w
|
|
263
382
|
);
|
|
264
|
-
let
|
|
383
|
+
let y;
|
|
265
384
|
try {
|
|
266
|
-
|
|
267
|
-
} catch (
|
|
385
|
+
y = new URL(w, window.location.href);
|
|
386
|
+
} catch (T) {
|
|
268
387
|
d && console.debug(
|
|
269
388
|
"%c[Routerino]%c Invalid URL:",
|
|
270
389
|
"color: #6b7280; font-weight: bold",
|
|
271
390
|
"",
|
|
272
|
-
|
|
273
|
-
|
|
391
|
+
w,
|
|
392
|
+
T
|
|
274
393
|
);
|
|
275
394
|
return;
|
|
276
395
|
}
|
|
277
|
-
d && console.debug(
|
|
396
|
+
if (d && console.debug(
|
|
278
397
|
"%c[Routerino]%c targetUrl:",
|
|
279
398
|
"color: #6b7280; font-weight: bold",
|
|
280
399
|
"",
|
|
281
|
-
|
|
400
|
+
y,
|
|
282
401
|
"current:",
|
|
283
402
|
window.location
|
|
284
|
-
),
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
403
|
+
), y && window.location.origin === y.origin) {
|
|
404
|
+
const T = y.pathname.toLowerCase();
|
|
405
|
+
if (ne.some((R) => T.endsWith(R))) {
|
|
406
|
+
d && console.debug(
|
|
407
|
+
"%c[Routerino]%c skipping file extension link:",
|
|
408
|
+
"color: #6b7280; font-weight: bold",
|
|
409
|
+
"",
|
|
410
|
+
w
|
|
411
|
+
);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (k.length > 0 && k.some(
|
|
415
|
+
(R) => new RegExp(R, "i").test(w)
|
|
416
|
+
)) {
|
|
417
|
+
d && console.debug(
|
|
418
|
+
"%c[Routerino]%c skipping ignored link pattern:",
|
|
419
|
+
"color: #6b7280; font-weight: bold",
|
|
420
|
+
"",
|
|
421
|
+
w
|
|
422
|
+
);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
if (d && console.debug(
|
|
426
|
+
"%c[Routerino]%c target link is same origin, will use push-state transitioning",
|
|
427
|
+
"color: #6b7280; font-weight: bold",
|
|
428
|
+
""
|
|
429
|
+
), g.preventDefault(), r.href !== window.location.href && (W(r.href), window.history.pushState({}, "", r.href)), r.hash) {
|
|
430
|
+
const R = decodeURIComponent(r.hash.slice(1));
|
|
431
|
+
setTimeout(() => {
|
|
432
|
+
const L = document.getElementById(R);
|
|
433
|
+
L ? L.scrollIntoView({ behavior: "auto" }) : window.scrollTo({ top: 0, behavior: "auto" });
|
|
434
|
+
}, 0);
|
|
435
|
+
} else
|
|
436
|
+
window.scrollTo({
|
|
437
|
+
top: 0,
|
|
438
|
+
behavior: "auto"
|
|
439
|
+
});
|
|
440
|
+
} else d && console.debug(
|
|
292
441
|
"%c[Routerino]%c target link does not share an origin, standard browser link handling applies",
|
|
293
442
|
"color: #6b7280; font-weight: bold",
|
|
294
443
|
""
|
|
295
444
|
);
|
|
296
445
|
};
|
|
297
446
|
document.addEventListener("click", o);
|
|
298
|
-
const
|
|
447
|
+
const p = () => {
|
|
299
448
|
d && console.debug(
|
|
300
449
|
"%c[Routerino]%c route change ->",
|
|
301
450
|
"color: #6b7280; font-weight: bold",
|
|
302
451
|
"",
|
|
303
452
|
window.location.pathname
|
|
304
|
-
),
|
|
453
|
+
), W(window.location.href);
|
|
305
454
|
};
|
|
306
|
-
return window.addEventListener("popstate",
|
|
307
|
-
document.removeEventListener("click", o), window.removeEventListener("popstate",
|
|
455
|
+
return window.addEventListener("popstate", p), () => {
|
|
456
|
+
document.removeEventListener("click", o), window.removeEventListener("popstate", p);
|
|
308
457
|
};
|
|
309
|
-
}, [
|
|
310
|
-
let
|
|
311
|
-
(
|
|
312
|
-
const
|
|
313
|
-
(o) => `${o.path}/` ===
|
|
314
|
-
),
|
|
315
|
-
const
|
|
316
|
-
return
|
|
317
|
-
}), s =
|
|
458
|
+
}, [x, k]);
|
|
459
|
+
let a = window?.location?.pathname ?? "/";
|
|
460
|
+
(a === "/index.html" || a === "") && (a = "/");
|
|
461
|
+
const P = i.find((o) => o.path === a), E = i.find(
|
|
462
|
+
(o) => `${o.path}/` === a || o.path === `${a}/`
|
|
463
|
+
), C = i.find((o) => {
|
|
464
|
+
const p = o.path.endsWith("/") ? o.path.slice(0, -1) : o.path, g = a.endsWith("/") ? a.slice(0, -1) : a, r = p.split("/").filter(Boolean), w = g.split("/").filter(Boolean);
|
|
465
|
+
return r.length !== w.length ? !1 : r.every((y, T) => y.startsWith(":") ? !0 : y === w[T]);
|
|
466
|
+
}), s = P ?? E ?? C;
|
|
318
467
|
if (d && console.debug(
|
|
319
468
|
"%c[Routerino]%c Route matching:",
|
|
320
469
|
"color: #6b7280; font-weight: bold",
|
|
321
470
|
"",
|
|
322
|
-
{ match: s, exactMatch:
|
|
471
|
+
{ match: s, exactMatch: P, addSlashMatch: E, paramsMatch: C }
|
|
323
472
|
), !s)
|
|
324
473
|
return d && (console.group(
|
|
325
474
|
"%c[Routerino]%c 404 - No matching route",
|
|
@@ -329,71 +478,71 @@ function Q({
|
|
|
329
478
|
"%c[Routerino]%c Requested path:",
|
|
330
479
|
"color: #f59e0b; font-weight: bold",
|
|
331
480
|
"",
|
|
332
|
-
|
|
481
|
+
a
|
|
333
482
|
), console.warn(
|
|
334
483
|
"%c[Routerino]%c Available routes:",
|
|
335
484
|
"color: #f59e0b; font-weight: bold",
|
|
336
485
|
"",
|
|
337
|
-
|
|
338
|
-
), console.groupEnd()), document.title =
|
|
339
|
-
if (
|
|
486
|
+
i.map((o) => o.path)
|
|
487
|
+
), console.groupEnd()), document.title = S, u && h({ name: "prerender-status-code", content: "404" }), e;
|
|
488
|
+
if (u) {
|
|
340
489
|
const o = document.querySelector(
|
|
341
490
|
'meta[name="prerender-status-code"]'
|
|
342
491
|
);
|
|
343
492
|
o && o.remove();
|
|
344
|
-
const
|
|
493
|
+
const p = document.querySelector(
|
|
345
494
|
'meta[name="prerender-header"]'
|
|
346
495
|
);
|
|
347
|
-
|
|
496
|
+
p && p.remove();
|
|
348
497
|
}
|
|
349
|
-
const
|
|
350
|
-
if (s.title) {
|
|
351
|
-
const o =
|
|
352
|
-
document.title = o,
|
|
353
|
-
tag: "link",
|
|
354
|
-
rel: "canonical",
|
|
355
|
-
href: U
|
|
356
|
-
}), s.tags?.find(({ property: a }) => a === "og:title") || u({
|
|
498
|
+
const B = l && !a.endsWith("/") && a !== "/", D = !l && a.endsWith("/") && a !== "/", z = B ? `${a}/` : D ? a.slice(0, -1) : a, b = `${F ?? window?.location?.origin ?? ""}${z}`;
|
|
499
|
+
if (s.title || v) {
|
|
500
|
+
const o = [s.title, v].filter(Boolean).join($);
|
|
501
|
+
document.title = o, s.tags?.find(({ property: p }) => p === "og:title") || h({
|
|
357
502
|
property: "og:title",
|
|
358
503
|
content: o
|
|
359
|
-
}), s.tags?.find(({ property: a }) => a === "og:url") || u({
|
|
360
|
-
property: "og:url",
|
|
361
|
-
content: U
|
|
362
504
|
});
|
|
363
505
|
}
|
|
364
|
-
if (
|
|
506
|
+
if (h({
|
|
507
|
+
tag: "link",
|
|
508
|
+
rel: "canonical",
|
|
509
|
+
href: b
|
|
510
|
+
}), s.tags?.find(({ property: o }) => o === "og:url") || h({
|
|
511
|
+
property: "og:url",
|
|
512
|
+
content: b
|
|
513
|
+
}), s.description && (h({ name: "description", content: s.description }), s.tags?.find(({ property: o }) => o === "og:description") || h({
|
|
365
514
|
property: "og:description",
|
|
366
515
|
content: s.description
|
|
367
|
-
})), (
|
|
516
|
+
})), (A || s.imageUrl) && h({
|
|
368
517
|
property: "og:image",
|
|
369
|
-
content: s.imageUrl ??
|
|
370
|
-
}), s.tags?.find(({ property: o }) => o === "twitter:card") ||
|
|
518
|
+
content: s.imageUrl ?? A
|
|
519
|
+
}), s.tags?.find(({ property: o }) => o === "twitter:card") || h({
|
|
371
520
|
name: "twitter:card",
|
|
372
521
|
content: "summary_large_image"
|
|
373
|
-
}),
|
|
522
|
+
}), j && h({
|
|
374
523
|
tag: "link",
|
|
375
524
|
rel: "apple-touch-icon",
|
|
376
|
-
href:
|
|
377
|
-
}),
|
|
525
|
+
href: j
|
|
526
|
+
}), u && (B || D) && (h({ name: "prerender-status-code", content: "301" }), h({
|
|
378
527
|
name: "prerender-header",
|
|
379
|
-
content: `Location: ${
|
|
380
|
-
})), s.tags && s.tags.length ? (s.tags.find(({ property: o }) => o === "og:type") ||
|
|
381
|
-
const o =
|
|
528
|
+
content: `Location: ${b}`
|
|
529
|
+
})), s.tags && s.tags.length ? (s.tags.find(({ property: o }) => o === "og:type") || h({ property: "og:type", content: "website" }), s.tags.forEach((o) => h(o))) : h({ property: "og:type", content: "website" }), s.element) {
|
|
530
|
+
const o = re({
|
|
382
531
|
routePattern: s.path,
|
|
383
|
-
currentRoute:
|
|
384
|
-
}),
|
|
385
|
-
currentRoute:
|
|
532
|
+
currentRoute: a
|
|
533
|
+
}), p = {
|
|
534
|
+
currentRoute: a,
|
|
386
535
|
params: o,
|
|
387
536
|
routePattern: s.path,
|
|
388
|
-
updateHeadTag:
|
|
537
|
+
updateHeadTag: h
|
|
389
538
|
};
|
|
390
|
-
return /* @__PURE__ */
|
|
391
|
-
|
|
539
|
+
return /* @__PURE__ */ m(N.Provider, { value: p, children: /* @__PURE__ */ m(
|
|
540
|
+
G,
|
|
392
541
|
{
|
|
393
542
|
fallback: n,
|
|
394
|
-
errorTitleString:
|
|
395
|
-
usePrerenderTags:
|
|
396
|
-
routePath:
|
|
543
|
+
errorTitleString: U,
|
|
544
|
+
usePrerenderTags: u,
|
|
545
|
+
routePath: a,
|
|
397
546
|
debug: d,
|
|
398
547
|
children: s.element
|
|
399
548
|
}
|
|
@@ -403,9 +552,9 @@ function Q({
|
|
|
403
552
|
"%c[Routerino]%c No route found for",
|
|
404
553
|
"color: #ff6b6b; font-weight: bold",
|
|
405
554
|
"",
|
|
406
|
-
|
|
407
|
-
), document.title =
|
|
408
|
-
} catch (
|
|
555
|
+
a
|
|
556
|
+
), document.title = S, u && h({ name: "prerender-status-code", content: "404" }), e;
|
|
557
|
+
} catch (x) {
|
|
409
558
|
return d && (console.group(
|
|
410
559
|
"%c[Routerino]%c Fatal Error",
|
|
411
560
|
"color: #ff6b6b; font-weight: bold",
|
|
@@ -418,23 +567,23 @@ function Q({
|
|
|
418
567
|
"%c[Routerino]%c Error:",
|
|
419
568
|
"color: #ff6b6b; font-weight: bold",
|
|
420
569
|
"",
|
|
421
|
-
|
|
570
|
+
x
|
|
422
571
|
), console.error(
|
|
423
572
|
"%c[Routerino]%c This typically means an issue with route configuration or router setup",
|
|
424
573
|
"color: #ff6b6b; font-weight: bold",
|
|
425
574
|
""
|
|
426
|
-
), console.groupEnd()),
|
|
575
|
+
), console.groupEnd()), u && h({ name: "prerender-status-code", content: "500" }), document.title = U, n;
|
|
427
576
|
}
|
|
428
577
|
}
|
|
429
|
-
const
|
|
430
|
-
path: (
|
|
431
|
-
const n =
|
|
578
|
+
const ce = t.exact({
|
|
579
|
+
path: (i, e, c) => {
|
|
580
|
+
const n = i[e];
|
|
432
581
|
return n == null ? new Error(
|
|
433
|
-
`The prop \`${e}\` is marked as required in \`${
|
|
582
|
+
`The prop \`${e}\` is marked as required in \`${c}\`, but its value is \`${n}\`.`
|
|
434
583
|
) : typeof n != "string" ? new Error(
|
|
435
|
-
`Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${
|
|
584
|
+
`Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${c}\`, expected \`string\`.`
|
|
436
585
|
) : n.startsWith("/") ? null : new Error(
|
|
437
|
-
`Invalid prop \`${e}\` value \`${n}\` supplied to \`${
|
|
586
|
+
`Invalid prop \`${e}\` value \`${n}\` supplied to \`${c}\`. Route paths must start with a forward slash (/).`
|
|
438
587
|
);
|
|
439
588
|
},
|
|
440
589
|
element: t.element.isRequired,
|
|
@@ -443,8 +592,8 @@ const X = t.exact({
|
|
|
443
592
|
tags: t.arrayOf(t.object),
|
|
444
593
|
imageUrl: t.string
|
|
445
594
|
});
|
|
446
|
-
|
|
447
|
-
routes: t.arrayOf(
|
|
595
|
+
ie.propTypes = {
|
|
596
|
+
routes: t.arrayOf(ce),
|
|
448
597
|
title: t.string,
|
|
449
598
|
separator: t.string,
|
|
450
599
|
notFoundTemplate: t.element,
|
|
@@ -453,29 +602,30 @@ Q.propTypes = {
|
|
|
453
602
|
errorTitle: t.string,
|
|
454
603
|
useTrailingSlash: t.bool,
|
|
455
604
|
usePrerenderTags: t.bool,
|
|
456
|
-
baseUrl: (
|
|
457
|
-
const n =
|
|
605
|
+
baseUrl: (i, e, c) => {
|
|
606
|
+
const n = i[e];
|
|
458
607
|
if (n != null) {
|
|
459
608
|
if (typeof n != "string")
|
|
460
609
|
return new Error(
|
|
461
|
-
`Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${
|
|
610
|
+
`Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${c}\`, expected \`string\`.`
|
|
462
611
|
);
|
|
463
612
|
if (n.endsWith("/"))
|
|
464
613
|
return new Error(
|
|
465
|
-
`Invalid prop \`${e}\` supplied to \`${
|
|
614
|
+
`Invalid prop \`${e}\` supplied to \`${c}\`. The baseUrl should not end with a slash. Got: "${n}"`
|
|
466
615
|
);
|
|
467
616
|
}
|
|
468
617
|
return null;
|
|
469
618
|
},
|
|
470
619
|
imageUrl: t.string,
|
|
471
620
|
touchIconUrl: t.string,
|
|
472
|
-
debug: t.bool
|
|
621
|
+
debug: t.bool,
|
|
622
|
+
ignorePatterns: t.arrayOf(t.string)
|
|
473
623
|
};
|
|
474
624
|
export {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
625
|
+
G as ErrorBoundary,
|
|
626
|
+
oe as Image,
|
|
627
|
+
ie as Routerino,
|
|
628
|
+
ie as default,
|
|
629
|
+
h as updateHeadTag,
|
|
630
|
+
ue as useRouterino
|
|
481
631
|
};
|