@qwik.dev/router 2.0.0-beta.4 → 2.0.0-beta.41
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/adapters/static/vite.d.ts +1 -1
- package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
- package/lib/adapters/azure-swa/vite/index.mjs +44 -58
- package/lib/adapters/bun-server/vite/index.d.ts +2 -2
- package/lib/adapters/bun-server/vite/index.mjs +16 -23
- package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
- package/lib/adapters/cloud-run/vite/index.mjs +15 -20
- package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
- package/lib/adapters/cloudflare-pages/vite/index.mjs +45 -77
- package/lib/adapters/deno-server/vite/index.d.ts +2 -2
- package/lib/adapters/deno-server/vite/index.mjs +25 -35
- package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
- package/lib/adapters/netlify-edge/vite/index.mjs +49 -89
- package/lib/adapters/node-server/vite/index.d.ts +2 -2
- package/lib/adapters/node-server/vite/index.mjs +16 -23
- package/lib/adapters/shared/vite/index.d.ts +9 -22
- package/lib/adapters/shared/vite/index.mjs +280 -333
- package/lib/adapters/ssg/vite/index.d.ts +13 -0
- package/lib/adapters/ssg/vite/index.mjs +13 -0
- package/lib/adapters/vercel-edge/vite/index.d.ts +3 -3
- package/lib/adapters/vercel-edge/vite/index.mjs +73 -80
- package/lib/chunks/dev-preloaded-route-loader.mjs +2 -0
- package/lib/chunks/format.mjs +24 -0
- package/lib/chunks/fs.mjs +140 -0
- package/lib/chunks/head.qwik.mjs +1202 -0
- package/lib/chunks/http-error.qwik.mjs +27 -0
- package/lib/chunks/pathname.mjs +57 -0
- package/lib/chunks/request-body-limit.mjs +27 -0
- package/lib/chunks/request-path.mjs +49 -0
- package/lib/chunks/routes.mjs +26 -0
- package/lib/chunks/server-error.mjs +16 -0
- package/lib/chunks/system.mjs +265 -0
- package/lib/chunks/url.mjs +59 -0
- package/lib/chunks/user-response.mjs +1730 -0
- package/lib/chunks/worker-thread.mjs +264 -0
- package/lib/index.d.ts +631 -174
- package/lib/index.qwik.mjs +1656 -1964
- package/lib/middleware/aws-lambda/index.d.ts +15 -16
- package/lib/middleware/aws-lambda/index.mjs +45 -54
- package/lib/middleware/azure-swa/index.mjs +85 -295
- package/lib/middleware/bun/index.d.ts +20 -5
- package/lib/middleware/bun/index.mjs +119 -205
- package/lib/middleware/cloudflare-pages/index.mjs +88 -105
- package/lib/middleware/deno/index.d.ts +22 -5
- package/lib/middleware/deno/index.mjs +105 -192
- package/lib/middleware/firebase/index.mjs +22 -35
- package/lib/middleware/netlify-edge/index.mjs +63 -81
- package/lib/middleware/node/index.d.ts +17 -5
- package/lib/middleware/node/index.mjs +299 -273
- package/lib/middleware/request-handler/index.d.ts +206 -99
- package/lib/middleware/request-handler/index.mjs +105 -1648
- package/lib/middleware/vercel-edge/index.mjs +76 -101
- package/lib/modules.d.ts +11 -16
- package/lib/service-worker/index.mjs +13 -0
- package/lib/{static → ssg}/index.d.ts +46 -22
- package/lib/ssg/index.mjs +257 -0
- package/lib/vite/index.d.ts +58 -10
- package/lib/vite/index.mjs +2471 -27446
- package/modules.d.ts +11 -16
- package/package.json +62 -70
- package/ssg.d.ts +2 -0
- package/static.d.ts +1 -1
- package/lib/adapters/azure-swa/vite/index.cjs +0 -96
- package/lib/adapters/bun-server/vite/index.cjs +0 -50
- package/lib/adapters/cloud-run/vite/index.cjs +0 -47
- package/lib/adapters/cloudflare-pages/vite/index.cjs +0 -115
- package/lib/adapters/deno-server/vite/index.cjs +0 -62
- package/lib/adapters/netlify-edge/vite/index.cjs +0 -129
- package/lib/adapters/node-server/vite/index.cjs +0 -50
- package/lib/adapters/shared/vite/index.cjs +0 -378
- package/lib/adapters/static/vite/index.cjs +0 -368
- package/lib/adapters/static/vite/index.d.ts +0 -10
- package/lib/adapters/static/vite/index.mjs +0 -331
- package/lib/adapters/vercel-edge/vite/index.cjs +0 -118
- package/lib/index.qwik.cjs +0 -2022
- package/lib/middleware/node/index.cjs +0 -314
- package/lib/middleware/request-handler/index.cjs +0 -1691
- package/lib/service-worker.cjs +0 -17
- package/lib/service-worker.mjs +0 -15
- package/lib/static/deno.mjs +0 -8
- package/lib/static/index.cjs +0 -67
- package/lib/static/index.mjs +0 -48
- package/lib/static/node.cjs +0 -1126
- package/lib/static/node.mjs +0 -1088
- package/lib/vite/index.cjs +0 -27525
- package/middleware/request-handler/generated/not-found-paths.ts +0 -7
- package/middleware/request-handler/generated/static-paths.ts +0 -35
package/lib/index.qwik.mjs
CHANGED
|
@@ -1,2003 +1,1695 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { t as ensureSlash } from "./chunks/pathname.mjs";
|
|
2
|
+
import { A as routeLoader$, B as RouteLoaderCtxContext, E as isImmutableLoader, F as ContentContext, G as QACTION_KEY, H as RouteNavigateContext, I as ContentInternalContext, J as Q_ROUTE, K as QDATA_KEY, L as DocumentHeadContext, M as setLoaderSignalValue, P as updateRouteLoaderPaths, R as HttpStatusContext, T as invalidateNavRouteLoaders, U as RoutePreventNavigateContext, V as RouteLocationContext, W as RouteStateContext, _ as fetchRouteLoaderData, a as isPromise, b as getRequestEvent, c as shouldPreload, d as loadRoute, g as ensureRouteLoaderSignals, i as getClientNavPath, j as routeLoaderQrl, l as toPath, m as clearNavFetchCache, n as resolveHead, o as isSameOrigin, q as QFN_KEY, s as isSamePath, t as createDocumentHead, u as toUrl, y as getModuleRouteLoaders, z as RouteActionContext } from "./chunks/head.qwik.mjs";
|
|
3
|
+
import { SkipRender, Slot, _captures, _fnSignal, _getConstProps, _getVarProps, _jsxSorted, _jsxSplit, _qrlSync, _restProps, _wrapProp, componentQrl, createComputedQrl, createElement, eventQrl, getLocale, implicit$FirstArg, inlinedQrl, isBrowser, isDev, isServer, noSerialize, untrack, useContext, useContextProvider, useErrorBoundary, useOnWindow, useServerData, useSignal, useStore, useTaskQrl, useVisibleTaskQrl, withLocale } from "@qwik.dev/core";
|
|
4
|
+
import { Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
5
5
|
import * as qwikRouterConfig from "@qwik-router-config";
|
|
6
|
+
import { p } from "@qwik.dev/core/preloader";
|
|
7
|
+
import { _deserialize, _getContextContainer, _getContextHostElement, _hasStoreEffects, _serialize, _waitUntilRendered, forceStoreEffects } from "@qwik.dev/core/internal";
|
|
8
|
+
import * as v from "valibot";
|
|
9
|
+
import * as z$1 from "zod";
|
|
6
10
|
import { z } from "zod";
|
|
7
|
-
import { z as z2 } from "zod";
|
|
8
11
|
import swRegister from "@qwik-router-sw-register";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (!opts?.action) {
|
|
39
|
-
qData = CLIENT_DATA_CACHE.get(clientDataPath);
|
|
40
|
-
}
|
|
41
|
-
if (opts?.prefetchSymbols !== false) {
|
|
42
|
-
prefetchSymbols(pagePathname);
|
|
43
|
-
}
|
|
44
|
-
let resolveFn;
|
|
45
|
-
if (!qData) {
|
|
46
|
-
const fetchOptions = getFetchOptions(opts?.action, opts?.clearCache);
|
|
47
|
-
if (opts?.action) {
|
|
48
|
-
opts.action.data = void 0;
|
|
49
|
-
}
|
|
50
|
-
qData = fetch(clientDataPath, fetchOptions).then((rsp) => {
|
|
51
|
-
if (rsp.status === 404 && opts?.loaderIds && retryCount < MAX_Q_DATA_RETRY_COUNT) {
|
|
52
|
-
opts.loaderIds = void 0;
|
|
53
|
-
return loadClientData(url, element, opts, retryCount + 1);
|
|
54
|
-
}
|
|
55
|
-
if (rsp.redirected) {
|
|
56
|
-
const redirectedURL = new URL(rsp.url);
|
|
57
|
-
const isQData = redirectedURL.pathname.endsWith("/q-data.json");
|
|
58
|
-
if (!isQData || redirectedURL.origin !== location.origin) {
|
|
59
|
-
location.href = redirectedURL.href;
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if ((rsp.headers.get("content-type") || "").includes("json")) {
|
|
64
|
-
return rsp.text().then((text) => {
|
|
65
|
-
const [clientData] = _deserialize(text, element);
|
|
66
|
-
if (!clientData) {
|
|
67
|
-
location.href = url.href;
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
if (opts?.clearCache) {
|
|
71
|
-
CLIENT_DATA_CACHE.delete(clientDataPath);
|
|
72
|
-
}
|
|
73
|
-
if (clientData.redirect) {
|
|
74
|
-
location.href = clientData.redirect;
|
|
75
|
-
} else if (opts?.action) {
|
|
76
|
-
const { action } = opts;
|
|
77
|
-
const actionData = clientData.loaders[action.id];
|
|
78
|
-
resolveFn = () => {
|
|
79
|
-
action.resolve({
|
|
80
|
-
status: rsp.status,
|
|
81
|
-
result: actionData
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
return clientData;
|
|
86
|
-
});
|
|
87
|
-
} else {
|
|
88
|
-
if (opts?.isPrefetch !== true) {
|
|
89
|
-
location.href = url.href;
|
|
90
|
-
}
|
|
91
|
-
return void 0;
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
if (!opts?.action) {
|
|
95
|
-
CLIENT_DATA_CACHE.set(clientDataPath, qData);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return qData.then((v) => {
|
|
99
|
-
if (!v) {
|
|
100
|
-
CLIENT_DATA_CACHE.delete(clientDataPath);
|
|
101
|
-
}
|
|
102
|
-
resolveFn && resolveFn();
|
|
103
|
-
return v;
|
|
104
|
-
});
|
|
12
|
+
import { renderToStream } from "@qwik.dev/core/server";
|
|
13
|
+
/** @public */ var ErrorBoundary = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
14
|
+
const store = useErrorBoundary();
|
|
15
|
+
useOnWindow("qerror", /*#__PURE__*/ inlinedQrl((e) => {
|
|
16
|
+
const store = _captures[0];
|
|
17
|
+
store.error = e.detail.error;
|
|
18
|
+
}, "ErrorBoundary_component_useOnWindow_G0jFRpoNY0M", [store]));
|
|
19
|
+
if (store.error && props.fallback$) return /*#__PURE__*/ _jsxSorted(Fragment, null, null, props.fallback$(store.error), 1, "bA_0");
|
|
20
|
+
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "bA_1");
|
|
21
|
+
}, "ErrorBoundary_component_pOa6vjtC7ik"));
|
|
22
|
+
/**
|
|
23
|
+
* Prefetch a route's loader data in parallel (fire-and-forget). The per-nav fetch map dedupes
|
|
24
|
+
* repeat hovers and shares the promise with the navigation's own fetch; the browser HTTP cache
|
|
25
|
+
* handles freshness. Immutable loaders are skipped: they download lazily on first actual read and
|
|
26
|
+
* are then browser-cached for the life of the deploy.
|
|
27
|
+
*/ var prefetchLoaderData = (loadedRoute, url, manifestHash) => {
|
|
28
|
+
if (!loadedRoute.$loaders$?.length || !loadedRoute.$loaderPaths$) return;
|
|
29
|
+
const immutableIds = new Set(getModuleRouteLoaders(loadedRoute.$mods$).filter((loader) => loader.__cacheControl === "immutable").map((loader) => loader.__id));
|
|
30
|
+
const basePath = qwikRouterConfig.basePathname ?? "/";
|
|
31
|
+
for (const hash of loadedRoute.$loaders$) {
|
|
32
|
+
if (immutableIds.has(hash)) continue;
|
|
33
|
+
let loaderPath = loadedRoute.$loaderPaths$[hash];
|
|
34
|
+
if (!loaderPath) continue;
|
|
35
|
+
if (basePath !== "/" && !loaderPath.startsWith(basePath)) loaderPath = basePath + loaderPath.slice(1);
|
|
36
|
+
fetchRouteLoaderData(hash, loaderPath, manifestHash, {
|
|
37
|
+
pageUrl: url,
|
|
38
|
+
basePath
|
|
39
|
+
}).catch(() => {});
|
|
40
|
+
}
|
|
105
41
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Prefetch a route's JS bundles and optionally its loader data.
|
|
44
|
+
*
|
|
45
|
+
* Resolves the route from the trie to get the routeName (for the bundle graph preloader) and
|
|
46
|
+
* `$loaders$` (for data prefetching). The bundle graph is keyed by route name (e.g.
|
|
47
|
+
* `products/[id]/`), not by actual pathname (e.g. `products/123/`).
|
|
48
|
+
*
|
|
49
|
+
* @param url - The URL pathname to prefetch
|
|
50
|
+
* @param prefetchData - Whether to prefetch loader data
|
|
51
|
+
* @param probability - Bundle preload probability (0-1, default 0.8)
|
|
52
|
+
* @param manifestHash - Build manifest hash for loader URLs (from `useDocumentHead().manifestHash`)
|
|
53
|
+
* @param prefetchBundle - Whether to prefetch route JS bundles
|
|
54
|
+
*/ async function prefetchRoute(url, prefetchData, probability = .8, manifestHash, prefetchBundle = true) {
|
|
55
|
+
if (!isBrowser || isDev) return;
|
|
56
|
+
try {
|
|
57
|
+
const loadedRoute = await loadRoute(qwikRouterConfig.routes, qwikRouterConfig.cacheModules, url.pathname);
|
|
58
|
+
if (!loadedRoute) return;
|
|
59
|
+
if (prefetchBundle) {
|
|
60
|
+
let routeName = loadedRoute.$routeName$;
|
|
61
|
+
routeName = ensureSlash(routeName);
|
|
62
|
+
if (routeName.length > 1 && routeName.startsWith("/")) routeName = routeName.slice(1);
|
|
63
|
+
p(routeName, probability);
|
|
64
|
+
}
|
|
65
|
+
if (!prefetchData || !manifestHash) return;
|
|
66
|
+
prefetchLoaderData(loadedRoute, url, manifestHash);
|
|
67
|
+
} catch {}
|
|
68
|
+
}
|
|
69
|
+
/** @public */ var useHttpStatus = () => useContext(HttpStatusContext).value;
|
|
70
|
+
/** @public */ var useContent = () => useContext(ContentContext);
|
|
71
|
+
/**
|
|
72
|
+
* Returns the document head for the current page. The generic type describes the front matter.
|
|
73
|
+
*
|
|
74
|
+
* @public
|
|
75
|
+
*/ var useDocumentHead = () => useContext(DocumentHeadContext);
|
|
76
|
+
/** @public */ var useLocation = () => useContext(RouteLocationContext);
|
|
77
|
+
/** @public */ var useNavigate = () => useContext(RouteNavigateContext);
|
|
78
|
+
/** @internal Implementation of usePreventNavigate$ */ var usePreventNavigateQrl = (fn) => {
|
|
79
|
+
const registerPreventNav = useContext(RoutePreventNavigateContext);
|
|
80
|
+
useVisibleTaskQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
81
|
+
const fn = _captures[0], registerPreventNav = _captures[1];
|
|
82
|
+
return registerPreventNav(fn);
|
|
83
|
+
}, "usePreventNavigateQrl_useVisibleTask_BsYUaz9XhUs", [fn, registerPreventNav]));
|
|
142
84
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Prevent navigation attempts. This hook registers a callback that will be called before SPA or
|
|
87
|
+
* browser navigation.
|
|
88
|
+
*
|
|
89
|
+
* Return `true` to prevent navigation.
|
|
90
|
+
*
|
|
91
|
+
* #### SPA Navigation
|
|
92
|
+
*
|
|
93
|
+
* For Single-Page-App (SPA) navigation (via `<Link />`, `const nav = useNavigate()`, and browser
|
|
94
|
+
* backwards/forwards inside SPA history), the callback will be provided with the target, either a
|
|
95
|
+
* URL or a number. It will only be a number if `nav(number)` was called to navigate forwards or
|
|
96
|
+
* backwards in SPA history.
|
|
97
|
+
*
|
|
98
|
+
* If you return a Promise, the navigation will be blocked until the promise resolves.
|
|
99
|
+
*
|
|
100
|
+
* This can be used to show a nice dialog to the user, and wait for the user to confirm, or to
|
|
101
|
+
* record the url, prevent the navigation, and navigate there later via `nav(url)`.
|
|
102
|
+
*
|
|
103
|
+
* #### Browser Navigation
|
|
104
|
+
*
|
|
105
|
+
* However, when the user navigates away by clicking on a regular `<a />`, reloading, or moving
|
|
106
|
+
* backwards/forwards outside SPA history, this callback will not be awaited. This is because the
|
|
107
|
+
* browser does not provide a way to asynchronously prevent these navigations.
|
|
108
|
+
*
|
|
109
|
+
* In this case, returning returning `true` will tell the browser to show a confirmation dialog,
|
|
110
|
+
* which cannot be customized. You are also not able to show your own `window.confirm()` dialog
|
|
111
|
+
* during the callback, the browser won't allow it. If you return a Promise, it will be considered
|
|
112
|
+
* as `true`.
|
|
113
|
+
*
|
|
114
|
+
* When the callback is called from the browser, no url will be provided. Use this to know whether
|
|
115
|
+
* you can show a dialog or just return `true` to prevent the navigation.
|
|
116
|
+
*
|
|
117
|
+
* @public
|
|
118
|
+
*/ var usePreventNavigate$ = implicit$FirstArg(usePreventNavigateQrl);
|
|
119
|
+
var useAction = () => useContext(RouteActionContext);
|
|
120
|
+
var useQwikRouterEnv = () => noSerialize(useServerData("qwikrouter"));
|
|
121
|
+
/** @public */ var Link = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
122
|
+
const nav = useNavigate();
|
|
123
|
+
const loc = useLocation();
|
|
124
|
+
const head = useDocumentHead();
|
|
125
|
+
const originalHref = props.href;
|
|
126
|
+
const { onClick$, prefetch: prefetchProp, reload, replaceState, scroll, prefetchBundles: prefetchBundlesProp = "visible", prefetchData: prefetchDataProp = prefetchProp === "js" ? "off" : "intent", ...linkProps } = props;
|
|
127
|
+
const clientNavPath = untrack(getClientNavPath, {
|
|
128
|
+
...linkProps,
|
|
129
|
+
reload
|
|
130
|
+
}, loc);
|
|
131
|
+
linkProps.href = clientNavPath || originalHref;
|
|
132
|
+
const isDepratedPrefetchDisabled = prefetchProp === false;
|
|
133
|
+
const shouldPrefetch = untrack(shouldPreload, clientNavPath, loc);
|
|
134
|
+
const shouldVisiblePrefetchBundles = !!clientNavPath && shouldPrefetch && !isDepratedPrefetchDisabled && (prefetchBundlesProp === "visible" || prefetchProp === "js" || prefetchProp === true);
|
|
135
|
+
const shouldVisiblePrefetchData = !!clientNavPath && shouldPrefetch && !isDepratedPrefetchDisabled && (prefetchDataProp === "visible" || prefetchProp === true);
|
|
136
|
+
const handleDataPrefetch = !!clientNavPath && prefetchDataProp !== "off" && shouldPrefetch && !isDepratedPrefetchDisabled ? /*#__PURE__*/ inlinedQrl((_, elm) => {
|
|
137
|
+
const head = _captures[0];
|
|
138
|
+
if (navigator.connection?.saveData) return;
|
|
139
|
+
if (elm && elm.href) prefetchRoute(new URL(elm.href), true, .8, head.manifestHash, false);
|
|
140
|
+
}, "Link_component_handleDataPrefetch_lcd4O9LHbbA", [head]) : null;
|
|
141
|
+
const preventDefault = clientNavPath ? _qrlSync((event) => {
|
|
142
|
+
if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) event.preventDefault();
|
|
143
|
+
}, "event=>{if(!(event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)){event.preventDefault();}}") : null;
|
|
144
|
+
const prefetchData = /*#__PURE__*/ inlinedQrl(async (_, elm) => {
|
|
145
|
+
const handleDataPrefetch = _captures[0];
|
|
146
|
+
handleDataPrefetch?.(null, elm);
|
|
147
|
+
}, "Link_component_prefetchData_UwVx4NhHkSo", [handleDataPrefetch]);
|
|
148
|
+
const onEnterKeyDown = /*#__PURE__*/ inlinedQrl((event, element) => {
|
|
149
|
+
const prefetchData = _captures[0];
|
|
150
|
+
if (event.key === "Enter") prefetchData(null, element);
|
|
151
|
+
}, "Link_component_onEnterKeyDown_z274ws00irY", [prefetchData]);
|
|
152
|
+
const handleClientSideNavigation = clientNavPath ? /*#__PURE__*/ inlinedQrl((event, elm) => {
|
|
153
|
+
const nav = _captures[0], reload = _captures[1], replaceState = _captures[2], scroll = _captures[3];
|
|
154
|
+
if (event.defaultPrevented) {
|
|
155
|
+
if (elm.href) {
|
|
156
|
+
elm.setAttribute("aria-pressed", "true");
|
|
157
|
+
nav(elm.href, {
|
|
158
|
+
forceReload: reload,
|
|
159
|
+
replaceState,
|
|
160
|
+
scroll
|
|
161
|
+
}).then(() => {
|
|
162
|
+
elm.removeAttribute("aria-pressed");
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}, "Link_component_handleClientSideNavigation_h3qenoGeI6M", [
|
|
167
|
+
nav,
|
|
168
|
+
reload,
|
|
169
|
+
replaceState,
|
|
170
|
+
scroll
|
|
171
|
+
]) : null;
|
|
172
|
+
const handlePreload = /*#__PURE__*/ inlinedQrl((_, elm) => {
|
|
173
|
+
prefetchRoute(new URL(elm.href), false, 1);
|
|
174
|
+
}, "Link_component_handlePreload_AAemwtuBjsE");
|
|
175
|
+
return /*#__PURE__*/ _jsxSplit("a", {
|
|
176
|
+
"q:link": !!clientNavPath,
|
|
177
|
+
..._getVarProps(linkProps),
|
|
178
|
+
..._getConstProps(linkProps),
|
|
179
|
+
"data-q-prefetch": shouldVisiblePrefetchBundles && shouldVisiblePrefetchData ? "bd" : shouldVisiblePrefetchBundles ? "b" : shouldVisiblePrefetchData ? "d" : null,
|
|
180
|
+
"q-e:click": [
|
|
181
|
+
preventDefault,
|
|
182
|
+
handlePreload,
|
|
183
|
+
onClick$,
|
|
184
|
+
handleClientSideNavigation
|
|
185
|
+
],
|
|
186
|
+
"q-e:pointerenter": [linkProps.onMouseOver$, prefetchDataProp === "intent" ? prefetchData : null],
|
|
187
|
+
"q-e:focus": [linkProps.onFocus$, prefetchDataProp === "intent" ? prefetchData : null],
|
|
188
|
+
"q-e:pointerdown": [linkProps.onPointerDown$, prefetchDataProp === "commit" ? prefetchData : null],
|
|
189
|
+
"q-e:keydown": [linkProps.onKeyDown$, prefetchDataProp === "commit" ? onEnterKeyDown : null]
|
|
190
|
+
}, null, /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "jO_0"), 0, "jO_1");
|
|
191
|
+
}, "Link_component_VPmar9tb3t4"));
|
|
192
|
+
var newScrollState = () => {
|
|
193
|
+
return {
|
|
194
|
+
x: 0,
|
|
195
|
+
y: 0,
|
|
196
|
+
w: 0,
|
|
197
|
+
h: 0
|
|
198
|
+
};
|
|
156
199
|
};
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
console.error(e);
|
|
168
|
-
}
|
|
169
|
-
} else if (props.reload) {
|
|
170
|
-
return toPath(toUrl("", baseUrl.url));
|
|
171
|
-
}
|
|
172
|
-
return null;
|
|
200
|
+
var clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
|
|
201
|
+
if (navType !== "popstate") {
|
|
202
|
+
const samePath = isSamePath(fromURL, toURL);
|
|
203
|
+
const sameHash = fromURL.hash === toURL.hash;
|
|
204
|
+
if (!samePath || !sameHash) {
|
|
205
|
+
const newState = { _qRouterScroll: newScrollState() };
|
|
206
|
+
if (replaceState) win.history.replaceState(newState, "", toPath(toURL));
|
|
207
|
+
else win.history.pushState(newState, "", toPath(toURL));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
173
210
|
};
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return false;
|
|
211
|
+
var preloadRouteBundles = (path, probability = .8) => {
|
|
212
|
+
if (isBrowser) {
|
|
213
|
+
path = ensureSlash(path);
|
|
214
|
+
path = path.length > 1 && path.startsWith("/") ? path.slice(1) : path;
|
|
215
|
+
p(path, probability);
|
|
216
|
+
}
|
|
181
217
|
};
|
|
182
|
-
|
|
183
|
-
|
|
218
|
+
var prefetchedLinks = /* @__PURE__ */ new WeakSet();
|
|
219
|
+
var cleanupPrefetchObserver;
|
|
220
|
+
var resetLinkPrefetchState = () => {
|
|
221
|
+
prefetchedLinks = /* @__PURE__ */ new WeakSet();
|
|
184
222
|
};
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
223
|
+
var createLinkPrefetchObserver = (manifestHash) => {
|
|
224
|
+
const anchors = document.querySelectorAll("a[q\\:link][data-q-prefetch]");
|
|
225
|
+
const prefetchAnchor = (anchor, observer) => {
|
|
226
|
+
if (prefetchedLinks.has(anchor)) return;
|
|
227
|
+
prefetchedLinks.add(anchor);
|
|
228
|
+
observer?.unobserve(anchor);
|
|
229
|
+
if (navigator.connection?.saveData || !anchor.href) return;
|
|
230
|
+
let url;
|
|
231
|
+
try {
|
|
232
|
+
url = new URL(anchor.href);
|
|
233
|
+
} catch {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const currentUrl = new URL(location.href);
|
|
237
|
+
if (!isSameOrigin(url, currentUrl) || !shouldPreload(toPath(url), { url: currentUrl })) return;
|
|
238
|
+
const mode = anchor.getAttribute("data-q-prefetch") || "";
|
|
239
|
+
if (mode.includes("b")) preloadRouteBundles(url.pathname);
|
|
240
|
+
if (mode.includes("d")) prefetchRoute(url, true, .8, manifestHash, false);
|
|
241
|
+
};
|
|
242
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
243
|
+
anchors.forEach((anchor) => prefetchAnchor(anchor));
|
|
244
|
+
return () => {};
|
|
245
|
+
}
|
|
246
|
+
const observer = new IntersectionObserver((entries) => {
|
|
247
|
+
for (const entry of entries) if (entry.isIntersecting) prefetchAnchor(entry.target, observer);
|
|
248
|
+
});
|
|
249
|
+
anchors.forEach((anchor) => observer.observe(anchor));
|
|
250
|
+
return () => {
|
|
251
|
+
observer.disconnect();
|
|
252
|
+
};
|
|
196
253
|
};
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
loaderIds: [
|
|
202
|
-
loaderId
|
|
203
|
-
]
|
|
204
|
-
});
|
|
205
|
-
loadersObject[loaderId] = data?.loaders[loaderId] ?? _UNINITIALIZED;
|
|
206
|
-
}
|
|
207
|
-
return loadersObject[loaderId];
|
|
208
|
-
}, {
|
|
209
|
-
container,
|
|
210
|
-
serializationStrategy
|
|
211
|
-
});
|
|
254
|
+
var refreshLinkPrefetchObserver = (manifestHash) => {
|
|
255
|
+
resetLinkPrefetchState();
|
|
256
|
+
cleanupPrefetchObserver?.();
|
|
257
|
+
cleanupPrefetchObserver = createLinkPrefetchObserver(manifestHash);
|
|
212
258
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
259
|
+
var linkPrefetchInit = eventQrl(/*#__PURE__*/ inlinedQrl((_, element) => {
|
|
260
|
+
refreshLinkPrefetchObserver(element.closest("[q\\:manifest-hash]")?.getAttribute("q:manifest-hash") || void 0);
|
|
261
|
+
}, "linkPrefetchInit_event_hoZr9O26Irg"));
|
|
262
|
+
function callRestoreScrollOnDocument() {
|
|
263
|
+
if (document.__q_scroll_restore__) {
|
|
264
|
+
document.__q_scroll_restore__();
|
|
265
|
+
document.__q_scroll_restore__ = void 0;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
var hashScroll = (toUrl, fromUrl) => {
|
|
269
|
+
const elmId = toUrl.hash.slice(1);
|
|
270
|
+
const elm = elmId && document.getElementById(elmId);
|
|
271
|
+
if (elm) {
|
|
272
|
+
elm.scrollIntoView();
|
|
273
|
+
return true;
|
|
274
|
+
} else if (!elm && toUrl.hash && isSamePath(toUrl, fromUrl)) return true;
|
|
275
|
+
return false;
|
|
228
276
|
};
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
h: 0
|
|
235
|
-
};
|
|
277
|
+
var restoreScroll = (type, toUrl, fromUrl, scroller, scrollState) => {
|
|
278
|
+
if (type === "popstate" && scrollState) scroller.scrollTo(scrollState.x, scrollState.y);
|
|
279
|
+
else if (type === "link" || type === "form") {
|
|
280
|
+
if (!hashScroll(toUrl, fromUrl)) scroller.scrollTo(0, 0);
|
|
281
|
+
}
|
|
236
282
|
};
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
283
|
+
var currentScrollState = (elm) => {
|
|
284
|
+
return {
|
|
285
|
+
x: elm.scrollLeft,
|
|
286
|
+
y: elm.scrollTop,
|
|
287
|
+
w: Math.max(elm.scrollWidth, elm.clientWidth),
|
|
288
|
+
h: Math.max(elm.scrollHeight, elm.clientHeight)
|
|
289
|
+
};
|
|
243
290
|
};
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const ContentInternalContext = /* @__PURE__ */ createContextId("qc-ic");
|
|
247
|
-
const DocumentHeadContext = /* @__PURE__ */ createContextId("qc-h");
|
|
248
|
-
const RouteLocationContext = /* @__PURE__ */ createContextId("qc-l");
|
|
249
|
-
const RouteNavigateContext = /* @__PURE__ */ createContextId("qc-n");
|
|
250
|
-
const RouteActionContext = /* @__PURE__ */ createContextId("qc-a");
|
|
251
|
-
const RouteInternalContext = /* @__PURE__ */ createContextId("qc-ir");
|
|
252
|
-
const RoutePreventNavigateContext = /* @__PURE__ */ createContextId("qc-p");
|
|
253
|
-
const useContent = () => useContext(ContentContext);
|
|
254
|
-
const useDocumentHead = () => useContext(DocumentHeadContext);
|
|
255
|
-
const useLocation = () => useContext(RouteLocationContext);
|
|
256
|
-
const useNavigate = () => useContext(RouteNavigateContext);
|
|
257
|
-
const usePreventNavigateQrl = (fn) => {
|
|
258
|
-
if (!__EXPERIMENTAL__.preventNavigate) {
|
|
259
|
-
throw new Error('usePreventNavigate$ is experimental and must be enabled with `experimental: ["preventNavigate"]` in the `qwikVite` plugin.');
|
|
260
|
-
}
|
|
261
|
-
const registerPreventNav = useContext(RoutePreventNavigateContext);
|
|
262
|
-
useVisibleTask$(() => registerPreventNav(fn));
|
|
291
|
+
var getScrollHistory = () => {
|
|
292
|
+
return history.state?._qRouterScroll;
|
|
263
293
|
};
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const nav = useNavigate();
|
|
269
|
-
const loc = useLocation();
|
|
270
|
-
const originalHref = props.href;
|
|
271
|
-
const anchorRef = useSignal();
|
|
272
|
-
const { onClick$, prefetch: prefetchProp, reload, replaceState, scroll, ...linkProps } = /* @__PURE__ */ (() => props)();
|
|
273
|
-
const clientNavPath = untrack(() => getClientNavPath({
|
|
274
|
-
...linkProps,
|
|
275
|
-
reload
|
|
276
|
-
}, loc));
|
|
277
|
-
linkProps.href = clientNavPath || originalHref;
|
|
278
|
-
const prefetchData = untrack(() => !!clientNavPath && prefetchProp !== false && prefetchProp !== "js" || void 0);
|
|
279
|
-
const prefetch = untrack(() => prefetchData || !!clientNavPath && prefetchProp !== false && shouldPreload(clientNavPath, loc));
|
|
280
|
-
const handlePrefetch = prefetch ? $((_, elm) => {
|
|
281
|
-
if (navigator.connection?.saveData) {
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
if (elm && elm.href) {
|
|
285
|
-
const url = new URL(elm.href);
|
|
286
|
-
prefetchSymbols(url.pathname);
|
|
287
|
-
if (elm.hasAttribute("data-prefetch")) {
|
|
288
|
-
loadClientData(url, elm, {
|
|
289
|
-
prefetchSymbols: false,
|
|
290
|
-
isPrefetch: true
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}) : void 0;
|
|
295
|
-
const preventDefault = clientNavPath ? sync$((event) => {
|
|
296
|
-
if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
|
|
297
|
-
event.preventDefault();
|
|
298
|
-
}
|
|
299
|
-
}) : void 0;
|
|
300
|
-
const handleClick = clientNavPath ? $(async (event, elm) => {
|
|
301
|
-
if (event.defaultPrevented) {
|
|
302
|
-
if (elm.href) {
|
|
303
|
-
elm.setAttribute("aria-pressed", "true");
|
|
304
|
-
await nav(elm.href, {
|
|
305
|
-
forceReload: reload,
|
|
306
|
-
replaceState,
|
|
307
|
-
scroll
|
|
308
|
-
});
|
|
309
|
-
elm.removeAttribute("aria-pressed");
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}) : void 0;
|
|
313
|
-
useVisibleTask$(({ track }) => {
|
|
314
|
-
track(() => loc.url.pathname);
|
|
315
|
-
const handler = linkProps.onQVisible$;
|
|
316
|
-
if (handler) {
|
|
317
|
-
const event = new CustomEvent("qvisible");
|
|
318
|
-
if (Array.isArray(handler)) {
|
|
319
|
-
handler.flat(10).forEach((handler2) => handler2?.(event, anchorRef.value));
|
|
320
|
-
} else {
|
|
321
|
-
handler?.(event, anchorRef.value);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (!isDev && anchorRef.value) {
|
|
325
|
-
handlePrefetch?.(void 0, anchorRef.value);
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
return /* @__PURE__ */ jsx("a", {
|
|
329
|
-
ref: anchorRef,
|
|
330
|
-
"q:link": !!clientNavPath,
|
|
331
|
-
...linkProps,
|
|
332
|
-
onClick$: [
|
|
333
|
-
preventDefault,
|
|
334
|
-
onClick$,
|
|
335
|
-
handleClick
|
|
336
|
-
],
|
|
337
|
-
"data-prefetch": prefetchData,
|
|
338
|
-
onMouseOver$: [
|
|
339
|
-
linkProps.onMouseOver$,
|
|
340
|
-
handlePrefetch
|
|
341
|
-
],
|
|
342
|
-
onFocus$: [
|
|
343
|
-
linkProps.onFocus$,
|
|
344
|
-
handlePrefetch
|
|
345
|
-
],
|
|
346
|
-
// We need to prevent the onQVisible$ from being called twice since it is handled in the visible task
|
|
347
|
-
onQVisible$: [],
|
|
348
|
-
children: /* @__PURE__ */ jsx(Slot, {})
|
|
349
|
-
});
|
|
350
|
-
});
|
|
351
|
-
const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
|
|
352
|
-
const head = createDocumentHead();
|
|
353
|
-
const getData = (loaderOrAction) => {
|
|
354
|
-
const id = loaderOrAction.__id;
|
|
355
|
-
if (loaderOrAction.__brand === "server_loader") {
|
|
356
|
-
if (!(id in endpoint.loaders)) {
|
|
357
|
-
throw new Error("You can not get the returned data of a loader that has not been executed for this request.");
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
const data = endpoint.loaders[id];
|
|
361
|
-
if (isPromise(data)) {
|
|
362
|
-
throw new Error("Loaders returning a promise can not be resolved for the head function.");
|
|
363
|
-
}
|
|
364
|
-
return data;
|
|
365
|
-
};
|
|
366
|
-
const headProps = {
|
|
367
|
-
head,
|
|
368
|
-
withLocale: (fn) => withLocale(locale, fn),
|
|
369
|
-
resolveValue: getData,
|
|
370
|
-
...routeLocation
|
|
371
|
-
};
|
|
372
|
-
for (let i = contentModules.length - 1; i >= 0; i--) {
|
|
373
|
-
const contentModuleHead = contentModules[i] && contentModules[i].head;
|
|
374
|
-
if (contentModuleHead) {
|
|
375
|
-
if (typeof contentModuleHead === "function") {
|
|
376
|
-
resolveDocumentHead(head, withLocale(locale, () => contentModuleHead(headProps)));
|
|
377
|
-
} else if (typeof contentModuleHead === "object") {
|
|
378
|
-
resolveDocumentHead(head, contentModuleHead);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return headProps.head;
|
|
294
|
+
var saveScrollHistory = (scrollState) => {
|
|
295
|
+
const state = history.state || {};
|
|
296
|
+
state._qRouterScroll = scrollState;
|
|
297
|
+
history.replaceState(state, "");
|
|
383
298
|
};
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
299
|
+
var Q_ROUTER_POPSTATE_EVENT = "qrouterpopstate";
|
|
300
|
+
var createCurrentPathTracker = (initialPath) => {
|
|
301
|
+
let currentPath = initialPath;
|
|
302
|
+
return (nextPath) => {
|
|
303
|
+
if (currentPath !== nextPath) {
|
|
304
|
+
currentPath = nextPath;
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
return false;
|
|
308
|
+
};
|
|
393
309
|
};
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
for (const newItem of newArr) {
|
|
397
|
-
if (typeof newItem.key === "string") {
|
|
398
|
-
const existingIndex = existingArr.findIndex((i) => i.key === newItem.key);
|
|
399
|
-
if (existingIndex > -1) {
|
|
400
|
-
existingArr[existingIndex] = newItem;
|
|
401
|
-
continue;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
existingArr.push(newItem);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
310
|
+
var dispatchRouterPopstate = (document1, href) => {
|
|
311
|
+
document1.dispatchEvent(new CustomEvent(Q_ROUTER_POPSTATE_EVENT, { detail: { href } }));
|
|
407
312
|
};
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
function
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
313
|
+
var spa_init_default = eventQrl(/*#__PURE__*/ inlinedQrl((_, el) => {
|
|
314
|
+
if (!window._qRouterSPA && !window._qRouterInitPopstate) {
|
|
315
|
+
const hasPathChanged = createCurrentPathTracker(location.pathname + location.search);
|
|
316
|
+
const checkAndScroll = (scrollState) => {
|
|
317
|
+
if (scrollState) window.scrollTo(scrollState.x, scrollState.y);
|
|
318
|
+
};
|
|
319
|
+
const currentScrollState = () => {
|
|
320
|
+
const elm = document.documentElement;
|
|
321
|
+
return {
|
|
322
|
+
x: elm.scrollLeft,
|
|
323
|
+
y: elm.scrollTop,
|
|
324
|
+
w: Math.max(elm.scrollWidth, elm.clientWidth),
|
|
325
|
+
h: Math.max(elm.scrollHeight, elm.clientHeight)
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
const saveScrollState = (scrollState) => {
|
|
329
|
+
const state = history.state || {};
|
|
330
|
+
state._qRouterScroll = scrollState || currentScrollState();
|
|
331
|
+
history.replaceState(state, "");
|
|
332
|
+
};
|
|
333
|
+
saveScrollState();
|
|
334
|
+
window._qRouterInitPopstate = () => {
|
|
335
|
+
if (window._qRouterSPA) return;
|
|
336
|
+
window._qRouterScrollEnabled = false;
|
|
337
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
338
|
+
if (hasPathChanged(location.pathname + location.search)) dispatchRouterPopstate(document, location.href);
|
|
339
|
+
else if (history.scrollRestoration === "manual") {
|
|
340
|
+
const scrollState = history.state?._qRouterScroll;
|
|
341
|
+
checkAndScroll(scrollState);
|
|
342
|
+
window._qRouterScrollEnabled = true;
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
if (!window._qRouterHistoryPatch) {
|
|
346
|
+
window._qRouterHistoryPatch = true;
|
|
347
|
+
const pushState = history.pushState;
|
|
348
|
+
const replaceState = history.replaceState;
|
|
349
|
+
const prepareState = (state) => {
|
|
350
|
+
if (state === null || typeof state === "undefined") state = {};
|
|
351
|
+
else if (state?.constructor !== Object) {
|
|
352
|
+
state = { _data: state };
|
|
353
|
+
if (isDev) console.warn("In a Qwik SPA context, `history.state` is used to store scroll state. Direct calls to `pushState()` and `replaceState()` must supply an actual Object type. We need to be able to automatically attach the scroll state to your state object. A new state object has been created, your data has been moved to: `history.state._data`");
|
|
354
|
+
}
|
|
355
|
+
state._qRouterScroll = state._qRouterScroll || currentScrollState();
|
|
356
|
+
return state;
|
|
357
|
+
};
|
|
358
|
+
history.pushState = (state, title, url) => {
|
|
359
|
+
state = prepareState(state);
|
|
360
|
+
return pushState.call(history, state, title, url);
|
|
361
|
+
};
|
|
362
|
+
history.replaceState = (state, title, url) => {
|
|
363
|
+
state = prepareState(state);
|
|
364
|
+
return replaceState.call(history, state, title, url);
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
window._qRouterInitAnchors = (event) => {
|
|
368
|
+
if (window._qRouterSPA || event.defaultPrevented) return;
|
|
369
|
+
const target = event.target.closest("a[href]");
|
|
370
|
+
if (target && !target.hasAttribute("preventdefault:click")) {
|
|
371
|
+
const href = target.getAttribute("href");
|
|
372
|
+
const prev = new URL(location.href);
|
|
373
|
+
const dest = new URL(href, prev);
|
|
374
|
+
const sameOrigin = dest.origin === prev.origin;
|
|
375
|
+
const samePath = dest.pathname + dest.search === prev.pathname + prev.search;
|
|
376
|
+
if (sameOrigin && samePath) {
|
|
377
|
+
event.preventDefault();
|
|
378
|
+
if (dest.href !== prev.href) history.pushState(null, "", dest);
|
|
379
|
+
if (!dest.hash) {
|
|
380
|
+
if (dest.href.endsWith("#")) window.scrollTo(0, 0);
|
|
381
|
+
else {
|
|
382
|
+
window._qRouterScrollEnabled = false;
|
|
383
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
384
|
+
saveScrollState({
|
|
385
|
+
...currentScrollState(),
|
|
386
|
+
x: 0,
|
|
387
|
+
y: 0
|
|
388
|
+
});
|
|
389
|
+
location.reload();
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
const elmId = dest.hash.slice(1);
|
|
393
|
+
const elm = document.getElementById(elmId);
|
|
394
|
+
if (elm) elm.scrollIntoView();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
window._qRouterInitVisibility = () => {
|
|
400
|
+
if (!window._qRouterSPA && window._qRouterScrollEnabled && document.visibilityState === "hidden") saveScrollState();
|
|
401
|
+
};
|
|
402
|
+
window._qRouterInitScroll = () => {
|
|
403
|
+
if (window._qRouterSPA || !window._qRouterScrollEnabled) return;
|
|
404
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
405
|
+
window._qRouterScrollDebounce = setTimeout(() => {
|
|
406
|
+
saveScrollState();
|
|
407
|
+
window._qRouterScrollDebounce = void 0;
|
|
408
|
+
}, 200);
|
|
409
|
+
};
|
|
410
|
+
window._qRouterScrollEnabled = true;
|
|
411
|
+
window.addEventListener("popstate", window._qRouterInitPopstate);
|
|
412
|
+
window.addEventListener("scroll", window._qRouterInitScroll, { passive: true });
|
|
413
|
+
document.addEventListener("click", window._qRouterInitAnchors);
|
|
414
|
+
if (!window.navigation) document.addEventListener("visibilitychange", window._qRouterInitVisibility, { passive: true });
|
|
415
|
+
}
|
|
416
|
+
}, "spa_init_event_igI1pUsax0E"));
|
|
417
|
+
/**
|
|
418
|
+
* Submit an action to the server and get the result.
|
|
419
|
+
*
|
|
420
|
+
* POSTs to the route URL with `qaction={actionId}` appended and `Accept: application/json`. The
|
|
421
|
+
* server runs the action and returns the action result, optionally with the loader hashes that
|
|
422
|
+
* should be invalidated.
|
|
423
|
+
*/ async function submitAction(action, routeUrl) {
|
|
424
|
+
const pathBase = ensureSlash(routeUrl.pathname);
|
|
425
|
+
const searchParams = new URLSearchParams(routeUrl.search);
|
|
426
|
+
searchParams.set(QACTION_KEY, action.id);
|
|
427
|
+
const url = `${pathBase}?${searchParams.toString()}`;
|
|
428
|
+
const actionData = action.data;
|
|
429
|
+
action.data = void 0;
|
|
430
|
+
let fetchOptions;
|
|
431
|
+
if (actionData instanceof FormData) fetchOptions = {
|
|
432
|
+
method: "POST",
|
|
433
|
+
body: actionData,
|
|
434
|
+
headers: { Accept: "application/json" }
|
|
435
|
+
};
|
|
436
|
+
else fetchOptions = {
|
|
437
|
+
method: "POST",
|
|
438
|
+
body: JSON.stringify(actionData),
|
|
439
|
+
headers: {
|
|
440
|
+
"Content-Type": "application/json; charset=UTF-8",
|
|
441
|
+
Accept: "application/json"
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
const response = await fetch(url, fetchOptions);
|
|
445
|
+
if (response.redirected) {
|
|
446
|
+
const redirectedURL = new URL(response.url);
|
|
447
|
+
if (redirectedURL.origin !== location.origin) {
|
|
448
|
+
location.href = redirectedURL.href;
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
location.href = redirectedURL.href;
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if ((response.headers.get("content-type") || "").includes("json")) {
|
|
455
|
+
const text = await response.text();
|
|
456
|
+
const data = await _deserialize(text);
|
|
457
|
+
return {
|
|
458
|
+
status: response.status,
|
|
459
|
+
result: data?.result,
|
|
460
|
+
redirect: data?.redirect,
|
|
461
|
+
loaderHashes: data?.loaderHashes
|
|
462
|
+
};
|
|
463
|
+
}
|
|
524
464
|
}
|
|
525
|
-
var
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
MenuDataProp2[MenuDataProp2["MenuLoader"] = 1] = "MenuLoader";
|
|
535
|
-
return MenuDataProp2;
|
|
536
|
-
}({});
|
|
537
|
-
const loadRoute = async (routes, menus, cacheModules, pathname) => {
|
|
538
|
-
if (!Array.isArray(routes)) {
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
|
-
for (const routeData of routes) {
|
|
542
|
-
const routeName = routeData[RouteDataProp.RouteName];
|
|
543
|
-
const params = matchRoute(routeName, pathname);
|
|
544
|
-
if (!params) {
|
|
545
|
-
continue;
|
|
546
|
-
}
|
|
547
|
-
const loaders = routeData[RouteDataProp.Loaders];
|
|
548
|
-
const routeBundleNames = routeData[RouteDataProp.RouteBundleNames];
|
|
549
|
-
const modules = new Array(loaders.length);
|
|
550
|
-
const pendingLoads = [];
|
|
551
|
-
loaders.forEach((moduleLoader, i) => {
|
|
552
|
-
loadModule(moduleLoader, pendingLoads, (routeModule) => modules[i] = routeModule, cacheModules);
|
|
553
|
-
});
|
|
554
|
-
const menuLoader = getMenuLoader(menus, pathname);
|
|
555
|
-
let menu = void 0;
|
|
556
|
-
loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
|
|
557
|
-
if (pendingLoads.length > 0) {
|
|
558
|
-
await Promise.all(pendingLoads);
|
|
559
|
-
}
|
|
560
|
-
return [
|
|
561
|
-
routeName,
|
|
562
|
-
params,
|
|
563
|
-
modules,
|
|
564
|
-
deepFreeze(menu),
|
|
565
|
-
routeBundleNames
|
|
566
|
-
];
|
|
567
|
-
}
|
|
568
|
-
return null;
|
|
465
|
+
var qwik_view_transition_default = "@layer qwik{@supports selector(html:active-view-transition-type(type)){html:active-view-transition-type(qwik-navigation){& :root{view-transition-name:none}}}@supports not selector(html:active-view-transition-type(type)){:root{view-transition-name:none}}}";
|
|
466
|
+
/** View transitions are opt-in and require browser support. */ var shouldStartViewTransition = (viewTransition) => viewTransition === true && "startViewTransition" in document;
|
|
467
|
+
var VIEW_TRANSITION_STYLE_ID = "qwik-view-transition";
|
|
468
|
+
/** Inject the view-transition stylesheet once, only when a transition actually runs. */ var ensureViewTransitionStyles = () => {
|
|
469
|
+
if (document.getElementById(VIEW_TRANSITION_STYLE_ID)) return;
|
|
470
|
+
const style = document.createElement("style");
|
|
471
|
+
style.id = VIEW_TRANSITION_STYLE_ID;
|
|
472
|
+
style.textContent = qwik_view_transition_default;
|
|
473
|
+
document.head.appendChild(style);
|
|
569
474
|
};
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
475
|
+
var startViewTransition = (params) => {
|
|
476
|
+
if ("startViewTransition" in document) {
|
|
477
|
+
ensureViewTransitionStyles();
|
|
478
|
+
let transition;
|
|
479
|
+
try {
|
|
480
|
+
transition = document.startViewTransition(params);
|
|
481
|
+
} catch {
|
|
482
|
+
transition = document.startViewTransition(params.update);
|
|
483
|
+
}
|
|
484
|
+
const event = new CustomEvent("qviewtransition", { detail: transition });
|
|
485
|
+
document.dispatchEvent(event);
|
|
486
|
+
return {
|
|
487
|
+
ready: transition.ready,
|
|
488
|
+
transition
|
|
489
|
+
};
|
|
490
|
+
} else return { ready: params.update() };
|
|
589
491
|
};
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
492
|
+
/**
|
|
493
|
+
* Qwik Router Component
|
|
494
|
+
*
|
|
495
|
+
* This file contains the main Qwik Router component, which initializes the router and provides the
|
|
496
|
+
* necessary context for it to work. It also contains the logic for handling navigation, including
|
|
497
|
+
* updating the URL, managing scroll restoration, and resolving document head changes.
|
|
498
|
+
*
|
|
499
|
+
* Note: This component is designed to work both on the server and the client. During server-side
|
|
500
|
+
* rendering (SSR), it initializes the router state based on the URL and route data provided by the
|
|
501
|
+
* server environment. On the client, it handles navigation events and updates the router state
|
|
502
|
+
* accordingly.
|
|
503
|
+
*
|
|
504
|
+
* SSR is _required_ for the initial load.
|
|
505
|
+
*
|
|
506
|
+
* The flow of navigation is as follows:
|
|
507
|
+
*
|
|
508
|
+
* 1. During SSR, the server environment parses the initial URL and collects the route data.
|
|
509
|
+
* 2. It runs the middleware hooks (`onRequest`, `onGet`, `onPost`, etc.), and responds to q-loader,
|
|
510
|
+
* action$ and server$ requests.
|
|
511
|
+
* 3. If SSR is deemed appropriate, the route data is provided via `useServerData` and this component
|
|
512
|
+
* uses it to initialize the router contexts, register Tasks, and render the Slot. This component
|
|
513
|
+
* will never render again.
|
|
514
|
+
* 4. Then, slotted components like `<DocumentHeadTags />` and `<RouterOutlet />` can consume the route
|
|
515
|
+
* data to render the page.
|
|
516
|
+
* 5. On the client, when a navigation event occurs, this calls `goto()`, which updates the URL in the
|
|
517
|
+
* same tick, loads the route data and adjusts the router context.
|
|
518
|
+
* 6. The changed contexts trigger the slotted components to re-render with the new route data.
|
|
519
|
+
*
|
|
520
|
+
* Since the head data can depend on route loaders and they get their data asynchronously and can
|
|
521
|
+
* update without navigation, the head is resolved in a separate Task that tracks the relevant
|
|
522
|
+
* signals.
|
|
523
|
+
*/
|
|
524
|
+
/**
|
|
525
|
+
* @deprecated Use `QWIK_ROUTER_SCROLLER` instead (will be removed in V3)
|
|
526
|
+
* @public
|
|
527
|
+
*/ var QWIK_CITY_SCROLLER = "_qCityScroller";
|
|
528
|
+
/** @public */ var QWIK_ROUTER_SCROLLER = "_qRouterScroller";
|
|
529
|
+
var preventNav = {};
|
|
530
|
+
var internalState = { navCount: 0 };
|
|
531
|
+
var getScroller = () => {
|
|
532
|
+
let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
|
|
533
|
+
if (!scroller) {
|
|
534
|
+
scroller = document.getElementById(QWIK_CITY_SCROLLER);
|
|
535
|
+
if (scroller && isDev) console.warn(`Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`);
|
|
536
|
+
}
|
|
537
|
+
return scroller ?? document.documentElement;
|
|
598
538
|
};
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
const
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
};
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const scrollEnabled = "_qRouterScrollEnabled";
|
|
653
|
-
const debounceTimeout = "_qRouterScrollDebounce";
|
|
654
|
-
const scrollHistory = "_qRouterScroll";
|
|
655
|
-
const checkAndScroll = (scrollState) => {
|
|
656
|
-
if (scrollState) {
|
|
657
|
-
win.scrollTo(scrollState.x, scrollState.y);
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
const currentScrollState2 = () => {
|
|
661
|
-
const elm = document.documentElement;
|
|
662
|
-
return {
|
|
663
|
-
x: elm.scrollLeft,
|
|
664
|
-
y: elm.scrollTop,
|
|
665
|
-
w: Math.max(elm.scrollWidth, elm.clientWidth),
|
|
666
|
-
h: Math.max(elm.scrollHeight, elm.clientHeight)
|
|
667
|
-
};
|
|
668
|
-
};
|
|
669
|
-
const saveScrollState = (scrollState) => {
|
|
670
|
-
const state = history.state || {};
|
|
671
|
-
state[scrollHistory] = scrollState || currentScrollState2();
|
|
672
|
-
history.replaceState(state, "");
|
|
673
|
-
};
|
|
674
|
-
saveScrollState();
|
|
675
|
-
win[initPopstate] = () => {
|
|
676
|
-
if (win[spa]) {
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
win[scrollEnabled] = false;
|
|
680
|
-
clearTimeout(win[debounceTimeout]);
|
|
681
|
-
if (currentPath !== location.pathname + location.search) {
|
|
682
|
-
const getContainer = (el2) => el2.closest("[q\\:container]:not([q\\:container=html]):not([q\\:container=text])");
|
|
683
|
-
const container = getContainer(el);
|
|
684
|
-
const domContainer = container.qContainer;
|
|
685
|
-
const hostElement = domContainer.vNodeLocate(el);
|
|
686
|
-
const nav = domContainer?.resolveContext(hostElement, {
|
|
687
|
-
id: "qc--n"
|
|
688
|
-
});
|
|
689
|
-
if (nav) {
|
|
690
|
-
nav(location.href, {
|
|
691
|
-
type: "popstate"
|
|
692
|
-
});
|
|
693
|
-
} else {
|
|
694
|
-
location.reload();
|
|
695
|
-
}
|
|
696
|
-
} else {
|
|
697
|
-
if (history.scrollRestoration === "manual") {
|
|
698
|
-
const scrollState = history.state?.[scrollHistory];
|
|
699
|
-
checkAndScroll(scrollState);
|
|
700
|
-
win[scrollEnabled] = true;
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
if (!win[historyPatch]) {
|
|
705
|
-
win[historyPatch] = true;
|
|
706
|
-
const pushState = history.pushState;
|
|
707
|
-
const replaceState = history.replaceState;
|
|
708
|
-
const prepareState = (state) => {
|
|
709
|
-
if (state === null || typeof state === "undefined") {
|
|
710
|
-
state = {};
|
|
711
|
-
} else if (state?.constructor !== Object) {
|
|
712
|
-
state = {
|
|
713
|
-
_data: state
|
|
714
|
-
};
|
|
715
|
-
if (isDev) {
|
|
716
|
-
console.warn("In a Qwik SPA context, `history.state` is used to store scroll state. Direct calls to `pushState()` and `replaceState()` must supply an actual Object type. We need to be able to automatically attach the scroll state to your state object. A new state object has been created, your data has been moved to: `history.state._data`");
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
state._qRouterScroll = state._qRouterScroll || currentScrollState2();
|
|
720
|
-
return state;
|
|
721
|
-
};
|
|
722
|
-
history.pushState = (state, title, url) => {
|
|
723
|
-
state = prepareState(state);
|
|
724
|
-
return pushState.call(history, state, title, url);
|
|
725
|
-
};
|
|
726
|
-
history.replaceState = (state, title, url) => {
|
|
727
|
-
state = prepareState(state);
|
|
728
|
-
return replaceState.call(history, state, title, url);
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
win[initAnchors] = (event) => {
|
|
732
|
-
if (win[spa] || event.defaultPrevented) {
|
|
733
|
-
return;
|
|
734
|
-
}
|
|
735
|
-
const target = event.target.closest("a[href]");
|
|
736
|
-
if (target && !target.hasAttribute("preventdefault:click")) {
|
|
737
|
-
const href = target.getAttribute("href");
|
|
738
|
-
const prev = new URL(location.href);
|
|
739
|
-
const dest = new URL(href, prev);
|
|
740
|
-
const sameOrigin = dest.origin === prev.origin;
|
|
741
|
-
const samePath = dest.pathname + dest.search === prev.pathname + prev.search;
|
|
742
|
-
if (sameOrigin && samePath) {
|
|
743
|
-
event.preventDefault();
|
|
744
|
-
if (dest.href !== prev.href) {
|
|
745
|
-
history.pushState(null, "", dest);
|
|
746
|
-
}
|
|
747
|
-
if (!dest.hash) {
|
|
748
|
-
if (dest.href.endsWith("#")) {
|
|
749
|
-
window.scrollTo(0, 0);
|
|
750
|
-
} else {
|
|
751
|
-
win[scrollEnabled] = false;
|
|
752
|
-
clearTimeout(win[debounceTimeout]);
|
|
753
|
-
saveScrollState({
|
|
754
|
-
...currentScrollState2(),
|
|
755
|
-
x: 0,
|
|
756
|
-
y: 0
|
|
757
|
-
});
|
|
758
|
-
location.reload();
|
|
759
|
-
}
|
|
760
|
-
} else {
|
|
761
|
-
const elmId = dest.hash.slice(1);
|
|
762
|
-
const elm = document.getElementById(elmId);
|
|
763
|
-
if (elm) {
|
|
764
|
-
elm.scrollIntoView();
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
win[initVisibility] = () => {
|
|
771
|
-
if (!win[spa] && win[scrollEnabled] && document.visibilityState === "hidden") {
|
|
772
|
-
saveScrollState();
|
|
773
|
-
}
|
|
774
|
-
};
|
|
775
|
-
win[initScroll] = () => {
|
|
776
|
-
if (win[spa] || !win[scrollEnabled]) {
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
clearTimeout(win[debounceTimeout]);
|
|
780
|
-
win[debounceTimeout] = setTimeout(() => {
|
|
781
|
-
saveScrollState();
|
|
782
|
-
win[debounceTimeout] = void 0;
|
|
783
|
-
}, 200);
|
|
784
|
-
};
|
|
785
|
-
win[scrollEnabled] = true;
|
|
786
|
-
setTimeout(() => {
|
|
787
|
-
addEventListener("popstate", win[initPopstate]);
|
|
788
|
-
addEventListener("scroll", win[initScroll], {
|
|
789
|
-
passive: true
|
|
790
|
-
});
|
|
791
|
-
document.body.addEventListener("click", win[initAnchors]);
|
|
792
|
-
if (!win.navigation) {
|
|
793
|
-
document.addEventListener("visibilitychange", win[initVisibility], {
|
|
794
|
-
passive: true
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
}, 0);
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
const startViewTransition = (params) => {
|
|
801
|
-
if (!params.update) {
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
if ("startViewTransition" in document) {
|
|
805
|
-
let transition;
|
|
806
|
-
try {
|
|
807
|
-
transition = document.startViewTransition(params);
|
|
808
|
-
} catch {
|
|
809
|
-
transition = document.startViewTransition(params.update);
|
|
810
|
-
}
|
|
811
|
-
const event = new CustomEvent("qviewtransition", {
|
|
812
|
-
detail: transition
|
|
813
|
-
});
|
|
814
|
-
document.dispatchEvent(event);
|
|
815
|
-
return transition;
|
|
816
|
-
} else {
|
|
817
|
-
params.update?.();
|
|
818
|
-
}
|
|
539
|
+
/** @public */ var useQwikMockRouter = (props) => {
|
|
540
|
+
const urlEnv = props.url ?? "http://localhost/";
|
|
541
|
+
const url = new URL(urlEnv);
|
|
542
|
+
const routeLocation = useStore({
|
|
543
|
+
url,
|
|
544
|
+
params: props.params ?? {},
|
|
545
|
+
isNavigating: false,
|
|
546
|
+
prevUrl: void 0
|
|
547
|
+
}, { deep: false });
|
|
548
|
+
const loadersData = props.loaders?.reduce((acc, { loader, data }) => {
|
|
549
|
+
acc[loader.__id] = data;
|
|
550
|
+
return acc;
|
|
551
|
+
}, {});
|
|
552
|
+
const loadersState = useStore({}, { deep: false });
|
|
553
|
+
for (const [loaderId, data] of Object.entries(loadersData ?? {})) loadersState[loaderId] ||= createComputedQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
554
|
+
return _captures[0];
|
|
555
|
+
}, "useQwikMockRouter_createComputed_JL6bChMwwyc", [data]));
|
|
556
|
+
const goto = props.goto ?? /*#__PURE__*/ inlinedQrl(async () => {
|
|
557
|
+
console.warn("QwikRouterMockProvider: goto not provided");
|
|
558
|
+
}, "useQwikMockRouter_goto_aViHFxQ1a3s");
|
|
559
|
+
const documentHead = useStore(createDocumentHead, { deep: false });
|
|
560
|
+
const content = useStore({
|
|
561
|
+
headings: void 0,
|
|
562
|
+
menu: void 0
|
|
563
|
+
}, { deep: false });
|
|
564
|
+
const contentInternal = useSignal();
|
|
565
|
+
const actionState = useSignal();
|
|
566
|
+
const httpStatus = useSignal({
|
|
567
|
+
status: 200,
|
|
568
|
+
message: ""
|
|
569
|
+
});
|
|
570
|
+
useContextProvider(ContentContext, content);
|
|
571
|
+
useContextProvider(ContentInternalContext, contentInternal);
|
|
572
|
+
useContextProvider(DocumentHeadContext, documentHead);
|
|
573
|
+
useContextProvider(HttpStatusContext, httpStatus);
|
|
574
|
+
useContextProvider(RouteLocationContext, routeLocation);
|
|
575
|
+
useContextProvider(RouteNavigateContext, goto);
|
|
576
|
+
useContextProvider(RouteStateContext, loadersState);
|
|
577
|
+
useContextProvider(RouteActionContext, actionState);
|
|
578
|
+
const actionsMocks = props.actions?.reduce((acc, { action, handler }) => {
|
|
579
|
+
acc[action.__id] = handler;
|
|
580
|
+
return acc;
|
|
581
|
+
}, {});
|
|
582
|
+
useTaskQrl(/*#__PURE__*/ inlinedQrl(async ({ track }) => {
|
|
583
|
+
const actionState = _captures[0], actionsMocks = _captures[1];
|
|
584
|
+
const action = track(actionState);
|
|
585
|
+
if (!action?.resolve) return;
|
|
586
|
+
const mock = actionsMocks?.[action.id];
|
|
587
|
+
if (mock) {
|
|
588
|
+
const actionResult = await mock(action.data);
|
|
589
|
+
action.resolve(actionResult);
|
|
590
|
+
}
|
|
591
|
+
}, "useQwikMockRouter_useTask_tXTLR4tzCy0", [actionState, actionsMocks]));
|
|
819
592
|
};
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
internalState.navCount++;
|
|
908
|
-
if (!preventNav.$cbs$) {
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
const prevents = [
|
|
912
|
-
...preventNav.$cbs$.values()
|
|
913
|
-
].map((cb) => cb.resolved ? cb.resolved() : cb());
|
|
914
|
-
if (prevents.some(Boolean)) {
|
|
915
|
-
event.preventDefault();
|
|
916
|
-
event.returnValue = true;
|
|
917
|
-
}
|
|
918
|
-
});
|
|
919
|
-
(preventNav.$cbs$ || (preventNav.$cbs$ = /* @__PURE__ */ new Set())).add(fn$);
|
|
920
|
-
fn$.resolve();
|
|
921
|
-
window.addEventListener("beforeunload", preventNav.$handler$);
|
|
922
|
-
return () => {
|
|
923
|
-
if (preventNav.$cbs$) {
|
|
924
|
-
preventNav.$cbs$.delete(fn$);
|
|
925
|
-
if (!preventNav.$cbs$.size) {
|
|
926
|
-
preventNav.$cbs$ = void 0;
|
|
927
|
-
window.removeEventListener("beforeunload", preventNav.$handler$);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
};
|
|
931
|
-
});
|
|
932
|
-
const goto = $(async (path, opt) => {
|
|
933
|
-
const { type = "link", forceReload = path === void 0, replaceState = false, scroll = true } = typeof opt === "object" ? opt : {
|
|
934
|
-
forceReload: opt
|
|
935
|
-
};
|
|
936
|
-
internalState.navCount++;
|
|
937
|
-
const lastDest = routeInternal.value.dest;
|
|
938
|
-
const dest = path === void 0 ? lastDest : typeof path === "number" ? path : toUrl(path, routeLocation.url);
|
|
939
|
-
if (preventNav.$cbs$ && (forceReload || typeof dest === "number" || !isSamePath(dest, lastDest) || !isSameOrigin(dest, lastDest))) {
|
|
940
|
-
const ourNavId = internalState.navCount;
|
|
941
|
-
const prevents = await Promise.all([
|
|
942
|
-
...preventNav.$cbs$.values()
|
|
943
|
-
].map((cb) => cb(dest)));
|
|
944
|
-
if (ourNavId !== internalState.navCount || prevents.some(Boolean)) {
|
|
945
|
-
if (ourNavId === internalState.navCount && type === "popstate") {
|
|
946
|
-
history.pushState(null, "", lastDest);
|
|
947
|
-
}
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
if (typeof dest === "number") {
|
|
952
|
-
if (isBrowser) {
|
|
953
|
-
history.go(dest);
|
|
954
|
-
}
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
if (!isSameOrigin(dest, lastDest)) {
|
|
958
|
-
if (isBrowser) {
|
|
959
|
-
location.href = dest.href;
|
|
960
|
-
}
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
if (!forceReload && isSamePath(dest, lastDest)) {
|
|
964
|
-
if (isBrowser) {
|
|
965
|
-
if (type === "link" && dest.href !== location.href) {
|
|
966
|
-
history.pushState(null, "", dest);
|
|
967
|
-
}
|
|
968
|
-
let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
|
|
969
|
-
if (!scroller) {
|
|
970
|
-
scroller = document.getElementById(QWIK_CITY_SCROLLER);
|
|
971
|
-
if (scroller && isDev) {
|
|
972
|
-
console.warn(`Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
if (!scroller) {
|
|
976
|
-
scroller = document.documentElement;
|
|
977
|
-
}
|
|
978
|
-
restoreScroll(type, dest, new URL(location.href), scroller, getScrollHistory());
|
|
979
|
-
if (type === "popstate") {
|
|
980
|
-
window._qRouterScrollEnabled = true;
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
routeInternal.value = {
|
|
986
|
-
type,
|
|
987
|
-
dest,
|
|
988
|
-
forceReload,
|
|
989
|
-
replaceState,
|
|
990
|
-
scroll
|
|
991
|
-
};
|
|
992
|
-
if (isBrowser) {
|
|
993
|
-
loadClientData(dest, _getContextElement());
|
|
994
|
-
loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, dest.pathname);
|
|
995
|
-
}
|
|
996
|
-
actionState.value = void 0;
|
|
997
|
-
routeLocation.isNavigating = true;
|
|
998
|
-
return new Promise((resolve) => {
|
|
999
|
-
navResolver.r = resolve;
|
|
1000
|
-
});
|
|
1001
|
-
});
|
|
1002
|
-
useContextProvider(ContentContext, content);
|
|
1003
|
-
useContextProvider(ContentInternalContext, contentInternal);
|
|
1004
|
-
useContextProvider(DocumentHeadContext, documentHead);
|
|
1005
|
-
useContextProvider(RouteLocationContext, routeLocation);
|
|
1006
|
-
useContextProvider(RouteNavigateContext, goto);
|
|
1007
|
-
useContextProvider(RouteStateContext, loaderState);
|
|
1008
|
-
useContextProvider(RouteActionContext, actionState);
|
|
1009
|
-
useContextProvider(RouteInternalContext, routeInternal);
|
|
1010
|
-
useContextProvider(RoutePreventNavigateContext, registerPreventNav);
|
|
1011
|
-
useTask$(({ track }) => {
|
|
1012
|
-
async function run() {
|
|
1013
|
-
const [navigation, action] = track(() => [
|
|
1014
|
-
routeInternal.value,
|
|
1015
|
-
actionState.value
|
|
1016
|
-
]);
|
|
1017
|
-
const locale = getLocale("");
|
|
1018
|
-
const prevUrl = routeLocation.url;
|
|
1019
|
-
const navType = action ? "form" : navigation.type;
|
|
1020
|
-
const replaceState = navigation.replaceState;
|
|
1021
|
-
let trackUrl;
|
|
1022
|
-
let clientPageData;
|
|
1023
|
-
let loadedRoute = null;
|
|
1024
|
-
let elm;
|
|
1025
|
-
if (isServer) {
|
|
1026
|
-
trackUrl = new URL(navigation.dest, routeLocation.url);
|
|
1027
|
-
loadedRoute = env.loadedRoute;
|
|
1028
|
-
clientPageData = env.response;
|
|
1029
|
-
} else {
|
|
1030
|
-
trackUrl = new URL(navigation.dest, location);
|
|
1031
|
-
if (trackUrl.pathname.endsWith("/")) {
|
|
1032
|
-
if (!qwikRouterConfig.trailingSlash) {
|
|
1033
|
-
trackUrl.pathname = trackUrl.pathname.slice(0, -1);
|
|
1034
|
-
}
|
|
1035
|
-
} else if (qwikRouterConfig.trailingSlash) {
|
|
1036
|
-
trackUrl.pathname += "/";
|
|
1037
|
-
}
|
|
1038
|
-
let loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, trackUrl.pathname);
|
|
1039
|
-
elm = _getContextElement();
|
|
1040
|
-
const pageData = clientPageData = await loadClientData(trackUrl, elm, {
|
|
1041
|
-
action,
|
|
1042
|
-
clearCache: true
|
|
1043
|
-
});
|
|
1044
|
-
if (!pageData) {
|
|
1045
|
-
routeInternal.untrackedValue = {
|
|
1046
|
-
type: navType,
|
|
1047
|
-
dest: trackUrl
|
|
1048
|
-
};
|
|
1049
|
-
return;
|
|
1050
|
-
}
|
|
1051
|
-
const newHref = pageData.href;
|
|
1052
|
-
const newURL = new URL(newHref, trackUrl);
|
|
1053
|
-
if (!isSamePath(newURL, trackUrl)) {
|
|
1054
|
-
if (!pageData.isRewrite) {
|
|
1055
|
-
trackUrl = newURL;
|
|
1056
|
-
}
|
|
1057
|
-
loadRoutePromise = loadRoute(
|
|
1058
|
-
qwikRouterConfig.routes,
|
|
1059
|
-
qwikRouterConfig.menus,
|
|
1060
|
-
qwikRouterConfig.cacheModules,
|
|
1061
|
-
newURL.pathname
|
|
1062
|
-
// Load the actual required path.
|
|
1063
|
-
);
|
|
1064
|
-
}
|
|
1065
|
-
try {
|
|
1066
|
-
loadedRoute = await loadRoutePromise;
|
|
1067
|
-
} catch (e) {
|
|
1068
|
-
console.error(e);
|
|
1069
|
-
window.location.href = newHref;
|
|
1070
|
-
return;
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
if (loadedRoute) {
|
|
1074
|
-
const [routeName, params, mods, menu] = loadedRoute;
|
|
1075
|
-
const contentModules = mods;
|
|
1076
|
-
const pageModule = contentModules[contentModules.length - 1];
|
|
1077
|
-
const isRedirect = navType === "form" && !isSamePath(trackUrl, prevUrl);
|
|
1078
|
-
if (navigation.dest.search && !isRedirect) {
|
|
1079
|
-
trackUrl.search = navigation.dest.search;
|
|
1080
|
-
}
|
|
1081
|
-
if (!isSamePath(trackUrl, prevUrl)) {
|
|
1082
|
-
routeLocation.prevUrl = prevUrl;
|
|
1083
|
-
}
|
|
1084
|
-
routeLocation.url = trackUrl;
|
|
1085
|
-
routeLocation.params = {
|
|
1086
|
-
...params
|
|
1087
|
-
};
|
|
1088
|
-
routeInternal.untrackedValue = {
|
|
1089
|
-
type: navType,
|
|
1090
|
-
dest: trackUrl
|
|
1091
|
-
};
|
|
1092
|
-
const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale);
|
|
1093
|
-
content.headings = pageModule.headings;
|
|
1094
|
-
content.menu = menu;
|
|
1095
|
-
contentInternal.value = noSerialize(contentModules);
|
|
1096
|
-
documentHead.links = resolvedHead.links;
|
|
1097
|
-
documentHead.meta = resolvedHead.meta;
|
|
1098
|
-
documentHead.styles = resolvedHead.styles;
|
|
1099
|
-
documentHead.scripts = resolvedHead.scripts;
|
|
1100
|
-
documentHead.title = resolvedHead.title;
|
|
1101
|
-
documentHead.frontmatter = resolvedHead.frontmatter;
|
|
1102
|
-
if (isBrowser) {
|
|
1103
|
-
let scrollState;
|
|
1104
|
-
if (navType === "popstate") {
|
|
1105
|
-
scrollState = getScrollHistory();
|
|
1106
|
-
}
|
|
1107
|
-
const scroller = document.getElementById(QWIK_ROUTER_SCROLLER) ?? document.documentElement;
|
|
1108
|
-
if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || isRedirect) {
|
|
1109
|
-
document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
|
|
1110
|
-
}
|
|
1111
|
-
const loaders = clientPageData?.loaders;
|
|
1112
|
-
if (loaders) {
|
|
1113
|
-
const container2 = _getContextContainer();
|
|
1114
|
-
for (const [key, value] of Object.entries(loaders)) {
|
|
1115
|
-
const signal = loaderState[key];
|
|
1116
|
-
const awaitedValue = await value;
|
|
1117
|
-
loadersObject[key] = awaitedValue;
|
|
1118
|
-
if (!signal) {
|
|
1119
|
-
loaderState[key] = createLoaderSignal(loadersObject, key, trackUrl, DEFAULT_LOADERS_SERIALIZATION_STRATEGY, container2);
|
|
1120
|
-
} else {
|
|
1121
|
-
signal.invalidate();
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
CLIENT_DATA_CACHE.clear();
|
|
1126
|
-
const win = window;
|
|
1127
|
-
if (!win._qRouterSPA) {
|
|
1128
|
-
win._qRouterSPA = true;
|
|
1129
|
-
history.scrollRestoration = "manual";
|
|
1130
|
-
win.addEventListener("popstate", () => {
|
|
1131
|
-
win._qRouterScrollEnabled = false;
|
|
1132
|
-
clearTimeout(win._qRouterScrollDebounce);
|
|
1133
|
-
goto(location.href, {
|
|
1134
|
-
type: "popstate"
|
|
1135
|
-
});
|
|
1136
|
-
});
|
|
1137
|
-
win.removeEventListener("popstate", win._qRouterInitPopstate);
|
|
1138
|
-
win._qRouterInitPopstate = void 0;
|
|
1139
|
-
if (!win._qRouterHistoryPatch) {
|
|
1140
|
-
win._qRouterHistoryPatch = true;
|
|
1141
|
-
const pushState = history.pushState;
|
|
1142
|
-
const replaceState2 = history.replaceState;
|
|
1143
|
-
const prepareState = (state) => {
|
|
1144
|
-
if (state === null || typeof state === "undefined") {
|
|
1145
|
-
state = {};
|
|
1146
|
-
} else if (state?.constructor !== Object) {
|
|
1147
|
-
state = {
|
|
1148
|
-
_data: state
|
|
1149
|
-
};
|
|
1150
|
-
if (isDev) {
|
|
1151
|
-
console.warn("In a Qwik SPA context, `history.state` is used to store scroll state. Direct calls to `pushState()` and `replaceState()` must supply an actual Object type. We need to be able to automatically attach the scroll state to your state object. A new state object has been created, your data has been moved to: `history.state._data`");
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
|
|
1155
|
-
return state;
|
|
1156
|
-
};
|
|
1157
|
-
history.pushState = (state, title, url2) => {
|
|
1158
|
-
state = prepareState(state);
|
|
1159
|
-
return pushState.call(history, state, title, url2);
|
|
1160
|
-
};
|
|
1161
|
-
history.replaceState = (state, title, url2) => {
|
|
1162
|
-
state = prepareState(state);
|
|
1163
|
-
return replaceState2.call(history, state, title, url2);
|
|
1164
|
-
};
|
|
1165
|
-
}
|
|
1166
|
-
document.body.addEventListener("click", (event) => {
|
|
1167
|
-
if (event.defaultPrevented) {
|
|
1168
|
-
return;
|
|
1169
|
-
}
|
|
1170
|
-
const target = event.target.closest("a[href]");
|
|
1171
|
-
if (target && !target.hasAttribute("preventdefault:click")) {
|
|
1172
|
-
const href = target.getAttribute("href");
|
|
1173
|
-
const prev = new URL(location.href);
|
|
1174
|
-
const dest = new URL(href, prev);
|
|
1175
|
-
if (isSameOrigin(dest, prev) && isSamePath(dest, prev)) {
|
|
1176
|
-
event.preventDefault();
|
|
1177
|
-
if (!dest.hash && !dest.href.endsWith("#")) {
|
|
1178
|
-
if (dest.href !== prev.href) {
|
|
1179
|
-
history.pushState(null, "", dest);
|
|
1180
|
-
}
|
|
1181
|
-
win._qRouterScrollEnabled = false;
|
|
1182
|
-
clearTimeout(win._qRouterScrollDebounce);
|
|
1183
|
-
saveScrollHistory({
|
|
1184
|
-
...currentScrollState(scroller),
|
|
1185
|
-
x: 0,
|
|
1186
|
-
y: 0
|
|
1187
|
-
});
|
|
1188
|
-
location.reload();
|
|
1189
|
-
return;
|
|
1190
|
-
}
|
|
1191
|
-
goto(target.getAttribute("href"));
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
});
|
|
1195
|
-
document.body.removeEventListener("click", win._qRouterInitAnchors);
|
|
1196
|
-
win._qRouterInitAnchors = void 0;
|
|
1197
|
-
if (!window.navigation) {
|
|
1198
|
-
document.addEventListener("visibilitychange", () => {
|
|
1199
|
-
if ((win._qRouterScrollEnabled || win._qCityScrollEnabled) && document.visibilityState === "hidden") {
|
|
1200
|
-
if (win._qCityScrollEnabled) {
|
|
1201
|
-
console.warn('"_qCityScrollEnabled" is deprecated. Use "_qRouterScrollEnabled" instead.');
|
|
1202
|
-
}
|
|
1203
|
-
const scrollState2 = currentScrollState(scroller);
|
|
1204
|
-
saveScrollHistory(scrollState2);
|
|
1205
|
-
}
|
|
1206
|
-
}, {
|
|
1207
|
-
passive: true
|
|
1208
|
-
});
|
|
1209
|
-
document.removeEventListener("visibilitychange", win._qRouterInitVisibility);
|
|
1210
|
-
win._qRouterInitVisibility = void 0;
|
|
1211
|
-
}
|
|
1212
|
-
win.addEventListener("scroll", () => {
|
|
1213
|
-
if (!win._qRouterScrollEnabled && !win._qCityScrollEnabled) {
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
clearTimeout(win._qRouterScrollDebounce);
|
|
1217
|
-
win._qRouterScrollDebounce = setTimeout(() => {
|
|
1218
|
-
const scrollState2 = currentScrollState(scroller);
|
|
1219
|
-
saveScrollHistory(scrollState2);
|
|
1220
|
-
win._qRouterScrollDebounce = void 0;
|
|
1221
|
-
}, 200);
|
|
1222
|
-
}, {
|
|
1223
|
-
passive: true
|
|
1224
|
-
});
|
|
1225
|
-
removeEventListener("scroll", win._qRouterInitScroll);
|
|
1226
|
-
win._qRouterInitScroll = void 0;
|
|
1227
|
-
spaInit.resolve();
|
|
1228
|
-
}
|
|
1229
|
-
if (navType !== "popstate") {
|
|
1230
|
-
win._qRouterScrollEnabled = false;
|
|
1231
|
-
clearTimeout(win._qRouterScrollDebounce);
|
|
1232
|
-
const scrollState2 = currentScrollState(scroller);
|
|
1233
|
-
saveScrollHistory(scrollState2);
|
|
1234
|
-
}
|
|
1235
|
-
const navigate = () => {
|
|
1236
|
-
clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
|
|
1237
|
-
return _waitUntilRendered(elm);
|
|
1238
|
-
};
|
|
1239
|
-
const _waitNextPage = () => {
|
|
1240
|
-
if (isServer || props.viewTransition === false) {
|
|
1241
|
-
return navigate();
|
|
1242
|
-
} else {
|
|
1243
|
-
const viewTransition = startViewTransition({
|
|
1244
|
-
update: navigate,
|
|
1245
|
-
types: [
|
|
1246
|
-
"qwik-navigation"
|
|
1247
|
-
]
|
|
1248
|
-
});
|
|
1249
|
-
if (!viewTransition) {
|
|
1250
|
-
return Promise.resolve();
|
|
1251
|
-
}
|
|
1252
|
-
return viewTransition.ready;
|
|
1253
|
-
}
|
|
1254
|
-
};
|
|
1255
|
-
_waitNextPage().then(() => {
|
|
1256
|
-
const container2 = _getQContainerElement(elm);
|
|
1257
|
-
container2.setAttribute(Q_ROUTE, routeName);
|
|
1258
|
-
const scrollState2 = currentScrollState(scroller);
|
|
1259
|
-
saveScrollHistory(scrollState2);
|
|
1260
|
-
win._qRouterScrollEnabled = true;
|
|
1261
|
-
if (isBrowser) {
|
|
1262
|
-
callRestoreScrollOnDocument();
|
|
1263
|
-
}
|
|
1264
|
-
routeLocation.isNavigating = false;
|
|
1265
|
-
navResolver.r?.();
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
if (isServer) {
|
|
1271
|
-
return run();
|
|
1272
|
-
} else {
|
|
1273
|
-
run();
|
|
1274
|
-
}
|
|
1275
|
-
});
|
|
1276
|
-
return /* @__PURE__ */ jsx(Slot, {});
|
|
1277
|
-
});
|
|
1278
|
-
const QwikCityProvider = QwikRouterProvider;
|
|
1279
|
-
const QwikRouterMockProvider = component$((props) => {
|
|
1280
|
-
const urlEnv = props.url ?? "http://localhost/";
|
|
1281
|
-
const url = new URL(urlEnv);
|
|
1282
|
-
const routeLocation = useStore({
|
|
1283
|
-
url,
|
|
1284
|
-
params: props.params ?? {},
|
|
1285
|
-
isNavigating: false,
|
|
1286
|
-
prevUrl: void 0
|
|
1287
|
-
}, {
|
|
1288
|
-
deep: false
|
|
1289
|
-
});
|
|
1290
|
-
const loaderState = {};
|
|
1291
|
-
const routeInternal = useSignal({
|
|
1292
|
-
type: "initial",
|
|
1293
|
-
dest: url
|
|
1294
|
-
});
|
|
1295
|
-
const goto = props.goto ?? $(async () => {
|
|
1296
|
-
console.warn("QwikRouterMockProvider: goto not provided");
|
|
1297
|
-
});
|
|
1298
|
-
const documentHead = useStore(createDocumentHead, {
|
|
1299
|
-
deep: false
|
|
1300
|
-
});
|
|
1301
|
-
const content = useStore({
|
|
1302
|
-
headings: void 0,
|
|
1303
|
-
menu: void 0
|
|
1304
|
-
}, {
|
|
1305
|
-
deep: false
|
|
1306
|
-
});
|
|
1307
|
-
const contentInternal = useSignal();
|
|
1308
|
-
const actionState = useSignal();
|
|
1309
|
-
useContextProvider(ContentContext, content);
|
|
1310
|
-
useContextProvider(ContentInternalContext, contentInternal);
|
|
1311
|
-
useContextProvider(DocumentHeadContext, documentHead);
|
|
1312
|
-
useContextProvider(RouteLocationContext, routeLocation);
|
|
1313
|
-
useContextProvider(RouteNavigateContext, goto);
|
|
1314
|
-
useContextProvider(RouteStateContext, loaderState);
|
|
1315
|
-
useContextProvider(RouteActionContext, actionState);
|
|
1316
|
-
useContextProvider(RouteInternalContext, routeInternal);
|
|
1317
|
-
return /* @__PURE__ */ jsx(Slot, {});
|
|
1318
|
-
});
|
|
1319
|
-
const QwikCityMockProvider = QwikRouterMockProvider;
|
|
1320
|
-
const RouterOutlet = component$(() => {
|
|
1321
|
-
const serverData = useServerData("containerAttributes");
|
|
1322
|
-
if (!serverData) {
|
|
1323
|
-
throw new Error("PrefetchServiceWorker component must be rendered on the server.");
|
|
1324
|
-
}
|
|
1325
|
-
const { value } = useContext(ContentInternalContext);
|
|
1326
|
-
if (value && value.length > 0) {
|
|
1327
|
-
const contentsLen = value.length;
|
|
1328
|
-
let cmp = null;
|
|
1329
|
-
for (let i = contentsLen - 1; i >= 0; i--) {
|
|
1330
|
-
if (value[i].default) {
|
|
1331
|
-
cmp = jsx$1(value[i].default, {
|
|
1332
|
-
children: cmp
|
|
1333
|
-
});
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
return /* @__PURE__ */ jsxs(Fragment, {
|
|
1337
|
-
children: [
|
|
1338
|
-
cmp,
|
|
1339
|
-
!__EXPERIMENTAL__.noSPA && /* @__PURE__ */ jsx("script", {
|
|
1340
|
-
"document:onQCInit$": spaInit,
|
|
1341
|
-
"document:onQInit$": sync$(() => {
|
|
1342
|
-
((w, h) => {
|
|
1343
|
-
if (!w._qcs && h.scrollRestoration === "manual") {
|
|
1344
|
-
w._qcs = true;
|
|
1345
|
-
const s = h.state?._qRouterScroll;
|
|
1346
|
-
if (s) {
|
|
1347
|
-
w.scrollTo(s.x, s.y);
|
|
1348
|
-
}
|
|
1349
|
-
document.dispatchEvent(new Event("qcinit"));
|
|
1350
|
-
}
|
|
1351
|
-
})(window, history);
|
|
1352
|
-
})
|
|
1353
|
-
})
|
|
1354
|
-
]
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
return SkipRender;
|
|
1358
|
-
});
|
|
1359
|
-
var store;
|
|
1360
|
-
function getGlobalConfig(config2) {
|
|
1361
|
-
return {
|
|
1362
|
-
lang: config2?.lang ?? store?.lang,
|
|
1363
|
-
message: config2?.message,
|
|
1364
|
-
abortEarly: config2?.abortEarly ?? store?.abortEarly,
|
|
1365
|
-
abortPipeEarly: config2?.abortPipeEarly ?? store?.abortPipeEarly
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
|
-
function getDotPath(issue) {
|
|
1369
|
-
if (issue.path) {
|
|
1370
|
-
let key = "";
|
|
1371
|
-
for (const item of issue.path) {
|
|
1372
|
-
if (typeof item.key === "string" || typeof item.key === "number") {
|
|
1373
|
-
if (key) {
|
|
1374
|
-
key += `.${item.key}`;
|
|
1375
|
-
} else {
|
|
1376
|
-
key += item.key;
|
|
1377
|
-
}
|
|
1378
|
-
} else {
|
|
1379
|
-
return null;
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
return key;
|
|
1383
|
-
}
|
|
1384
|
-
return null;
|
|
1385
|
-
}
|
|
1386
|
-
function flatten(issues) {
|
|
1387
|
-
const flatErrors = {};
|
|
1388
|
-
for (const issue of issues) {
|
|
1389
|
-
if (issue.path) {
|
|
1390
|
-
const dotPath = getDotPath(issue);
|
|
1391
|
-
if (dotPath) {
|
|
1392
|
-
if (!flatErrors.nested) {
|
|
1393
|
-
flatErrors.nested = {};
|
|
1394
|
-
}
|
|
1395
|
-
if (flatErrors.nested[dotPath]) {
|
|
1396
|
-
flatErrors.nested[dotPath].push(issue.message);
|
|
1397
|
-
} else {
|
|
1398
|
-
flatErrors.nested[dotPath] = [issue.message];
|
|
1399
|
-
}
|
|
1400
|
-
} else {
|
|
1401
|
-
if (flatErrors.other) {
|
|
1402
|
-
flatErrors.other.push(issue.message);
|
|
1403
|
-
} else {
|
|
1404
|
-
flatErrors.other = [issue.message];
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
} else {
|
|
1408
|
-
if (flatErrors.root) {
|
|
1409
|
-
flatErrors.root.push(issue.message);
|
|
1410
|
-
} else {
|
|
1411
|
-
flatErrors.root = [issue.message];
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
return flatErrors;
|
|
1416
|
-
}
|
|
1417
|
-
async function safeParseAsync(schema, input, config2) {
|
|
1418
|
-
const dataset = await schema._run(
|
|
1419
|
-
{ typed: false, value: input },
|
|
1420
|
-
getGlobalConfig(config2)
|
|
1421
|
-
);
|
|
1422
|
-
return {
|
|
1423
|
-
typed: dataset.typed,
|
|
1424
|
-
success: !dataset.issues,
|
|
1425
|
-
output: dataset.value,
|
|
1426
|
-
issues: dataset.issues
|
|
1427
|
-
};
|
|
593
|
+
/** @public */ var QwikRouterMockProvider = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
594
|
+
useQwikMockRouter(props);
|
|
595
|
+
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "5y_1");
|
|
596
|
+
}, "QwikRouterMockProvider_component_IN4dVpT0x74"));
|
|
597
|
+
/**
|
|
598
|
+
* @deprecated Use `useQwikMockRouter()` instead. Will be removed in V3
|
|
599
|
+
* @public
|
|
600
|
+
*/ var QwikCityMockProvider = QwikRouterMockProvider;
|
|
601
|
+
function initializeSPA(goto, scroller) {
|
|
602
|
+
if (!window._qRouterSPA) {
|
|
603
|
+
window._qRouterSPA = true;
|
|
604
|
+
history.scrollRestoration = "manual";
|
|
605
|
+
window.addEventListener("popstate", () => {
|
|
606
|
+
window._qRouterScrollEnabled = false;
|
|
607
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
608
|
+
goto(location.href, { type: "popstate" });
|
|
609
|
+
});
|
|
610
|
+
window.removeEventListener("popstate", window._qRouterInitPopstate);
|
|
611
|
+
window._qRouterInitPopstate = void 0;
|
|
612
|
+
if (!window._qRouterHistoryPatch) {
|
|
613
|
+
window._qRouterHistoryPatch = true;
|
|
614
|
+
const pushState = history.pushState;
|
|
615
|
+
const replaceState = history.replaceState;
|
|
616
|
+
const prepareState = (state) => {
|
|
617
|
+
if (state === null || typeof state === "undefined") state = {};
|
|
618
|
+
else if (state?.constructor !== Object) {
|
|
619
|
+
state = { _data: state };
|
|
620
|
+
if (isDev) console.warn("In a Qwik SPA context, `history.state` is used to store scroll state. Direct calls to `pushState()` and `replaceState()` must supply an actual Object type. We need to be able to automatically attach the scroll state to your state object. A new state object has been created, your data has been moved to: `history.state._data`");
|
|
621
|
+
}
|
|
622
|
+
state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
|
|
623
|
+
return state;
|
|
624
|
+
};
|
|
625
|
+
history.pushState = (state, title, url) => {
|
|
626
|
+
state = prepareState(state);
|
|
627
|
+
return pushState.call(history, state, title, url);
|
|
628
|
+
};
|
|
629
|
+
history.replaceState = (state, title, url) => {
|
|
630
|
+
state = prepareState(state);
|
|
631
|
+
return replaceState.call(history, state, title, url);
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
document.addEventListener("click", (event) => {
|
|
635
|
+
if (event.defaultPrevented) return;
|
|
636
|
+
const target = event.target.closest("a[href]");
|
|
637
|
+
if (target && !target.hasAttribute("preventdefault:click")) {
|
|
638
|
+
const href = target.getAttribute("href");
|
|
639
|
+
const prev = new URL(location.href);
|
|
640
|
+
const dest = new URL(href, prev);
|
|
641
|
+
if (isSameOrigin(dest, prev) && isSamePath(dest, prev)) {
|
|
642
|
+
event.preventDefault();
|
|
643
|
+
if (!dest.hash && !dest.href.endsWith("#")) {
|
|
644
|
+
if (dest.href !== prev.href) history.pushState(null, "", dest);
|
|
645
|
+
window._qRouterScrollEnabled = false;
|
|
646
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
647
|
+
saveScrollHistory({
|
|
648
|
+
...currentScrollState(scroller),
|
|
649
|
+
x: 0,
|
|
650
|
+
y: 0
|
|
651
|
+
});
|
|
652
|
+
location.reload();
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
goto(target.getAttribute("href"));
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
document.removeEventListener("click", window._qRouterInitAnchors);
|
|
660
|
+
window._qRouterInitAnchors = void 0;
|
|
661
|
+
if (!window.navigation) {
|
|
662
|
+
document.addEventListener("visibilitychange", () => {
|
|
663
|
+
if (window._qRouterScrollEnabled && document.visibilityState === "hidden") saveScrollHistory(currentScrollState(scroller));
|
|
664
|
+
}, { passive: true });
|
|
665
|
+
document.removeEventListener("visibilitychange", window._qRouterInitVisibility);
|
|
666
|
+
window._qRouterInitVisibility = void 0;
|
|
667
|
+
}
|
|
668
|
+
window.addEventListener("scroll", () => {
|
|
669
|
+
if (!window._qRouterScrollEnabled) return;
|
|
670
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
671
|
+
window._qRouterScrollDebounce = setTimeout(() => {
|
|
672
|
+
saveScrollHistory(currentScrollState(scroller));
|
|
673
|
+
window._qRouterScrollDebounce = void 0;
|
|
674
|
+
}, 200);
|
|
675
|
+
}, { passive: true });
|
|
676
|
+
removeEventListener("scroll", window._qRouterInitScroll);
|
|
677
|
+
window._qRouterInitScroll = void 0;
|
|
678
|
+
spa_init_default.resolve();
|
|
679
|
+
}
|
|
1428
680
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
681
|
+
/**
|
|
682
|
+
* @public
|
|
683
|
+
* This hook initializes Qwik Router, providing the necessary context for it to work.
|
|
684
|
+
*
|
|
685
|
+
* This hook should be used once, at the root of your application.
|
|
686
|
+
*/ var useQwikRouter = (props) => {
|
|
687
|
+
if (!isServer) throw new Error("useQwikRouter can only run during SSR on the server. If you are seeing this, it means you are re-rendering the root of your application. Fix that or use the <QwikRouterProvider> component around the root of your application.");
|
|
688
|
+
const env = useQwikRouterEnv();
|
|
689
|
+
if (!env?.params) throw new Error(`Missing Qwik Router Env Data for help visit https://github.com/QwikDev/qwik/issues/6237`);
|
|
690
|
+
const urlEnv = useServerData("url");
|
|
691
|
+
if (!urlEnv) throw new Error(`Missing Qwik URL Env Data`);
|
|
692
|
+
const serverHead = useServerData("documentHead");
|
|
693
|
+
const manifestHash = useServerData("containerAttributes")?.["q:manifest-hash"];
|
|
694
|
+
const url = new URL(urlEnv);
|
|
695
|
+
const routeLocationTarget = {
|
|
696
|
+
url,
|
|
697
|
+
params: env.params,
|
|
698
|
+
isNavigating: false,
|
|
699
|
+
prevUrl: void 0
|
|
700
|
+
};
|
|
701
|
+
const routeLocation = useStore(routeLocationTarget, { deep: false });
|
|
702
|
+
const navResolver = {};
|
|
703
|
+
const routeLoaderCtx = useStore(env.routeLoaderCtx);
|
|
704
|
+
routeLoaderCtx.manifestHash = manifestHash;
|
|
705
|
+
const loaderState = {};
|
|
706
|
+
const contentModulesForInit = env.loadedRoute.$mods$;
|
|
707
|
+
const loaders = ensureRouteLoaderSignals(contentModulesForInit, loaderState, routeLoaderCtx);
|
|
708
|
+
for (const loader of loaders) if (loader.__id in env.loaderValues) {
|
|
709
|
+
const value = env.loaderValues[loader.__id];
|
|
710
|
+
setLoaderSignalValue(loaderState[loader.__id], value);
|
|
711
|
+
}
|
|
712
|
+
const routeInternal = useSignal({
|
|
713
|
+
type: "initial",
|
|
714
|
+
dest: url
|
|
715
|
+
});
|
|
716
|
+
const documentHead = useStore(() => createDocumentHead(serverHead, manifestHash));
|
|
717
|
+
const content = useStore({
|
|
718
|
+
headings: void 0,
|
|
719
|
+
menu: void 0
|
|
720
|
+
});
|
|
721
|
+
const contentInternal = useSignal();
|
|
722
|
+
/**
|
|
723
|
+
* Non-serializable navigation context passed from the nav task to the head+commit task. Only the
|
|
724
|
+
* data that can't be derived from existing stores/signals.
|
|
725
|
+
*/ const navContext = useSignal();
|
|
726
|
+
const httpStatus = useSignal({
|
|
727
|
+
status: env.response.status,
|
|
728
|
+
message: env.loadedRoute.$notFound$ ? "Not Found" : env.response.statusMessage ?? ""
|
|
729
|
+
});
|
|
730
|
+
const currentActionId = env.response.action;
|
|
731
|
+
const currentAction = currentActionId ? env.response.actionResult : void 0;
|
|
732
|
+
const actionState = useSignal(currentAction ? {
|
|
733
|
+
id: currentActionId,
|
|
734
|
+
data: env.response.formData,
|
|
735
|
+
output: {
|
|
736
|
+
result: currentAction,
|
|
737
|
+
status: env.response.status
|
|
738
|
+
}
|
|
739
|
+
} : void 0);
|
|
740
|
+
const actionDataSignal = useSignal(currentActionId ? {
|
|
741
|
+
action: currentActionId,
|
|
742
|
+
actionResult: currentAction,
|
|
743
|
+
status: env.response.status
|
|
744
|
+
} : void 0);
|
|
745
|
+
const registerPreventNav = /*#__PURE__*/ inlinedQrl((fn$) => {
|
|
746
|
+
if (!isBrowser) return;
|
|
747
|
+
preventNav.$handler$ ||= (event) => {
|
|
748
|
+
internalState.navCount++;
|
|
749
|
+
if (!preventNav.$cbs$) return;
|
|
750
|
+
if ([...preventNav.$cbs$.values()].map((cb) => cb.resolved ? cb.resolved() : cb()).some(Boolean)) {
|
|
751
|
+
event.preventDefault();
|
|
752
|
+
event.returnValue = true;
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
(preventNav.$cbs$ ||= /* @__PURE__ */ new Set()).add(fn$);
|
|
756
|
+
fn$.resolve();
|
|
757
|
+
window.addEventListener("beforeunload", preventNav.$handler$);
|
|
758
|
+
return () => {
|
|
759
|
+
if (preventNav.$cbs$) {
|
|
760
|
+
preventNav.$cbs$.delete(fn$);
|
|
761
|
+
if (!preventNav.$cbs$.size) {
|
|
762
|
+
preventNav.$cbs$ = void 0;
|
|
763
|
+
window.removeEventListener("beforeunload", preventNav.$handler$);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
}, "useQwikRouter_registerPreventNav_69B0DK0eZJc");
|
|
768
|
+
/**
|
|
769
|
+
* This is the `nav()` function that `useNavigation()` returns. It is also used internally for SPA
|
|
770
|
+
* navigations and is provided in context for use in loaders and actions.
|
|
771
|
+
*
|
|
772
|
+
* Note: when goto is called, the address bar change must happen in the same tick for Safari to
|
|
773
|
+
* treat it as a user-initiated navigation and allow scroll restoration to work. For this reason,
|
|
774
|
+
* make sure to change the address bar before awaiting anything.
|
|
775
|
+
*/ const goto = /*#__PURE__*/ inlinedQrl(async (path, opt) => {
|
|
776
|
+
const actionState = _captures[0], manifestHash = _captures[1], navResolver = _captures[2], routeInternal = _captures[3], routeLocation = _captures[4];
|
|
777
|
+
const { type = "link", forceReload = path === void 0, replaceState = false, scroll = true } = typeof opt === "object" ? opt : { forceReload: opt };
|
|
778
|
+
if (isBrowser && type === "link" && routeInternal.value.type === "initial") {
|
|
779
|
+
const url = new URL(window.location.href);
|
|
780
|
+
routeInternal.value.dest = url;
|
|
781
|
+
routeLocation.url = url;
|
|
782
|
+
}
|
|
783
|
+
const lastDest = routeInternal.value.dest;
|
|
784
|
+
const dest = path === void 0 ? lastDest : typeof path === "number" ? path : toUrl(path, routeLocation.url);
|
|
785
|
+
if (navResolver.p && !forceReload && typeof dest !== "number" && isSamePath(dest, lastDest) && dest.href === lastDest.href) return navResolver.p;
|
|
786
|
+
const navCount = ++internalState.navCount;
|
|
787
|
+
internalState.currentTransition?.skipTransition();
|
|
788
|
+
if (preventNav.$cbs$ && (forceReload || typeof dest === "number" || !isSamePath(dest, lastDest) || !isSameOrigin(dest, lastDest))) {
|
|
789
|
+
const prevents = await Promise.all([...preventNav.$cbs$.values()].map((cb) => cb(dest)));
|
|
790
|
+
if (navCount !== internalState.navCount || prevents.some(Boolean)) {
|
|
791
|
+
if (navCount === internalState.navCount && type === "popstate") history.pushState(null, "", lastDest);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
if (typeof dest === "number") {
|
|
796
|
+
if (isBrowser) history.go(dest);
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (!isSameOrigin(dest, lastDest)) {
|
|
800
|
+
if (isBrowser) location.href = dest.href;
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
if (!forceReload && isSamePath(dest, lastDest)) {
|
|
804
|
+
if (isBrowser) {
|
|
805
|
+
if (type === "link" && dest.href !== location.href) history.pushState(null, "", dest);
|
|
806
|
+
const scroller = getScroller();
|
|
807
|
+
restoreScroll(type, dest, new URL(location.href), scroller, getScrollHistory());
|
|
808
|
+
if (type === "popstate") window._qRouterScrollEnabled = true;
|
|
809
|
+
}
|
|
810
|
+
if (dest.href !== routeLocation.url.href) {
|
|
811
|
+
const newUrl = new URL(dest.href);
|
|
812
|
+
routeInternal.value.dest = newUrl;
|
|
813
|
+
routeLocation.url = newUrl;
|
|
814
|
+
}
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
let historyUpdated = false;
|
|
818
|
+
if (isBrowser && type === "link" && !forceReload) {
|
|
819
|
+
const scroller = getScroller();
|
|
820
|
+
window._qRouterScrollEnabled = false;
|
|
821
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
822
|
+
saveScrollHistory(currentScrollState(scroller));
|
|
823
|
+
clientNavigate(window, type, new URL(location.href), dest, replaceState);
|
|
824
|
+
historyUpdated = true;
|
|
825
|
+
}
|
|
826
|
+
routeLocation.isNavigating = true;
|
|
827
|
+
const container = isBrowser ? _getContextContainer() : void 0;
|
|
828
|
+
if (container) {
|
|
829
|
+
await _waitUntilRendered(container);
|
|
830
|
+
if (navCount !== internalState.navCount) return;
|
|
831
|
+
}
|
|
832
|
+
actionState.value = void 0;
|
|
833
|
+
routeInternal.value = {
|
|
834
|
+
type,
|
|
835
|
+
dest,
|
|
836
|
+
forceReload,
|
|
837
|
+
replaceState,
|
|
838
|
+
scroll,
|
|
839
|
+
historyUpdated
|
|
840
|
+
};
|
|
841
|
+
if (isBrowser) prefetchRoute(dest, true, .8, manifestHash);
|
|
842
|
+
navResolver.p = new Promise((resolve) => {
|
|
843
|
+
navResolver.r = () => {
|
|
844
|
+
navResolver.r = void 0;
|
|
845
|
+
navResolver.p = void 0;
|
|
846
|
+
resolve();
|
|
847
|
+
};
|
|
848
|
+
});
|
|
849
|
+
return navResolver.p;
|
|
850
|
+
}, "useQwikRouter_goto_8j8Vrz2yUIM", [
|
|
851
|
+
actionState,
|
|
852
|
+
manifestHash,
|
|
853
|
+
navResolver,
|
|
854
|
+
routeInternal,
|
|
855
|
+
routeLocation
|
|
856
|
+
]);
|
|
857
|
+
useContextProvider(ContentContext, content);
|
|
858
|
+
useContextProvider(ContentInternalContext, contentInternal);
|
|
859
|
+
useContextProvider(DocumentHeadContext, documentHead);
|
|
860
|
+
useContextProvider(HttpStatusContext, httpStatus);
|
|
861
|
+
useContextProvider(RouteLocationContext, routeLocation);
|
|
862
|
+
useContextProvider(RouteNavigateContext, goto);
|
|
863
|
+
useContextProvider(RouteStateContext, loaderState);
|
|
864
|
+
useContextProvider(RouteLoaderCtxContext, routeLoaderCtx);
|
|
865
|
+
useContextProvider(RouteActionContext, actionState);
|
|
866
|
+
useContextProvider(RoutePreventNavigateContext, registerPreventNav);
|
|
867
|
+
/**
|
|
868
|
+
* This is split in 3 tasks because we need to update the head once we figured out the route, and
|
|
869
|
+
* before we trigger the render, and we need to subscribe only head to loader signal updates
|
|
870
|
+
*/ useTaskQrl(/*#__PURE__*/ inlinedQrl(async ({ track }) => {
|
|
871
|
+
const actionDataSignal = _captures[0], actionState = _captures[1], content = _captures[2], contentInternal = _captures[3], env = _captures[4], goto = _captures[5], httpStatus = _captures[6], loaderState = _captures[7], navContext = _captures[8], routeInternal = _captures[9], routeLoaderCtx = _captures[10], routeLocation = _captures[11], routeLocationTarget = _captures[12];
|
|
872
|
+
const navigation = track(routeInternal);
|
|
873
|
+
const action = track(actionState);
|
|
874
|
+
const prevUrl = routeLocation.url;
|
|
875
|
+
const navType = action ? "form" : navigation.type;
|
|
876
|
+
const replaceState = navigation.replaceState;
|
|
877
|
+
const navCountBefore = internalState.navCount;
|
|
878
|
+
let trackUrl;
|
|
879
|
+
let endpointResponse;
|
|
880
|
+
let actionData;
|
|
881
|
+
let actionLoaderHashes;
|
|
882
|
+
let shouldInvalidateActionLoaders = false;
|
|
883
|
+
let loadedRoute;
|
|
884
|
+
if (isServer) {
|
|
885
|
+
trackUrl = new URL(navigation.dest, routeLocation.url);
|
|
886
|
+
loadedRoute = env.loadedRoute;
|
|
887
|
+
endpointResponse = env.response;
|
|
888
|
+
actionData = endpointResponse;
|
|
889
|
+
} else {
|
|
890
|
+
trackUrl = new URL(navigation.dest, location);
|
|
891
|
+
if (trackUrl.pathname.endsWith("/")) {
|
|
892
|
+
if (globalThis.__NO_TRAILING_SLASH__) trackUrl.pathname = trackUrl.pathname.slice(0, -1);
|
|
893
|
+
} else if (!globalThis.__NO_TRAILING_SLASH__) trackUrl.pathname = ensureSlash(trackUrl.pathname);
|
|
894
|
+
const loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.cacheModules, trackUrl.pathname);
|
|
895
|
+
try {
|
|
896
|
+
loadedRoute = await loadRoutePromise;
|
|
897
|
+
} catch (e) {
|
|
898
|
+
console.error(`Could not load route ${trackUrl.pathname}, reloading:`, e);
|
|
899
|
+
window.location.href = trackUrl.href;
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
if (internalState.navCount !== navCountBefore) return;
|
|
903
|
+
if (action) {
|
|
904
|
+
const result = await submitAction(action, trackUrl);
|
|
905
|
+
if (!result) {
|
|
906
|
+
routeInternal.untrackedValue = {
|
|
907
|
+
type: navType,
|
|
908
|
+
dest: trackUrl
|
|
909
|
+
};
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
if (action.resolve) {
|
|
913
|
+
action.resolve({
|
|
914
|
+
status: result.status,
|
|
915
|
+
result: result.result
|
|
916
|
+
});
|
|
917
|
+
action.resolve = void 0;
|
|
918
|
+
}
|
|
919
|
+
if (result.redirect) {
|
|
920
|
+
goto(result.redirect, { replaceState: true });
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
actionData = {
|
|
924
|
+
status: result.status,
|
|
925
|
+
action: action.id,
|
|
926
|
+
actionResult: result.result
|
|
927
|
+
};
|
|
928
|
+
actionLoaderHashes = result.loaderHashes;
|
|
929
|
+
shouldInvalidateActionLoaders = true;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
const { $routeName$, $params$, $mods$, $menu$, $notFound$ } = loadedRoute;
|
|
933
|
+
const contentModules = $mods$;
|
|
934
|
+
if (!isServer) routeLoaderCtx.goto = noSerialize(goto);
|
|
935
|
+
updateRouteLoaderPaths(routeLoaderCtx, loadedRoute.$loaderPaths$, trackUrl);
|
|
936
|
+
const routeLoaders = ensureRouteLoaderSignals(contentModules, loaderState, routeLoaderCtx);
|
|
937
|
+
if (!isServer) invalidateNavRouteLoaders(loaderState);
|
|
938
|
+
if (shouldInvalidateActionLoaders) {
|
|
939
|
+
if (actionLoaderHashes !== void 0) for (const hash of actionLoaderHashes) loaderState[hash]?.invalidate(true);
|
|
940
|
+
else for (const loader of routeLoaders) loaderState[loader.__id].invalidate(true);
|
|
941
|
+
}
|
|
942
|
+
if (routeLoaders.length > 0) for (let i = 0; i < routeLoaders.length; i++) {
|
|
943
|
+
const loader = routeLoaders[i];
|
|
944
|
+
if (!isImmutableLoader(loader.__id)) loaderState[loader.__id].untrackedPending;
|
|
945
|
+
}
|
|
946
|
+
if (!isServer) clearNavFetchCache();
|
|
947
|
+
if (internalState.navCount !== navCountBefore) return;
|
|
948
|
+
if ($notFound$) httpStatus.value = {
|
|
949
|
+
status: 404,
|
|
950
|
+
message: "Not Found"
|
|
951
|
+
};
|
|
952
|
+
else if (endpointResponse) httpStatus.value = {
|
|
953
|
+
status: endpointResponse.status,
|
|
954
|
+
message: endpointResponse.statusMessage ?? "OK"
|
|
955
|
+
};
|
|
956
|
+
else if (actionData) httpStatus.value = {
|
|
957
|
+
status: actionData.status,
|
|
958
|
+
message: "OK"
|
|
959
|
+
};
|
|
960
|
+
else httpStatus.value = {
|
|
961
|
+
status: 200,
|
|
962
|
+
message: "OK"
|
|
963
|
+
};
|
|
964
|
+
const pageModule = contentModules[contentModules.length - 1];
|
|
965
|
+
if (navigation.dest.search && !!isSamePath(trackUrl, prevUrl)) trackUrl.search = navigation.dest.search;
|
|
966
|
+
let shouldForcePrevUrl = false;
|
|
967
|
+
let shouldForceUrl = false;
|
|
968
|
+
let shouldForceParams = false;
|
|
969
|
+
if (!isSamePath(trackUrl, prevUrl)) {
|
|
970
|
+
if (_hasStoreEffects(routeLocation, "prevUrl")) shouldForcePrevUrl = true;
|
|
971
|
+
routeLocationTarget.prevUrl = prevUrl;
|
|
972
|
+
}
|
|
973
|
+
if (routeLocationTarget.url !== trackUrl) {
|
|
974
|
+
if (_hasStoreEffects(routeLocation, "url")) shouldForceUrl = true;
|
|
975
|
+
routeLocationTarget.url = trackUrl;
|
|
976
|
+
}
|
|
977
|
+
if (routeLocationTarget.params !== $params$) {
|
|
978
|
+
if (_hasStoreEffects(routeLocation, "params")) shouldForceParams = true;
|
|
979
|
+
routeLocationTarget.params = $params$;
|
|
980
|
+
}
|
|
981
|
+
const nextRouteInternal = {
|
|
982
|
+
type: navType,
|
|
983
|
+
dest: trackUrl
|
|
984
|
+
};
|
|
985
|
+
if (navigation.forceReload !== void 0) nextRouteInternal.forceReload = navigation.forceReload;
|
|
986
|
+
if (navigation.replaceState !== void 0) nextRouteInternal.replaceState = navigation.replaceState;
|
|
987
|
+
if (navigation.scroll !== void 0) nextRouteInternal.scroll = navigation.scroll;
|
|
988
|
+
if (navigation.historyUpdated !== void 0) nextRouteInternal.historyUpdated = navigation.historyUpdated;
|
|
989
|
+
routeInternal.untrackedValue = nextRouteInternal;
|
|
990
|
+
content.headings = pageModule.headings;
|
|
991
|
+
content.menu = $menu$;
|
|
992
|
+
contentInternal.untrackedValue = noSerialize(contentModules);
|
|
993
|
+
actionDataSignal.value = actionData;
|
|
994
|
+
navContext.value = noSerialize({
|
|
995
|
+
routeName: $routeName$,
|
|
996
|
+
navType,
|
|
997
|
+
prevUrl,
|
|
998
|
+
replaceState,
|
|
999
|
+
shouldForcePrevUrl,
|
|
1000
|
+
shouldForceUrl,
|
|
1001
|
+
shouldForceParams,
|
|
1002
|
+
navCount: navCountBefore
|
|
1003
|
+
});
|
|
1004
|
+
}, "useQwikRouter_useTask_XpalYii770E", [
|
|
1005
|
+
actionDataSignal,
|
|
1006
|
+
actionState,
|
|
1007
|
+
content,
|
|
1008
|
+
contentInternal,
|
|
1009
|
+
env,
|
|
1010
|
+
goto,
|
|
1011
|
+
httpStatus,
|
|
1012
|
+
loaderState,
|
|
1013
|
+
navContext,
|
|
1014
|
+
routeInternal,
|
|
1015
|
+
routeLoaderCtx,
|
|
1016
|
+
routeLocation,
|
|
1017
|
+
routeLocationTarget
|
|
1018
|
+
]), { deferUpdates: isServer });
|
|
1019
|
+
/**
|
|
1020
|
+
* Calc head. This is in a separate task so that loader updates can trigger head recalculation
|
|
1021
|
+
* without re-running the navigation logic.
|
|
1022
|
+
*
|
|
1023
|
+
* Note that on the server these tasks run sequentially.
|
|
1024
|
+
*/ useTaskQrl(/*#__PURE__*/ inlinedQrl(({ track }) => {
|
|
1025
|
+
const actionDataSignal = _captures[0], contentInternal = _captures[1], documentHead = _captures[2], loaderState = _captures[3], routeLocation = _captures[4], serverHead = _captures[5];
|
|
1026
|
+
const contentModules = track(contentInternal);
|
|
1027
|
+
if (!contentModules) return;
|
|
1028
|
+
const actionData = track(actionDataSignal);
|
|
1029
|
+
let head;
|
|
1030
|
+
try {
|
|
1031
|
+
head = track(() => resolveHead(actionData, loaderState, routeLocation, contentModules, getLocale(""), serverHead));
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
if (isServer || isPromise(error)) throw error;
|
|
1034
|
+
console.error(error);
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
documentHead.links = head.links;
|
|
1038
|
+
documentHead.meta = head.meta;
|
|
1039
|
+
documentHead.styles = head.styles;
|
|
1040
|
+
documentHead.scripts = head.scripts;
|
|
1041
|
+
documentHead.title = head.title;
|
|
1042
|
+
documentHead.frontmatter = head.frontmatter;
|
|
1043
|
+
}, "useQwikRouter_useTask_1_1sKEZ9Pg1ow", [
|
|
1044
|
+
actionDataSignal,
|
|
1045
|
+
contentInternal,
|
|
1046
|
+
documentHead,
|
|
1047
|
+
loaderState,
|
|
1048
|
+
routeLocation,
|
|
1049
|
+
serverHead
|
|
1050
|
+
]), { deferUpdates: isServer });
|
|
1051
|
+
/** Actual navigation */ useTaskQrl(/*#__PURE__*/ inlinedQrl(({ track }) => {
|
|
1052
|
+
const contentInternal = _captures[0], goto = _captures[1], manifestHash = _captures[2], navContext = _captures[3], navResolver = _captures[4], props = _captures[5], routeInternal = _captures[6], routeLocation = _captures[7];
|
|
1053
|
+
const nav = track(navContext);
|
|
1054
|
+
if (isServer || !nav) return;
|
|
1055
|
+
if (nav.navCount !== internalState.navCount) return;
|
|
1056
|
+
const container = _getContextContainer();
|
|
1057
|
+
const navigation = routeInternal.untrackedValue;
|
|
1058
|
+
const { navType, prevUrl, replaceState, routeName } = nav;
|
|
1059
|
+
const trackUrl = routeLocation.url;
|
|
1060
|
+
const scroller = getScroller();
|
|
1061
|
+
let scrollState;
|
|
1062
|
+
if (navType === "popstate") scrollState = getScrollHistory();
|
|
1063
|
+
if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || navType === "form" && !isSamePath(trackUrl, prevUrl)) document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
|
|
1064
|
+
initializeSPA(goto, scroller);
|
|
1065
|
+
if (navType !== "popstate") {
|
|
1066
|
+
window._qRouterScrollEnabled = false;
|
|
1067
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
1068
|
+
if (!navigation.historyUpdated) saveScrollHistory(currentScrollState(scroller));
|
|
1069
|
+
}
|
|
1070
|
+
let didNavigate = false;
|
|
1071
|
+
let navigatePromise;
|
|
1072
|
+
let currentTransition;
|
|
1073
|
+
const navigate = () => {
|
|
1074
|
+
if (navigatePromise) return navigatePromise;
|
|
1075
|
+
if (nav.navCount !== internalState.navCount) return Promise.resolve();
|
|
1076
|
+
didNavigate = true;
|
|
1077
|
+
if (navigation.historyUpdated) {
|
|
1078
|
+
const currentPath = location.pathname + location.search + location.hash;
|
|
1079
|
+
const nextPath = toPath(trackUrl);
|
|
1080
|
+
if (currentPath !== nextPath) history.replaceState(history.state, "", nextPath);
|
|
1081
|
+
} else clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
|
|
1082
|
+
contentInternal.trigger();
|
|
1083
|
+
return navigatePromise = _waitUntilRendered(container);
|
|
1084
|
+
};
|
|
1085
|
+
const _waitNextPage = () => {
|
|
1086
|
+
if (!shouldStartViewTransition(props?.viewTransition)) return navigate().then(() => void 0);
|
|
1087
|
+
const { ready, transition } = startViewTransition({
|
|
1088
|
+
update: navigate,
|
|
1089
|
+
types: ["qwik-navigation"]
|
|
1090
|
+
});
|
|
1091
|
+
currentTransition = transition;
|
|
1092
|
+
internalState.currentTransition = transition;
|
|
1093
|
+
return ready.then(() => transition, (reason) => {
|
|
1094
|
+
if (!didNavigate && nav.navCount === internalState.navCount) return navigate().then(() => transition);
|
|
1095
|
+
if (reason?.name === "AbortError") return transition;
|
|
1096
|
+
throw reason;
|
|
1097
|
+
});
|
|
1098
|
+
};
|
|
1099
|
+
_waitNextPage().finally(() => {
|
|
1100
|
+
if (currentTransition && internalState.currentTransition === currentTransition) internalState.currentTransition = void 0;
|
|
1101
|
+
if (nav.navCount !== internalState.navCount) return;
|
|
1102
|
+
container.element.setAttribute?.(Q_ROUTE, routeName);
|
|
1103
|
+
saveScrollHistory(currentScrollState(scroller));
|
|
1104
|
+
window._qRouterScrollEnabled = true;
|
|
1105
|
+
callRestoreScrollOnDocument();
|
|
1106
|
+
refreshLinkPrefetchObserver(manifestHash);
|
|
1107
|
+
if (nav.shouldForcePrevUrl) forceStoreEffects(routeLocation, "prevUrl");
|
|
1108
|
+
if (nav.shouldForceUrl) forceStoreEffects(routeLocation, "url");
|
|
1109
|
+
if (nav.shouldForceParams) forceStoreEffects(routeLocation, "params");
|
|
1110
|
+
routeLocation.isNavigating = false;
|
|
1111
|
+
navResolver.r?.();
|
|
1112
|
+
});
|
|
1113
|
+
}, "useQwikRouter_useTask_2_yw17chooOac", [
|
|
1114
|
+
contentInternal,
|
|
1115
|
+
goto,
|
|
1116
|
+
manifestHash,
|
|
1117
|
+
navContext,
|
|
1118
|
+
navResolver,
|
|
1119
|
+
props,
|
|
1120
|
+
routeInternal,
|
|
1121
|
+
routeLocation
|
|
1122
|
+
]), { deferUpdates: false });
|
|
1123
|
+
};
|
|
1124
|
+
/** @public This is a wrapper around the `useQwikRouter()` hook. We recommend using the hook instead of this component, unless you have a good reason to make your root component reactive. */ var QwikRouterProvider = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
1125
|
+
useQwikRouter(props);
|
|
1126
|
+
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "5y_0");
|
|
1127
|
+
}, "QwikRouterProvider_component_6Kjfa79mqlY"));
|
|
1128
|
+
/**
|
|
1129
|
+
* @deprecated Use `useQwikRouter()` instead. Will be removed in v3.
|
|
1130
|
+
* @public
|
|
1131
|
+
*/ var QwikCityProvider = QwikRouterProvider;
|
|
1132
|
+
var handleRouterPopstate = (nav, event) => {
|
|
1133
|
+
const href = event.detail?.href;
|
|
1134
|
+
if (href) return nav(href, { type: "popstate" });
|
|
1521
1135
|
};
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1136
|
+
/** @public */ var RouterOutlet = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
1137
|
+
if (!useServerData("containerAttributes")) throw new Error("PrefetchServiceWorker component must be rendered on the server.");
|
|
1138
|
+
const internalContext = useContext(ContentInternalContext);
|
|
1139
|
+
const nav = useNavigate();
|
|
1140
|
+
const contents = internalContext.value;
|
|
1141
|
+
if (contents && contents.length > 0) {
|
|
1142
|
+
const contentsLen = contents.length;
|
|
1143
|
+
let cmp = null;
|
|
1144
|
+
for (let i = contentsLen - 1; i >= 0; i--) if (contents[i].default) cmp = _jsxSorted(contents[i].default, null, null, cmp, 1, "Fn_0");
|
|
1145
|
+
return /*#__PURE__*/ _jsxSorted(Fragment, null, null, [cmp, !__EXPERIMENTAL__.noSPA && /*#__PURE__*/ _jsxSorted("script", {
|
|
1146
|
+
"q-d:qinit": _qrlSync(() => {
|
|
1147
|
+
((w, h) => {
|
|
1148
|
+
if (!w._qcs) {
|
|
1149
|
+
w._qcs = !0;
|
|
1150
|
+
const s = h.state?._qRouterScroll;
|
|
1151
|
+
if (s) {
|
|
1152
|
+
h.scrollRestoration = "manual";
|
|
1153
|
+
w.scrollTo(s.x, s.y);
|
|
1154
|
+
}
|
|
1155
|
+
document.dispatchEvent(new Event("qcinit"));
|
|
1156
|
+
}
|
|
1157
|
+
})(window, history);
|
|
1158
|
+
}, "()=>{((w,h)=>{if(!w._qcs){w._qcs=!0;const s=h.state?._qRouterScroll;if(s){h.scrollRestoration=\"manual\";w.scrollTo(s.x,s.y);}document.dispatchEvent(new Event(\"qcinit\"));}})(window,history);}"),
|
|
1159
|
+
"q-d:qrouterpopstate": /*#__PURE__*/ inlinedQrl((event, _1, nav) => handleRouterPopstate(nav, event), "RouterOutlet_component_Fragment_script_q_d_qrouterpopstate_aRL6GvFyews").m(),
|
|
1160
|
+
"q:p": nav
|
|
1161
|
+
}, { "q-d:qcinit": [spa_init_default, linkPrefetchInit] }, null, 6, "Fn_1")], 1, "Fn_2");
|
|
1162
|
+
}
|
|
1163
|
+
return SkipRender;
|
|
1164
|
+
}, "RouterOutlet_component_QwONcWD5gIg"));
|
|
1165
|
+
/** @internal */ var validatorQrl = (validator) => {
|
|
1166
|
+
if (isServer) return { validate: validator };
|
|
1531
1167
|
};
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
}
|
|
1547
|
-
untrack(() => state[id].value);
|
|
1548
|
-
return state[id];
|
|
1549
|
-
}
|
|
1550
|
-
loader.__brand = "server_loader";
|
|
1551
|
-
loader.__qrl = loaderQrl;
|
|
1552
|
-
loader.__validators = validators;
|
|
1553
|
-
loader.__id = id;
|
|
1554
|
-
loader.__serializationStrategy = serializationStrategy;
|
|
1555
|
-
Object.freeze(loader);
|
|
1556
|
-
return loader;
|
|
1168
|
+
/** @public */ var validator$ = /*#__PURE__*/ implicit$FirstArg(validatorQrl);
|
|
1169
|
+
var flattenValibotIssues = (issues) => {
|
|
1170
|
+
return issues.reduce((acc, issue) => {
|
|
1171
|
+
if (issue.path) {
|
|
1172
|
+
if (issue.path.some((path) => path.type === "array")) {
|
|
1173
|
+
const keySuffix = issue.expected === "Array" ? "[]" : "";
|
|
1174
|
+
const key = issue.path.map((item) => item.type === "array" ? "*" : item.key).join(".").replace(/\.\*/g, "[]") + keySuffix;
|
|
1175
|
+
acc[key] = acc[key] || [];
|
|
1176
|
+
if (Array.isArray(acc[key])) acc[key].push(issue.message);
|
|
1177
|
+
return acc;
|
|
1178
|
+
} else acc[issue.path.map((item) => item.key).join(".")] = issue.message;
|
|
1179
|
+
}
|
|
1180
|
+
return acc;
|
|
1181
|
+
}, {});
|
|
1557
1182
|
};
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1183
|
+
/** @internal */ var valibotQrl = (qrl) => {
|
|
1184
|
+
if (!__EXPERIMENTAL__.valibot) throw new Error("Valibot is an experimental feature and is not enabled. Please enable the feature flag by adding `experimental: [\"valibot\"]` to your qwikVite plugin options.");
|
|
1185
|
+
if (isServer) return {
|
|
1186
|
+
__brand: "valibot",
|
|
1187
|
+
async validate(ev, inputData) {
|
|
1188
|
+
const schema = await qrl.resolve().then((obj) => typeof obj === "function" ? obj(ev) : obj);
|
|
1189
|
+
const data = inputData ?? await ev.parseBody();
|
|
1190
|
+
const result = await v.safeParseAsync(schema, data);
|
|
1191
|
+
if (result.success) return {
|
|
1192
|
+
success: true,
|
|
1193
|
+
data: result.output
|
|
1194
|
+
};
|
|
1195
|
+
else {
|
|
1196
|
+
if (isDev) console.error("ERROR: Valibot validation failed", result.issues);
|
|
1197
|
+
return {
|
|
1198
|
+
success: false,
|
|
1199
|
+
status: 400,
|
|
1200
|
+
error: {
|
|
1201
|
+
formErrors: v.flatten(result.issues).root ?? [],
|
|
1202
|
+
fieldErrors: flattenValibotIssues(result.issues)
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1566
1208
|
};
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
acc[issue.path.map((item) => item.key).join(".")] = issue.message;
|
|
1582
|
-
}
|
|
1583
|
-
}
|
|
1584
|
-
return acc;
|
|
1585
|
-
}, {});
|
|
1209
|
+
/** @beta */ var valibot$ = /*#__PURE__*/ implicit$FirstArg(valibotQrl);
|
|
1210
|
+
var flattenZodIssues = (issues) => {
|
|
1211
|
+
issues = Array.isArray(issues) ? issues : [issues];
|
|
1212
|
+
return issues.reduce((acc, issue) => {
|
|
1213
|
+
const isExpectingArray = "expected" in issue && issue.expected === "array";
|
|
1214
|
+
if (issue.path.some((path) => typeof path === "number") || isExpectingArray) {
|
|
1215
|
+
const keySuffix = "expected" in issue && issue.expected === "array" ? "[]" : "";
|
|
1216
|
+
const key = issue.path.map((path) => typeof path === "number" ? "*" : path).join(".").replace(/\.\*/g, "[]") + keySuffix;
|
|
1217
|
+
acc[key] = acc[key] || [];
|
|
1218
|
+
if (Array.isArray(acc[key])) acc[key].push(issue.message);
|
|
1219
|
+
return acc;
|
|
1220
|
+
} else acc[issue.path.join(".")] = issue.message;
|
|
1221
|
+
return acc;
|
|
1222
|
+
}, {});
|
|
1586
1223
|
};
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
fieldErrors: flattenValibotIssues(result.issues)
|
|
1613
|
-
}
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
};
|
|
1618
|
-
}
|
|
1619
|
-
return void 0;
|
|
1224
|
+
/** @internal */ var zodQrl = (qrl) => {
|
|
1225
|
+
if (isServer) return {
|
|
1226
|
+
__brand: "zod",
|
|
1227
|
+
async validate(ev, inputData) {
|
|
1228
|
+
const schema = await qrl.resolve().then((obj) => {
|
|
1229
|
+
if (typeof obj === "function") obj = obj(z$1, ev);
|
|
1230
|
+
if (obj instanceof z$1.ZodType) return obj;
|
|
1231
|
+
else return z$1.object(obj);
|
|
1232
|
+
});
|
|
1233
|
+
const data = inputData ?? await ev.parseBody();
|
|
1234
|
+
const result = await withLocale(ev.locale(), () => schema.safeParseAsync(data));
|
|
1235
|
+
if (result.success) return result;
|
|
1236
|
+
else {
|
|
1237
|
+
if (isDev) console.error("ERROR: Zod validation failed", result.error.issues);
|
|
1238
|
+
return {
|
|
1239
|
+
success: false,
|
|
1240
|
+
status: 400,
|
|
1241
|
+
error: {
|
|
1242
|
+
formErrors: result.error.flatten().formErrors,
|
|
1243
|
+
fieldErrors: flattenZodIssues(result.error.issues)
|
|
1244
|
+
}
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1620
1249
|
};
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1250
|
+
/** @public */ var zod$ = /*#__PURE__*/ implicit$FirstArg(zodQrl);
|
|
1251
|
+
var getValidators = (rest, qrl) => {
|
|
1252
|
+
let id;
|
|
1253
|
+
let invalidate;
|
|
1254
|
+
const validators = [];
|
|
1255
|
+
if (rest.length === 1) {
|
|
1256
|
+
const options = rest[0];
|
|
1257
|
+
if (options && typeof options === "object") {
|
|
1258
|
+
if ("validate" in options) validators.push(options);
|
|
1259
|
+
else {
|
|
1260
|
+
id = options.id;
|
|
1261
|
+
if (options.validation) validators.push(...options.validation);
|
|
1262
|
+
if (options.invalidate) invalidate = options.invalidate.map((loader) => loader.__id);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
} else if (rest.length > 1) validators.push(...rest.filter((v) => !!v));
|
|
1266
|
+
if (typeof id === "string") {
|
|
1267
|
+
if (isDev) {
|
|
1268
|
+
if (!/^[\w/.-]+$/.test(id)) throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`);
|
|
1269
|
+
}
|
|
1270
|
+
id = `id_${id}`;
|
|
1271
|
+
} else id = qrl.getHash();
|
|
1272
|
+
return {
|
|
1273
|
+
validators: validators.reverse(),
|
|
1274
|
+
id,
|
|
1275
|
+
invalidate
|
|
1276
|
+
};
|
|
1642
1277
|
};
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1278
|
+
/** @public */ var routeActionQrl = (actionQrl, ...rest) => {
|
|
1279
|
+
const { id, validators, invalidate } = getValidators(rest, actionQrl);
|
|
1280
|
+
function action() {
|
|
1281
|
+
const loc = useLocation();
|
|
1282
|
+
const currentAction = useAction();
|
|
1283
|
+
const initialState = {
|
|
1284
|
+
actionPath: `?${QACTION_KEY}=${id}`,
|
|
1285
|
+
submitted: false,
|
|
1286
|
+
isRunning: false,
|
|
1287
|
+
status: void 0,
|
|
1288
|
+
value: void 0,
|
|
1289
|
+
formData: void 0
|
|
1290
|
+
};
|
|
1291
|
+
const state = useStore(() => {
|
|
1292
|
+
const value = currentAction.value;
|
|
1293
|
+
if (value && value?.id === id) {
|
|
1294
|
+
const data = value.data;
|
|
1295
|
+
if (data instanceof FormData) initialState.formData = data;
|
|
1296
|
+
if (value.output) {
|
|
1297
|
+
const { status, result } = value.output;
|
|
1298
|
+
initialState.status = status;
|
|
1299
|
+
initialState.value = result;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return initialState;
|
|
1303
|
+
});
|
|
1304
|
+
initialState.submit = /* @__PURE__ */ inlinedQrl((input = {}) => {
|
|
1305
|
+
const currentAction = _captures[0], id = _captures[1], loc = _captures[2], state = _captures[3];
|
|
1306
|
+
if (isServer) throw new Error(`Actions can not be invoked within the server during SSR.
|
|
1307
|
+
Action.run() can only be called on the browser, for example when a user clicks a button, or submits a form.`);
|
|
1308
|
+
let data;
|
|
1309
|
+
let form;
|
|
1310
|
+
if (input instanceof SubmitEvent) {
|
|
1311
|
+
form = input.target;
|
|
1312
|
+
data = new FormData(form);
|
|
1313
|
+
if ((input.submitter instanceof HTMLInputElement || input.submitter instanceof HTMLButtonElement) && input.submitter.name) {
|
|
1314
|
+
if (input.submitter.name) data.append(input.submitter.name, input.submitter.value);
|
|
1315
|
+
}
|
|
1316
|
+
} else data = input;
|
|
1317
|
+
return new Promise((resolve) => {
|
|
1318
|
+
if (data instanceof FormData) state.formData = data;
|
|
1319
|
+
state.submitted = true;
|
|
1320
|
+
state.isRunning = true;
|
|
1321
|
+
loc.isNavigating = true;
|
|
1322
|
+
currentAction.value = {
|
|
1323
|
+
data,
|
|
1324
|
+
id,
|
|
1325
|
+
resolve: noSerialize(resolve)
|
|
1326
|
+
};
|
|
1327
|
+
}).then((_rawProps) => {
|
|
1328
|
+
state.isRunning = false;
|
|
1329
|
+
state.status = _rawProps.status;
|
|
1330
|
+
state.value = _rawProps.result;
|
|
1331
|
+
if (form) {
|
|
1332
|
+
if (form.getAttribute("data-spa-reset") === "true") form.reset();
|
|
1333
|
+
const detail = {
|
|
1334
|
+
status: _rawProps.status,
|
|
1335
|
+
value: _rawProps.result
|
|
1336
|
+
};
|
|
1337
|
+
form.dispatchEvent(new CustomEvent("submitcompleted", {
|
|
1338
|
+
bubbles: false,
|
|
1339
|
+
cancelable: false,
|
|
1340
|
+
composed: false,
|
|
1341
|
+
detail
|
|
1342
|
+
}));
|
|
1343
|
+
}
|
|
1344
|
+
return {
|
|
1345
|
+
status: _rawProps.status,
|
|
1346
|
+
value: _rawProps.result
|
|
1347
|
+
};
|
|
1348
|
+
});
|
|
1349
|
+
}, "routeActionQrl_action_submit_YuS5bpdQ360", [
|
|
1350
|
+
currentAction,
|
|
1351
|
+
id,
|
|
1352
|
+
loc,
|
|
1353
|
+
state
|
|
1354
|
+
]);
|
|
1355
|
+
return state;
|
|
1356
|
+
}
|
|
1357
|
+
action.__brand = "server_action";
|
|
1358
|
+
action.__validators = validators;
|
|
1359
|
+
action.__qrl = actionQrl;
|
|
1360
|
+
action.__id = id;
|
|
1361
|
+
action.__invalidate = invalidate;
|
|
1362
|
+
Object.freeze(action);
|
|
1363
|
+
return action;
|
|
1679
1364
|
};
|
|
1680
|
-
|
|
1681
|
-
const
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
}
|
|
1688
|
-
const method = options?.method?.toUpperCase?.() || "POST";
|
|
1689
|
-
const headers = options?.headers || {};
|
|
1690
|
-
const origin = options?.origin || "";
|
|
1691
|
-
const fetchOptions = options?.fetchOptions || {};
|
|
1692
|
-
function rpc() {
|
|
1693
|
-
return $(async function(...args) {
|
|
1694
|
-
const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
|
|
1695
|
-
if (isServer) {
|
|
1696
|
-
let requestEvent = globalThis.qcAsyncRequestStore?.getStore();
|
|
1697
|
-
if (!requestEvent) {
|
|
1698
|
-
const contexts = [
|
|
1699
|
-
useQwikRouterEnv()?.ev,
|
|
1700
|
-
this,
|
|
1701
|
-
_getContextEvent()
|
|
1702
|
-
];
|
|
1703
|
-
requestEvent = contexts.find((v2) => v2 && Object.prototype.hasOwnProperty.call(v2, "sharedMap") && Object.prototype.hasOwnProperty.call(v2, "cookie"));
|
|
1704
|
-
}
|
|
1705
|
-
return qrl.apply(requestEvent, isDev ? deepFreeze(args) : args);
|
|
1706
|
-
} else {
|
|
1707
|
-
const ctxElm = _getContextElement();
|
|
1708
|
-
const filteredArgs = args.map((arg) => {
|
|
1709
|
-
if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) {
|
|
1710
|
-
return new FormData(arg.target);
|
|
1711
|
-
} else if (arg instanceof Event) {
|
|
1712
|
-
return null;
|
|
1713
|
-
} else if (arg instanceof Node) {
|
|
1714
|
-
return null;
|
|
1715
|
-
}
|
|
1716
|
-
return arg;
|
|
1717
|
-
});
|
|
1718
|
-
const qrlHash = qrl.getHash();
|
|
1719
|
-
let query = "";
|
|
1720
|
-
const config = {
|
|
1721
|
-
...fetchOptions,
|
|
1722
|
-
method,
|
|
1723
|
-
headers: {
|
|
1724
|
-
...headers,
|
|
1725
|
-
"Content-Type": "application/qwik-json",
|
|
1726
|
-
Accept: "application/json, application/qwik-json, text/qwik-json-stream, text/plain",
|
|
1727
|
-
// Required so we don't call accidentally
|
|
1728
|
-
"X-QRL": qrlHash
|
|
1729
|
-
},
|
|
1730
|
-
signal: abortSignal
|
|
1731
|
-
};
|
|
1732
|
-
const body = await _serialize([
|
|
1733
|
-
qrl,
|
|
1734
|
-
...filteredArgs
|
|
1735
|
-
]);
|
|
1736
|
-
if (method === "GET") {
|
|
1737
|
-
query += `&${QDATA_KEY}=${encodeURIComponent(body)}`;
|
|
1738
|
-
} else {
|
|
1739
|
-
config.body = body;
|
|
1740
|
-
}
|
|
1741
|
-
const res = await fetch(`${origin}?${QFN_KEY}=${qrlHash}${query}`, config);
|
|
1742
|
-
const contentType = res.headers.get("Content-Type");
|
|
1743
|
-
if (res.ok && contentType === "text/qwik-json-stream" && res.body) {
|
|
1744
|
-
return async function* () {
|
|
1745
|
-
try {
|
|
1746
|
-
for await (const result of deserializeStream(res.body, ctxElm ?? document.documentElement, abortSignal)) {
|
|
1747
|
-
yield result;
|
|
1748
|
-
}
|
|
1749
|
-
} finally {
|
|
1750
|
-
if (!abortSignal?.aborted) {
|
|
1751
|
-
await res.body.cancel();
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
}();
|
|
1755
|
-
} else if (contentType === "application/qwik-json") {
|
|
1756
|
-
const str = await res.text();
|
|
1757
|
-
const [obj] = _deserialize(str, ctxElm ?? document.documentElement);
|
|
1758
|
-
if (res.status >= 400) {
|
|
1759
|
-
throw obj;
|
|
1760
|
-
}
|
|
1761
|
-
return obj;
|
|
1762
|
-
} else if (contentType === "application/json") {
|
|
1763
|
-
const obj = await res.json();
|
|
1764
|
-
if (res.status >= 400) {
|
|
1765
|
-
throw obj;
|
|
1766
|
-
}
|
|
1767
|
-
return obj;
|
|
1768
|
-
} else if (contentType === "text/plain" || contentType === "text/html") {
|
|
1769
|
-
const str = await res.text();
|
|
1770
|
-
if (res.status >= 400) {
|
|
1771
|
-
throw str;
|
|
1772
|
-
}
|
|
1773
|
-
return str;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
});
|
|
1777
|
-
}
|
|
1778
|
-
return rpc();
|
|
1365
|
+
/** @internal */ var globalActionQrl = (actionQrl, ...rest) => {
|
|
1366
|
+
const action = routeActionQrl(actionQrl, ...rest);
|
|
1367
|
+
if (isServer) {
|
|
1368
|
+
if (typeof globalThis._qwikActionsMap === "undefined") globalThis._qwikActionsMap = /* @__PURE__ */ new Map();
|
|
1369
|
+
globalThis._qwikActionsMap.set(action.__id, action);
|
|
1370
|
+
}
|
|
1371
|
+
return action;
|
|
1779
1372
|
};
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
};
|
|
1373
|
+
/**
|
|
1374
|
+
* Define a route action that handles form submissions or programmatic invocations.
|
|
1375
|
+
*
|
|
1376
|
+
* Actions run on the server when submitted from the client. The result is returned as an
|
|
1377
|
+
* `ActionStore` with `.value` for success data and `.error` for errors (including validation errors
|
|
1378
|
+
* from `zod$`/`valibot$` where `.fieldErrors` etc. are accessible directly on `.error`).
|
|
1379
|
+
*
|
|
1380
|
+
* By default, after an action completes, ALL current route loaders are invalidated on the client
|
|
1381
|
+
* and re-fetched as needed (so that the browser cache is correct). This can be controlled with:
|
|
1382
|
+
*
|
|
1383
|
+
* - `invalidate: [loader1, loader2]`: Only invalidate specific loaders. The client re-fetches them
|
|
1384
|
+
* individually. Other loaders keep their current data.
|
|
1385
|
+
* - `invalidate: []`: No loaders are invalidated. The action response only contains the action
|
|
1386
|
+
* result. Use this when the action doesn't affect any loader data.
|
|
1387
|
+
*
|
|
1388
|
+
* The `strictLoaders` Vite plugin option applies `invalidate: []` globally for all actions that
|
|
1389
|
+
* don't specify an explicit `invalidate` option.
|
|
1390
|
+
*
|
|
1391
|
+
* @public
|
|
1392
|
+
*/ var routeAction$ = /*#__PURE__*/ implicit$FirstArg(routeActionQrl);
|
|
1393
|
+
/** @public */ var globalAction$ = /*#__PURE__*/ implicit$FirstArg(globalActionQrl);
|
|
1394
|
+
var deserializeStream = async function* (stream, abortSignal) {
|
|
1395
|
+
const reader = stream.getReader();
|
|
1396
|
+
try {
|
|
1397
|
+
let buffer = "";
|
|
1398
|
+
const decoder = new TextDecoder();
|
|
1399
|
+
while (!abortSignal?.aborted) {
|
|
1400
|
+
const result = await reader.read();
|
|
1401
|
+
if (result.done) break;
|
|
1402
|
+
buffer += decoder.decode(result.value, { stream: true });
|
|
1403
|
+
const lines = buffer.split(/\n/);
|
|
1404
|
+
buffer = lines.pop();
|
|
1405
|
+
for (const line of lines) yield await _deserialize(line);
|
|
1406
|
+
}
|
|
1407
|
+
} finally {
|
|
1408
|
+
reader.releaseLock();
|
|
1409
|
+
}
|
|
1818
1410
|
};
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1411
|
+
/** @internal */ var serverQrl = (qrl, options) => {
|
|
1412
|
+
if (isServer) {
|
|
1413
|
+
const captured = qrl.getCaptured();
|
|
1414
|
+
if (captured && captured.length > 0 && !_getContextHostElement()) throw new Error("For security reasons, we cannot serialize QRLs that capture lexical scope.");
|
|
1415
|
+
}
|
|
1416
|
+
const method = options?.method?.toUpperCase?.() || "POST";
|
|
1417
|
+
const headers = options?.headers || {};
|
|
1418
|
+
const origin = options?.origin || "";
|
|
1419
|
+
const fetchOptions = options?.fetchOptions || {};
|
|
1420
|
+
return /*#__PURE__*/ inlinedQrl(async function(...args) {
|
|
1421
|
+
const fetchOptions = _captures[0], headers = _captures[1], method = _captures[2], origin = _captures[3], qrl = _captures[4];
|
|
1422
|
+
const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
|
|
1423
|
+
if (isServer) return qrl.apply(getRequestEvent(this), args);
|
|
1424
|
+
else {
|
|
1425
|
+
let filteredArgs = args.map((arg) => {
|
|
1426
|
+
if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) return new FormData(arg.target);
|
|
1427
|
+
else if (arg instanceof Event) return null;
|
|
1428
|
+
else if (arg instanceof Node) return null;
|
|
1429
|
+
return arg;
|
|
1430
|
+
});
|
|
1431
|
+
if (!filteredArgs.length) filteredArgs = void 0;
|
|
1432
|
+
const qrlHash = qrl.getHash();
|
|
1433
|
+
let query = "";
|
|
1434
|
+
const config = {
|
|
1435
|
+
...fetchOptions,
|
|
1436
|
+
method,
|
|
1437
|
+
headers: {
|
|
1438
|
+
...headers,
|
|
1439
|
+
"Content-Type": "application/qwik-json",
|
|
1440
|
+
Accept: "application/json, application/qwik-json, text/qwik-json-stream, text/plain",
|
|
1441
|
+
"X-QRL": qrlHash
|
|
1442
|
+
},
|
|
1443
|
+
signal: abortSignal
|
|
1444
|
+
};
|
|
1445
|
+
const captured = qrl.getCaptured();
|
|
1446
|
+
let toSend = [filteredArgs];
|
|
1447
|
+
if (captured?.length) toSend = [filteredArgs, ...captured];
|
|
1448
|
+
else toSend = filteredArgs ? [filteredArgs] : [];
|
|
1449
|
+
const body = await _serialize(toSend);
|
|
1450
|
+
if (method === "GET") query += `&${QDATA_KEY}=${encodeURIComponent(body)}`;
|
|
1451
|
+
else config.body = body;
|
|
1452
|
+
const res = await fetch(`${origin}?${QFN_KEY}=${qrlHash}${query}`, config);
|
|
1453
|
+
const contentType = res.headers.get("Content-Type");
|
|
1454
|
+
if (res.ok && contentType === "text/qwik-json-stream" && res.body) return async function* () {
|
|
1455
|
+
try {
|
|
1456
|
+
for await (const result of deserializeStream(res.body, abortSignal)) yield result;
|
|
1457
|
+
} finally {
|
|
1458
|
+
if (!abortSignal?.aborted) await res.body.cancel();
|
|
1459
|
+
}
|
|
1460
|
+
}();
|
|
1461
|
+
else if (contentType === "application/qwik-json") {
|
|
1462
|
+
const str = await res.text();
|
|
1463
|
+
const obj = await _deserialize(str);
|
|
1464
|
+
if (res.status >= 400) throw obj;
|
|
1465
|
+
return obj;
|
|
1466
|
+
} else if (contentType === "application/json") {
|
|
1467
|
+
const obj = await res.json();
|
|
1468
|
+
if (res.status >= 400) throw obj;
|
|
1469
|
+
return obj;
|
|
1470
|
+
} else if (contentType === "text/plain" || contentType === "text/html") {
|
|
1471
|
+
const str = await res.text();
|
|
1472
|
+
if (res.status >= 400) throw str;
|
|
1473
|
+
return str;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
}, "serverQrl_w03grD0Ag68", [
|
|
1477
|
+
fetchOptions,
|
|
1478
|
+
headers,
|
|
1479
|
+
method,
|
|
1480
|
+
origin,
|
|
1481
|
+
qrl
|
|
1482
|
+
]);
|
|
1842
1483
|
};
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1484
|
+
/** @public */ var server$ = /*#__PURE__*/ implicit$FirstArg(serverQrl);
|
|
1485
|
+
/**
|
|
1486
|
+
* Loads the service workers that are defined in the routes. Any file named `service-worker.*` (all
|
|
1487
|
+
* JS extensions are allowed) will be picked up, bundled into a separate file, and registered as a
|
|
1488
|
+
* service worker.
|
|
1489
|
+
*
|
|
1490
|
+
* Qwik 1.14.0 and above now use `<link rel="modulepreload">` by default. If you didn't add custom
|
|
1491
|
+
* service-worker logic, you should remove your service-worker.ts file(s) for the
|
|
1492
|
+
* `ServiceWorkerRegister` Component to actually unregister the service-worker.js and delete its
|
|
1493
|
+
* related cache. Make sure to keep the `ServiceWorkerRegister` Component in your app (without any
|
|
1494
|
+
* service-worker.ts file) as long as you want to unregister the service-worker.js for your users.
|
|
1495
|
+
*
|
|
1496
|
+
* @public
|
|
1497
|
+
*/ var ServiceWorkerRegister = (props) => /*#__PURE__*/ _jsxSorted("script", { nonce: _wrapProp(props, "nonce") }, {
|
|
1498
|
+
type: "module",
|
|
1499
|
+
dangerouslySetInnerHTML: swRegister
|
|
1500
|
+
}, null, 3, "1x_0");
|
|
1501
|
+
var _hf0 = (p0) => !p0.reloadDocument;
|
|
1502
|
+
var _hf0_str = "!p0.reloadDocument";
|
|
1503
|
+
var _hf1 = (p0) => p0.spaReset ? "true" : void 0;
|
|
1504
|
+
var _hf1_str = "p0.spaReset?\"true\":undefined";
|
|
1505
|
+
var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) => {
|
|
1506
|
+
const rest = _restProps(_rawProps, [
|
|
1507
|
+
"action",
|
|
1508
|
+
"spaReset",
|
|
1509
|
+
"reloadDocument",
|
|
1510
|
+
"onSubmit$"
|
|
1511
|
+
]);
|
|
1512
|
+
const nav = useNavigate();
|
|
1513
|
+
return /*#__PURE__*/ _jsxSplit("form", {
|
|
1514
|
+
action: "get",
|
|
1515
|
+
"preventdefault:submit": _fnSignal(_hf0, [_rawProps], _hf0_str),
|
|
1516
|
+
"data-spa-reset": _fnSignal(_hf1, [_rawProps], _hf1_str),
|
|
1517
|
+
..._getVarProps(rest),
|
|
1518
|
+
..._getConstProps(rest),
|
|
1519
|
+
"q-e:submit": [
|
|
1520
|
+
...Array.isArray(_rawProps.onSubmit$) ? _rawProps.onSubmit$ : [_rawProps.onSubmit$],
|
|
1521
|
+
/*#__PURE__*/ inlinedQrl(async (_evt, form) => {
|
|
1522
|
+
const nav = _captures[0];
|
|
1523
|
+
const formData = new FormData(form);
|
|
1524
|
+
const params = new URLSearchParams();
|
|
1525
|
+
formData.forEach((value, key) => {
|
|
1526
|
+
if (typeof value === "string") params.append(key, value);
|
|
1527
|
+
});
|
|
1528
|
+
await nav("?" + params.toString(), {
|
|
1529
|
+
type: "form",
|
|
1530
|
+
forceReload: true
|
|
1531
|
+
});
|
|
1532
|
+
}, "GetForm_component_form_q_e_submit_r3dkP9d2cF8", [nav]),
|
|
1533
|
+
/*#__PURE__*/ inlinedQrl((_evt, form) => {
|
|
1534
|
+
if (form.getAttribute("data-spa-reset") === "true") form.reset();
|
|
1535
|
+
form.dispatchEvent(new CustomEvent("submitcompleted", {
|
|
1536
|
+
bubbles: false,
|
|
1537
|
+
cancelable: false,
|
|
1538
|
+
composed: false,
|
|
1539
|
+
detail: { status: 200 }
|
|
1540
|
+
}));
|
|
1541
|
+
}, "GetForm_component_form_q_e_submit_1_cuYklZAOHrA")
|
|
1542
|
+
]
|
|
1543
|
+
}, null, /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "Q4_0"), 0, "Q4_1");
|
|
1544
|
+
}, "GetForm_component_2U5Z2Z8ryc0"));
|
|
1545
|
+
/** @public */ var Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => {
|
|
1546
|
+
if (action) {
|
|
1547
|
+
if (Array.isArray(onSubmit$)) return _jsxSplit("form", {
|
|
1548
|
+
..._getVarProps(rest),
|
|
1549
|
+
..._getConstProps(rest),
|
|
1550
|
+
action: _wrapProp(action, "actionPath"),
|
|
1551
|
+
"preventdefault:submit": !reloadDocument,
|
|
1552
|
+
"q-e:submit": [...onSubmit$, !reloadDocument ? /*#__PURE__*/ inlinedQrl((evt) => {
|
|
1553
|
+
const action = _captures[0];
|
|
1554
|
+
if (!action.submitted) return action.submit(evt);
|
|
1555
|
+
}, "Form_form_q_e_submit_6i0Jq5q8JFg", [action]) : void 0],
|
|
1556
|
+
["data-spa-reset"]: spaReset ? "true" : void 0
|
|
1557
|
+
}, { method: "post" }, null, 0, key);
|
|
1558
|
+
return _jsxSplit("form", {
|
|
1559
|
+
..._getVarProps(rest),
|
|
1560
|
+
..._getConstProps(rest),
|
|
1561
|
+
action: _wrapProp(action, "actionPath"),
|
|
1562
|
+
"preventdefault:submit": !reloadDocument,
|
|
1563
|
+
"q-e:submit": [onSubmit$, !reloadDocument ? action.submit : void 0],
|
|
1564
|
+
["data-spa-reset"]: spaReset ? "true" : void 0
|
|
1565
|
+
}, { method: "post" }, null, 0, key);
|
|
1566
|
+
} else return /*#__PURE__*/ _jsxSplit(GetForm, {
|
|
1567
|
+
spaReset,
|
|
1568
|
+
reloadDocument,
|
|
1569
|
+
onSubmit$,
|
|
1570
|
+
...rest
|
|
1571
|
+
}, null, null, 0, key);
|
|
1890
1572
|
};
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
}),
|
|
1915
|
-
$((_evt, form) => {
|
|
1916
|
-
if (form.getAttribute("data-spa-reset") === "true") {
|
|
1917
|
-
form.reset();
|
|
1918
|
-
}
|
|
1919
|
-
form.dispatchEvent(new CustomEvent("submitcompleted", {
|
|
1920
|
-
bubbles: false,
|
|
1921
|
-
cancelable: false,
|
|
1922
|
-
composed: false,
|
|
1923
|
-
detail: {
|
|
1924
|
-
status: 200
|
|
1925
|
-
}
|
|
1926
|
-
}));
|
|
1927
|
-
})
|
|
1928
|
-
],
|
|
1929
|
-
children: /* @__PURE__ */ jsx(Slot, {})
|
|
1930
|
-
});
|
|
1931
|
-
});
|
|
1932
|
-
const untypedAppUrl = function appUrl(route, params, paramsPrefix = "") {
|
|
1933
|
-
const path = route.split("/");
|
|
1934
|
-
for (let i = 0; i < path.length; i++) {
|
|
1935
|
-
const segment = path[i];
|
|
1936
|
-
if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
1937
|
-
const isSpread = segment.startsWith("[...");
|
|
1938
|
-
const key = segment.substring(segment.startsWith("[...") ? 4 : 1, segment.length - 1);
|
|
1939
|
-
const value = params ? params[paramsPrefix + key] || params[key] : "";
|
|
1940
|
-
path[i] = isSpread ? value : encodeURIComponent(value);
|
|
1941
|
-
}
|
|
1942
|
-
if (segment.startsWith("(") && segment.endsWith(")")) {
|
|
1943
|
-
path.splice(i, 1);
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
let url = path.join("/");
|
|
1947
|
-
let baseURL = "/";
|
|
1948
|
-
if (baseURL) {
|
|
1949
|
-
if (!baseURL.endsWith("/")) {
|
|
1950
|
-
baseURL += "/";
|
|
1951
|
-
}
|
|
1952
|
-
while (url.startsWith("/")) {
|
|
1953
|
-
url = url.substring(1);
|
|
1954
|
-
}
|
|
1955
|
-
url = baseURL + url;
|
|
1956
|
-
}
|
|
1957
|
-
return url;
|
|
1573
|
+
/**
|
|
1574
|
+
* @beta
|
|
1575
|
+
* @experimental
|
|
1576
|
+
*/ var untypedAppUrl = function appUrl(route, params, paramsPrefix = "") {
|
|
1577
|
+
const path = route.split("/");
|
|
1578
|
+
for (let i = 0; i < path.length; i++) {
|
|
1579
|
+
const segment = path[i];
|
|
1580
|
+
if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
1581
|
+
const isSpread = segment.startsWith("[...");
|
|
1582
|
+
const key = segment.substring(segment.startsWith("[...") ? 4 : 1, segment.length - 1);
|
|
1583
|
+
const value = params ? params[paramsPrefix + key] || params[key] : "";
|
|
1584
|
+
path[i] = isSpread ? value : encodeURIComponent(value);
|
|
1585
|
+
}
|
|
1586
|
+
if (segment.startsWith("(") && segment.endsWith(")")) path.splice(i, 1);
|
|
1587
|
+
}
|
|
1588
|
+
let url = path.join("/");
|
|
1589
|
+
let baseURL = "/";
|
|
1590
|
+
if (baseURL) {
|
|
1591
|
+
baseURL = ensureSlash(baseURL);
|
|
1592
|
+
while (url.startsWith("/")) url = url.substring(1);
|
|
1593
|
+
url = baseURL + url;
|
|
1594
|
+
}
|
|
1595
|
+
return url;
|
|
1958
1596
|
};
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1597
|
+
/**
|
|
1598
|
+
* Creates a new object from `obj` by omitting a set of `keys`.
|
|
1599
|
+
*
|
|
1600
|
+
* @beta
|
|
1601
|
+
* @experimental
|
|
1602
|
+
*/ function omitProps(obj, keys) {
|
|
1603
|
+
const omittedObj = {};
|
|
1604
|
+
for (const key in obj) if (!key.startsWith("param:") && !keys.includes(key)) omittedObj[key] = obj[key];
|
|
1605
|
+
return omittedObj;
|
|
1967
1606
|
}
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
1607
|
+
/**
|
|
1608
|
+
* Creates the `render()` function that is required by `createQwikRouter()`. It requires a function
|
|
1609
|
+
* that returns the `jsx` and `options` for the renderer.
|
|
1610
|
+
*
|
|
1611
|
+
* @example
|
|
1612
|
+
*
|
|
1613
|
+
* ```tsx
|
|
1614
|
+
* const renderer = createRenderer((opts) => {
|
|
1615
|
+
* if (opts.requestHeaders['x-hello'] === 'world') {
|
|
1616
|
+
* return { jsx: <Hello />, options: opts };
|
|
1617
|
+
* }
|
|
1618
|
+
* return { jsx: <Root />, options: {
|
|
1619
|
+
* ...opts,
|
|
1620
|
+
* serverData: {
|
|
1621
|
+
* ...opts.serverData,
|
|
1622
|
+
* documentHead: {
|
|
1623
|
+
* meta: [
|
|
1624
|
+
* { name: 'renderedAt', content: new Date().toISOString() },
|
|
1625
|
+
* ],
|
|
1626
|
+
* },
|
|
1627
|
+
* },
|
|
1628
|
+
* } };
|
|
1629
|
+
* });
|
|
1630
|
+
* ```
|
|
1631
|
+
*
|
|
1632
|
+
* @public
|
|
1633
|
+
*/ var createRenderer = (getOptions) => {
|
|
1634
|
+
return (opts) => {
|
|
1635
|
+
const { jsx, options } = getOptions(opts);
|
|
1636
|
+
const renderOptions = opts.serverData.renderMode === "static" ? {
|
|
1637
|
+
...options,
|
|
1638
|
+
streaming: {
|
|
1639
|
+
...options.streaming,
|
|
1640
|
+
outOfOrder: false
|
|
1641
|
+
}
|
|
1642
|
+
} : options;
|
|
1643
|
+
return renderToStream(jsx, renderOptions);
|
|
1644
|
+
};
|
|
2003
1645
|
};
|
|
1646
|
+
/**
|
|
1647
|
+
* This renders all the tags collected from `head`.
|
|
1648
|
+
*
|
|
1649
|
+
* You can partially override the head, for example if you want to change the title:
|
|
1650
|
+
*
|
|
1651
|
+
* ```tsx
|
|
1652
|
+
* import { DocumentHeadTags, useDocumentHead } from '@qwik.dev/router';
|
|
1653
|
+
*
|
|
1654
|
+
* export default component$(() => {
|
|
1655
|
+
* const head = useDocumentHead();
|
|
1656
|
+
* return <DocumentHeadTags title={`${head.title} - My App`} />;
|
|
1657
|
+
* });
|
|
1658
|
+
* ```
|
|
1659
|
+
*
|
|
1660
|
+
* You don't have to use this component, you can also do it yourself for full control. Just copy the
|
|
1661
|
+
* code from this component and modify it to your needs.
|
|
1662
|
+
*
|
|
1663
|
+
* Note that this component normally only runs once, during SSR. You can use Signals in your
|
|
1664
|
+
* `src/root.tsx` to make runtime changes to `<head>` if needed.
|
|
1665
|
+
*
|
|
1666
|
+
* @public
|
|
1667
|
+
*/ var DocumentHeadTags = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
1668
|
+
let head = useDocumentHead();
|
|
1669
|
+
if (props) head = {
|
|
1670
|
+
...head,
|
|
1671
|
+
...props
|
|
1672
|
+
};
|
|
1673
|
+
return /*#__PURE__*/ _jsxSorted(Fragment, null, null, [
|
|
1674
|
+
head.title && /*#__PURE__*/ _jsxSorted("title", null, null, head.title, 1, "r5_0"),
|
|
1675
|
+
head.meta.map((m) => /*#__PURE__*/ _jsxSplit("meta", { ..._getVarProps(m) }, _getConstProps(m), null, 0, "r5_1")),
|
|
1676
|
+
head.links.map((l) => /*#__PURE__*/ _jsxSplit("link", { ..._getVarProps(l) }, _getConstProps(l), null, 0, "r5_2")),
|
|
1677
|
+
head.styles.map((s) => {
|
|
1678
|
+
const props = s.props || s;
|
|
1679
|
+
return /*#__PURE__*/ createElement("style", {
|
|
1680
|
+
...props,
|
|
1681
|
+
dangerouslySetInnerHTML: s.style || props.dangerouslySetInnerHTML,
|
|
1682
|
+
key: s.key
|
|
1683
|
+
});
|
|
1684
|
+
}),
|
|
1685
|
+
head.scripts.map((s) => {
|
|
1686
|
+
const props = s.props || s;
|
|
1687
|
+
return /*#__PURE__*/ createElement("script", {
|
|
1688
|
+
...props,
|
|
1689
|
+
dangerouslySetInnerHTML: s.script || props.dangerouslySetInnerHTML,
|
|
1690
|
+
key: s.key
|
|
1691
|
+
});
|
|
1692
|
+
})
|
|
1693
|
+
], 1, "r5_3");
|
|
1694
|
+
}, "DocumentHeadTags_component_9CrWYOoCpgY"));
|
|
1695
|
+
export { DocumentHeadTags, ErrorBoundary, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, createRenderer, getRequestEvent, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, untypedAppUrl, useContent, useDocumentHead, useHttpStatus, useLocation, useNavigate, usePreventNavigate$, usePreventNavigateQrl, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, z, zod$, zodQrl };
|