@tyndall/core 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/client-router-bootstrap.d.ts +1 -0
- package/dist/client-router-bootstrap.d.ts.map +1 -1
- package/dist/client-router-bootstrap.js +422 -149
- package/dist/config.d.ts +4 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/layouts.d.ts +1 -0
- package/dist/layouts.d.ts.map +1 -1
- package/dist/layouts.js +16 -0
- package/dist/manifest.d.ts +68 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +66 -2
- package/dist/page-api.d.ts +27 -0
- package/dist/page-api.d.ts.map +1 -1
- package/dist/page-api.js +67 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/route-data.d.ts +7 -0
- package/dist/route-data.d.ts.map +1 -0
- package/dist/route-data.js +5 -0
- package/dist/route-graph.d.ts.map +1 -1
- package/dist/route-graph.js +25 -44
- package/dist/route-utils.d.ts +4 -0
- package/dist/route-utils.d.ts.map +1 -0
- package/dist/route-utils.js +43 -0
- package/dist/router.d.ts +2 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/special-routes.d.ts +14 -0
- package/dist/special-routes.d.ts.map +1 -0
- package/dist/special-routes.js +17 -0
- package/dist/ui-adapter.d.ts +3 -0
- package/dist/ui-adapter.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,59 +1,111 @@
|
|
|
1
|
+
import { ROUTE_DATA_SCRIPT_ID } from "./route-data.js";
|
|
1
2
|
export const CLIENT_ROUTER_BOOTSTRAP_PATH = "/_hyper/client-bootstrap.js";
|
|
2
3
|
export const renderClientRouterBootstrap = (options) => {
|
|
3
4
|
const navigationMode = JSON.stringify(options.navigationMode);
|
|
4
5
|
const clientRenderMode = JSON.stringify(options.clientRenderMode);
|
|
5
6
|
const prefetchPath = JSON.stringify(options.prefetchPath ?? "/__hyper/prefetch");
|
|
6
7
|
const linkInterceptionMode = JSON.stringify(options.linkInterceptionMode ?? "marked");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const scrollRestoration = JSON.stringify(options.scrollRestoration !== false);
|
|
9
|
+
const routeDataScriptId = JSON.stringify(ROUTE_DATA_SCRIPT_ID);
|
|
10
|
+
return `(function () {
|
|
11
|
+
if (typeof window === "undefined") { return; }
|
|
12
|
+
if (window.__HYPER_CLIENT_BOOTSTRAP__) { return; }
|
|
10
13
|
window.__HYPER_CLIENT_BOOTSTRAP__ = true;
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
var navigationMode = ${navigationMode};
|
|
16
|
+
var clientRenderMode = ${clientRenderMode};
|
|
17
|
+
var prefetchPath = ${prefetchPath};
|
|
18
|
+
var linkInterceptionMode = ${linkInterceptionMode};
|
|
19
|
+
var scrollRestoration = ${scrollRestoration};
|
|
20
|
+
var ROUTE_DATA_SCRIPT_ID = ${routeDataScriptId};
|
|
16
21
|
|
|
17
22
|
if (navigationMode !== "client") {
|
|
18
23
|
return;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
var NAVIGATION_HEADER = "x-hyper-navigation";
|
|
27
|
+
var NAVIGATION_MODE = "csr";
|
|
28
|
+
var MANAGED_HEAD_ATTR = "data-hyper-head";
|
|
29
|
+
var ROUTE_PAYLOAD_EVENT = "hyper:route-payload-applied";
|
|
30
|
+
var ROUTE_DATA_EVENT = "hyper:route-data-applied";
|
|
31
|
+
var ROUTE_REDIRECT_KIND = "hyper-route-redirect";
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33
|
+
var isRecord = function (value) {
|
|
34
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
var parseJsonPayload = function (value) {
|
|
38
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(value);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
var resolveNavigationGuard = function () {
|
|
49
|
+
var guard = window.__HYPER_NAVIGATION_GUARD__;
|
|
50
|
+
return typeof guard === "function" ? guard : null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
var shouldAllowNavigation = function (href, replace, type) {
|
|
54
|
+
var guard = resolveNavigationGuard();
|
|
55
|
+
if (!guard) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return guard({ href: href, replace: Boolean(replace), type: type });
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
28
64
|
|
|
29
|
-
|
|
30
|
-
if (!target
|
|
65
|
+
var findAnchor = function (target) {
|
|
66
|
+
if (!target) {
|
|
31
67
|
return null;
|
|
32
68
|
}
|
|
33
|
-
|
|
69
|
+
if (typeof target.closest === "function") {
|
|
70
|
+
return target.closest("a[href]");
|
|
71
|
+
}
|
|
72
|
+
var node = target;
|
|
73
|
+
while (node && node.nodeType === 1) {
|
|
74
|
+
if (
|
|
75
|
+
node.tagName &&
|
|
76
|
+
node.tagName.toLowerCase() === "a" &&
|
|
77
|
+
node.getAttribute &&
|
|
78
|
+
node.getAttribute("href")
|
|
79
|
+
) {
|
|
80
|
+
return node;
|
|
81
|
+
}
|
|
82
|
+
node = node.parentNode;
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
34
85
|
};
|
|
35
86
|
|
|
36
|
-
|
|
37
|
-
event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
|
|
87
|
+
var isModifiedClick = function (event) {
|
|
88
|
+
return event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
|
|
89
|
+
};
|
|
38
90
|
|
|
39
|
-
|
|
40
|
-
if (!anchor) return false;
|
|
41
|
-
if (anchor.getAttribute("data-hyper-link") === "false") return false;
|
|
42
|
-
if (linkInterceptionMode === "all") return true;
|
|
91
|
+
var shouldInterceptAnchor = function (anchor) {
|
|
92
|
+
if (!anchor) { return false; }
|
|
93
|
+
if (anchor.getAttribute("data-hyper-link") === "false") { return false; }
|
|
94
|
+
if (linkInterceptionMode === "all") { return true; }
|
|
43
95
|
return anchor.hasAttribute("data-hyper-link");
|
|
44
96
|
};
|
|
45
97
|
|
|
46
|
-
|
|
47
|
-
if (!anchor) return false;
|
|
48
|
-
if (event && event.button !== 0) return false;
|
|
49
|
-
if (event && isModifiedClick(event)) return false;
|
|
50
|
-
if (anchor.hasAttribute("download")) return false;
|
|
51
|
-
if (anchor.getAttribute("target")) return false;
|
|
52
|
-
if (anchor.getAttribute("rel") === "external") return false;
|
|
53
|
-
if (!shouldInterceptAnchor(anchor)) return false;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (url.origin !== window.location.origin) return false;
|
|
98
|
+
var canHandleAnchor = function (anchor, event) {
|
|
99
|
+
if (!anchor) { return false; }
|
|
100
|
+
if (event && event.button !== 0) { return false; }
|
|
101
|
+
if (event && isModifiedClick(event)) { return false; }
|
|
102
|
+
if (anchor.hasAttribute("download")) { return false; }
|
|
103
|
+
if (anchor.getAttribute("target")) { return false; }
|
|
104
|
+
if (anchor.getAttribute("rel") === "external") { return false; }
|
|
105
|
+
if (!shouldInterceptAnchor(anchor)) { return false; }
|
|
106
|
+
|
|
107
|
+
var url = new URL(anchor.href, window.location.href);
|
|
108
|
+
if (url.origin !== window.location.origin) { return false; }
|
|
57
109
|
if (
|
|
58
110
|
url.hash &&
|
|
59
111
|
url.pathname === window.location.pathname &&
|
|
@@ -64,45 +116,137 @@ export const renderClientRouterBootstrap = (options) => {
|
|
|
64
116
|
return true;
|
|
65
117
|
};
|
|
66
118
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
119
|
+
var scrollPositions =
|
|
120
|
+
window.__HYPER_SCROLL_POSITIONS__ && typeof window.__HYPER_SCROLL_POSITIONS__ === "object"
|
|
121
|
+
? window.__HYPER_SCROLL_POSITIONS__
|
|
122
|
+
: {};
|
|
123
|
+
window.__HYPER_SCROLL_POSITIONS__ = scrollPositions;
|
|
124
|
+
|
|
125
|
+
var toScrollKey = function (url) {
|
|
126
|
+
return url.pathname + url.search;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
var saveScrollPosition = function (href) {
|
|
130
|
+
if (!scrollRestoration) { return; }
|
|
131
|
+
if (!href || typeof href !== "string") { return; }
|
|
132
|
+
try {
|
|
133
|
+
var url = new URL(href, window.location.href);
|
|
134
|
+
var key = toScrollKey(url);
|
|
135
|
+
scrollPositions[key] = {
|
|
136
|
+
x: window.scrollX || window.pageXOffset || 0,
|
|
137
|
+
y: window.scrollY || window.pageYOffset || 0
|
|
138
|
+
};
|
|
139
|
+
} catch (error) {
|
|
140
|
+
// Ignore malformed hrefs for scroll tracking.
|
|
71
141
|
}
|
|
72
142
|
};
|
|
73
143
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
144
|
+
var scrollToHash = function (url) {
|
|
145
|
+
if (!url.hash) { return false; }
|
|
146
|
+
var id = url.hash.slice(1);
|
|
147
|
+
if (!id) { return false; }
|
|
148
|
+
var node = document.getElementById(id);
|
|
149
|
+
if (node && typeof node.scrollIntoView === "function") {
|
|
150
|
+
node.scrollIntoView();
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
var restoreScrollPosition = function (url, fromHistory) {
|
|
157
|
+
if (!scrollRestoration) { return; }
|
|
158
|
+
if (scrollToHash(url)) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
var key = toScrollKey(url);
|
|
162
|
+
if (fromHistory && scrollPositions[key]) {
|
|
163
|
+
var position = scrollPositions[key];
|
|
164
|
+
if (position && typeof position === "object") {
|
|
165
|
+
var x = typeof position.x === "number" ? position.x : 0;
|
|
166
|
+
var y = typeof position.y === "number" ? position.y : 0;
|
|
167
|
+
window.scrollTo(x, y);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
window.scrollTo(0, 0);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (scrollRestoration && window.history && "scrollRestoration" in window.history) {
|
|
175
|
+
try {
|
|
176
|
+
window.history.scrollRestoration = "manual";
|
|
177
|
+
} catch (error) {
|
|
178
|
+
// Ignore environments that block scrollRestoration assignment.
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
var currentHref = window.location.href;
|
|
183
|
+
var initialRouteDataScript = document.getElementById(ROUTE_DATA_SCRIPT_ID);
|
|
184
|
+
if (initialRouteDataScript && !window.__HYPER_ROUTE_DATA__) {
|
|
185
|
+
window.__HYPER_ROUTE_DATA__ = parseJsonPayload(initialRouteDataScript.textContent);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var removeManagedHead = function () {
|
|
189
|
+
if (!document.head) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
var managed = document.head.querySelectorAll("[" + MANAGED_HEAD_ATTR + "]");
|
|
193
|
+
for (var index = 0; index < managed.length; index += 1) {
|
|
194
|
+
var node = managed[index];
|
|
195
|
+
if (!node) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (typeof node.remove === "function") {
|
|
199
|
+
node.remove();
|
|
200
|
+
} else if (node.parentNode) {
|
|
201
|
+
node.parentNode.removeChild(node);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
var appendHeadNode = function (tagName, attrs) {
|
|
207
|
+
if (!document.head) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
var node = document.createElement(tagName);
|
|
211
|
+
for (var key in attrs) {
|
|
212
|
+
if (!Object.prototype.hasOwnProperty.call(attrs, key)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
var value = attrs[key];
|
|
216
|
+
if (value === undefined || value === null) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
78
219
|
node.setAttribute(key, String(value));
|
|
79
220
|
}
|
|
80
221
|
node.setAttribute(MANAGED_HEAD_ATTR, "true");
|
|
81
222
|
document.head.appendChild(node);
|
|
82
223
|
};
|
|
83
224
|
|
|
84
|
-
|
|
85
|
-
if (!isRecord(head)) return;
|
|
225
|
+
var applyHead = function (head) {
|
|
226
|
+
if (!isRecord(head)) { return; }
|
|
86
227
|
if (typeof head.title === "string") {
|
|
87
228
|
document.title = head.title;
|
|
88
229
|
}
|
|
89
230
|
removeManagedHead();
|
|
90
231
|
if (Array.isArray(head.meta)) {
|
|
91
|
-
for (
|
|
232
|
+
for (var index = 0; index < head.meta.length; index += 1) {
|
|
233
|
+
var meta = head.meta[index];
|
|
92
234
|
if (isRecord(meta)) {
|
|
93
235
|
appendHeadNode("meta", meta);
|
|
94
236
|
}
|
|
95
237
|
}
|
|
96
238
|
}
|
|
97
239
|
if (Array.isArray(head.link)) {
|
|
98
|
-
for (
|
|
240
|
+
for (var linkIndex = 0; linkIndex < head.link.length; linkIndex += 1) {
|
|
241
|
+
var link = head.link[linkIndex];
|
|
99
242
|
if (isRecord(link)) {
|
|
100
243
|
appendHeadNode("link", link);
|
|
101
244
|
}
|
|
102
245
|
}
|
|
103
246
|
}
|
|
104
247
|
if (Array.isArray(head.script)) {
|
|
105
|
-
for (
|
|
248
|
+
for (var scriptIndex = 0; scriptIndex < head.script.length; scriptIndex += 1) {
|
|
249
|
+
var script = head.script[scriptIndex];
|
|
106
250
|
if (isRecord(script)) {
|
|
107
251
|
appendHeadNode("script", script);
|
|
108
252
|
}
|
|
@@ -110,18 +254,52 @@ export const renderClientRouterBootstrap = (options) => {
|
|
|
110
254
|
}
|
|
111
255
|
};
|
|
112
256
|
|
|
113
|
-
|
|
114
|
-
if (!isRecord(value)) return false;
|
|
115
|
-
if (value.kind !== "hyper-route-payload") return false;
|
|
116
|
-
if (typeof value.routeId !== "string") return false;
|
|
117
|
-
if (typeof value.appHtml !== "string") return false;
|
|
118
|
-
if (typeof value.propsPayload !== "string") return false;
|
|
257
|
+
var isRoutePayload = function (value) {
|
|
258
|
+
if (!isRecord(value)) { return false; }
|
|
259
|
+
if (value.kind !== "hyper-route-payload") { return false; }
|
|
260
|
+
if (typeof value.routeId !== "string") { return false; }
|
|
261
|
+
if (typeof value.appHtml !== "string") { return false; }
|
|
262
|
+
if (typeof value.propsPayload !== "string") { return false; }
|
|
263
|
+
if (
|
|
264
|
+
value.routeDataPayload !== undefined &&
|
|
265
|
+
value.routeDataPayload !== null &&
|
|
266
|
+
typeof value.routeDataPayload !== "string"
|
|
267
|
+
) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
119
270
|
return true;
|
|
120
271
|
};
|
|
121
272
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
273
|
+
var isRouteRedirect = function (value) {
|
|
274
|
+
if (!isRecord(value)) { return false; }
|
|
275
|
+
if (value.kind !== ROUTE_REDIRECT_KIND) { return false; }
|
|
276
|
+
if (typeof value.destination !== "string") { return false; }
|
|
277
|
+
return true;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
var applyRouteDataPayload = function (payload, routeId) {
|
|
281
|
+
var routeDataPayload =
|
|
282
|
+
typeof payload.routeDataPayload === "string" ? payload.routeDataPayload : "{}";
|
|
283
|
+
var routeDataScript = document.getElementById(ROUTE_DATA_SCRIPT_ID);
|
|
284
|
+
if (routeDataScript) {
|
|
285
|
+
routeDataScript.textContent = routeDataPayload;
|
|
286
|
+
}
|
|
287
|
+
var routeData = parseJsonPayload(routeDataPayload);
|
|
288
|
+
window.__HYPER_ROUTE_DATA__ = routeData;
|
|
289
|
+
try {
|
|
290
|
+
window.dispatchEvent(
|
|
291
|
+
new CustomEvent(ROUTE_DATA_EVENT, {
|
|
292
|
+
detail: { routeId: routeId, routeData: routeData }
|
|
293
|
+
})
|
|
294
|
+
);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
// Keep navigation resilient even when CustomEvent is unavailable.
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
var applyPayload = function (payload) {
|
|
301
|
+
var app = document.getElementById("app");
|
|
302
|
+
var hasMountedClientApp =
|
|
125
303
|
payload.hydration !== "islands" && Boolean(window.__HYPER_CLIENT_APP_MOUNTED__);
|
|
126
304
|
if (app) {
|
|
127
305
|
if (!hasMountedClientApp) {
|
|
@@ -139,11 +317,12 @@ export const renderClientRouterBootstrap = (options) => {
|
|
|
139
317
|
}
|
|
140
318
|
}
|
|
141
319
|
|
|
142
|
-
|
|
320
|
+
var propsScript = document.getElementById("__HYPER_PROPS__");
|
|
143
321
|
if (propsScript) {
|
|
144
322
|
propsScript.textContent = payload.propsPayload;
|
|
145
323
|
}
|
|
146
324
|
|
|
325
|
+
applyRouteDataPayload(payload, payload.routeId);
|
|
147
326
|
applyHead(payload.head);
|
|
148
327
|
window.__HYPER_ROUTE_ID__ = payload.routeId;
|
|
149
328
|
window.__HYPER_HYDRATED__ = false;
|
|
@@ -151,77 +330,105 @@ export const renderClientRouterBootstrap = (options) => {
|
|
|
151
330
|
try {
|
|
152
331
|
window.dispatchEvent(
|
|
153
332
|
new CustomEvent(ROUTE_PAYLOAD_EVENT, {
|
|
154
|
-
detail: { routeId: payload.routeId }
|
|
155
|
-
})
|
|
333
|
+
detail: { routeId: payload.routeId }
|
|
334
|
+
})
|
|
156
335
|
);
|
|
157
|
-
} catch {
|
|
336
|
+
} catch (error) {
|
|
158
337
|
// Keep navigation resilient even when CustomEvent is unavailable.
|
|
159
338
|
}
|
|
160
339
|
};
|
|
161
340
|
|
|
162
|
-
|
|
163
|
-
|
|
341
|
+
var resolveModuleMap = function () {
|
|
342
|
+
var raw = window.__HYPER_CLIENT_ROUTE_MODULES__;
|
|
164
343
|
return isRecord(raw) ? raw : null;
|
|
165
344
|
};
|
|
166
345
|
|
|
167
|
-
|
|
168
|
-
if (clientRenderMode !== "module") return false;
|
|
169
|
-
|
|
170
|
-
if (!moduleMap) return false;
|
|
171
|
-
|
|
172
|
-
if (typeof loader !== "function") return false;
|
|
346
|
+
var tryModuleRender = function (url) {
|
|
347
|
+
if (clientRenderMode !== "module") { return Promise.resolve(false); }
|
|
348
|
+
var moduleMap = resolveModuleMap();
|
|
349
|
+
if (!moduleMap) { return Promise.resolve(false); }
|
|
350
|
+
var loader = moduleMap[url.pathname];
|
|
351
|
+
if (typeof loader !== "function") { return Promise.resolve(false); }
|
|
173
352
|
try {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
353
|
+
return Promise.resolve(loader())
|
|
354
|
+
.then(function (loaded) {
|
|
355
|
+
var renderFn =
|
|
356
|
+
(isRecord(loaded) && typeof loaded.render === "function" && loaded.render) ||
|
|
357
|
+
(isRecord(loaded) && typeof loaded.default === "function" && loaded.default) ||
|
|
358
|
+
(typeof loaded === "function" && loaded);
|
|
359
|
+
if (typeof renderFn !== "function") { return false; }
|
|
360
|
+
return Promise.resolve(renderFn({
|
|
361
|
+
href: url.toString(),
|
|
362
|
+
pathname: url.pathname,
|
|
363
|
+
routeId: url.pathname,
|
|
364
|
+
params: {},
|
|
365
|
+
query: {}
|
|
366
|
+
})).then(function (rendered) {
|
|
367
|
+
if (!isRecord(rendered) || typeof rendered.appHtml !== "string") {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
var routeDataPayload = "{}";
|
|
371
|
+
if (typeof rendered.routeDataPayload === "string") {
|
|
372
|
+
routeDataPayload = rendered.routeDataPayload;
|
|
373
|
+
} else if (isRecord(rendered.routeData)) {
|
|
374
|
+
try {
|
|
375
|
+
routeDataPayload = JSON.stringify(rendered.routeData);
|
|
376
|
+
} catch (error) {
|
|
377
|
+
routeDataPayload = "{}";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
applyPayload({
|
|
381
|
+
kind: "hyper-route-payload",
|
|
382
|
+
routeId: typeof rendered.routeId === "string" ? rendered.routeId : url.pathname,
|
|
383
|
+
appHtml: rendered.appHtml,
|
|
384
|
+
propsPayload:
|
|
385
|
+
typeof rendered.propsPayload === "string" ? rendered.propsPayload : "{}",
|
|
386
|
+
routeDataPayload: routeDataPayload,
|
|
387
|
+
head: rendered.head,
|
|
388
|
+
hydration: rendered.hydration
|
|
389
|
+
});
|
|
390
|
+
return true;
|
|
391
|
+
});
|
|
392
|
+
})
|
|
393
|
+
.catch(function () {
|
|
394
|
+
return false;
|
|
395
|
+
});
|
|
396
|
+
} catch (error) {
|
|
397
|
+
return Promise.resolve(false);
|
|
202
398
|
}
|
|
203
399
|
};
|
|
204
400
|
|
|
205
|
-
|
|
401
|
+
var fetchPayload = function (url) {
|
|
206
402
|
try {
|
|
207
|
-
|
|
403
|
+
var headers = { accept: "application/json" };
|
|
404
|
+
headers[NAVIGATION_HEADER] = NAVIGATION_MODE;
|
|
405
|
+
return fetch(url.toString(), {
|
|
208
406
|
method: "GET",
|
|
209
|
-
headers:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
407
|
+
headers: headers
|
|
408
|
+
})
|
|
409
|
+
.then(function (response) {
|
|
410
|
+
if (!response || !response.ok) { return null; }
|
|
411
|
+
var contentType = response.headers.get("content-type") || "";
|
|
412
|
+
if (contentType.indexOf("application/json") === -1) { return null; }
|
|
413
|
+
return response.json().then(function (json) {
|
|
414
|
+
if (isRoutePayload(json)) {
|
|
415
|
+
return { kind: "payload", payload: json };
|
|
416
|
+
}
|
|
417
|
+
if (isRouteRedirect(json)) {
|
|
418
|
+
return { kind: "redirect", payload: json };
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
});
|
|
422
|
+
})
|
|
423
|
+
.catch(function () {
|
|
424
|
+
return null;
|
|
425
|
+
});
|
|
426
|
+
} catch (error) {
|
|
427
|
+
return Promise.resolve(null);
|
|
221
428
|
}
|
|
222
429
|
};
|
|
223
430
|
|
|
224
|
-
|
|
431
|
+
var updateHistory = function (url, replace) {
|
|
225
432
|
if (replace) {
|
|
226
433
|
window.history.replaceState(null, "", url.toString());
|
|
227
434
|
return;
|
|
@@ -229,8 +436,8 @@ export const renderClientRouterBootstrap = (options) => {
|
|
|
229
436
|
window.history.pushState(null, "", url.toString());
|
|
230
437
|
};
|
|
231
438
|
|
|
232
|
-
|
|
233
|
-
|
|
439
|
+
var navigateByUrl = function (url, replace) {
|
|
440
|
+
var href = url.toString();
|
|
234
441
|
if (replace) {
|
|
235
442
|
window.location.replace(href);
|
|
236
443
|
return;
|
|
@@ -238,81 +445,147 @@ export const renderClientRouterBootstrap = (options) => {
|
|
|
238
445
|
window.location.assign(href);
|
|
239
446
|
};
|
|
240
447
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
return
|
|
448
|
+
var navigate = function (href, options) {
|
|
449
|
+
options = options || {};
|
|
450
|
+
var url;
|
|
451
|
+
try {
|
|
452
|
+
url = new URL(href, window.location.href);
|
|
453
|
+
} catch (error) {
|
|
454
|
+
return Promise.resolve(false);
|
|
248
455
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
applyPayload(payload);
|
|
252
|
-
if (!options.skipHistory) {
|
|
253
|
-
updateHistory(url, Boolean(options.replace));
|
|
254
|
-
}
|
|
255
|
-
return true;
|
|
456
|
+
if (!shouldAllowNavigation(url.toString(), Boolean(options.replace), options.type || "navigate")) {
|
|
457
|
+
return Promise.resolve(false);
|
|
256
458
|
}
|
|
257
|
-
if (!options.
|
|
258
|
-
|
|
459
|
+
if (!options.skipScrollSave) {
|
|
460
|
+
saveScrollPosition(currentHref);
|
|
259
461
|
}
|
|
260
|
-
return
|
|
462
|
+
return tryModuleRender(url).then(function (handled) {
|
|
463
|
+
if (handled) {
|
|
464
|
+
if (!options.skipHistory) {
|
|
465
|
+
updateHistory(url, Boolean(options.replace));
|
|
466
|
+
}
|
|
467
|
+
currentHref = url.toString();
|
|
468
|
+
if (!options.skipScrollRestore) {
|
|
469
|
+
restoreScrollPosition(url, Boolean(options.fromHistory));
|
|
470
|
+
}
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
return fetchPayload(url).then(function (payload) {
|
|
474
|
+
if (payload && payload.kind === "redirect") {
|
|
475
|
+
var destination = payload.payload.destination;
|
|
476
|
+
if (destination) {
|
|
477
|
+
return navigate(destination, {
|
|
478
|
+
replace: Boolean(payload.payload.replace),
|
|
479
|
+
skipHistory: false,
|
|
480
|
+
disableUrlFallback: false,
|
|
481
|
+
skipScrollSave: true,
|
|
482
|
+
type: "redirect"
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (payload && payload.kind === "payload") {
|
|
487
|
+
applyPayload(payload.payload);
|
|
488
|
+
if (!options.skipHistory) {
|
|
489
|
+
updateHistory(url, Boolean(options.replace));
|
|
490
|
+
}
|
|
491
|
+
currentHref = url.toString();
|
|
492
|
+
if (!options.skipScrollRestore) {
|
|
493
|
+
restoreScrollPosition(url, Boolean(options.fromHistory));
|
|
494
|
+
}
|
|
495
|
+
return true;
|
|
496
|
+
}
|
|
497
|
+
if (!options.disableUrlFallback) {
|
|
498
|
+
navigateByUrl(url, Boolean(options.replace));
|
|
499
|
+
}
|
|
500
|
+
return false;
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
var softReload = function () {
|
|
506
|
+
return navigate(window.location.href, {
|
|
507
|
+
replace: true,
|
|
508
|
+
skipHistory: true,
|
|
509
|
+
disableUrlFallback: true,
|
|
510
|
+
skipScrollSave: true,
|
|
511
|
+
skipScrollRestore: true,
|
|
512
|
+
type: "softReload"
|
|
513
|
+
}).then(function (ok) {
|
|
514
|
+
if (!ok && typeof window.location.reload === "function") {
|
|
515
|
+
window.location.reload();
|
|
516
|
+
}
|
|
517
|
+
return ok;
|
|
518
|
+
});
|
|
261
519
|
};
|
|
262
520
|
|
|
263
|
-
|
|
521
|
+
window.__HYPER_SOFT_RELOAD__ = softReload;
|
|
522
|
+
|
|
523
|
+
var prefetch = function (href) {
|
|
264
524
|
try {
|
|
265
|
-
|
|
266
|
-
|
|
525
|
+
var url = new URL(href, window.location.href);
|
|
526
|
+
var prefetchUrl = new URL(prefetchPath, window.location.origin);
|
|
267
527
|
prefetchUrl.searchParams.set("path", url.pathname + url.search);
|
|
268
|
-
|
|
269
|
-
} catch {
|
|
528
|
+
return fetch(prefetchUrl.toString(), { method: "POST" }).catch(function () {});
|
|
529
|
+
} catch (error) {
|
|
270
530
|
// Best-effort prefetch only.
|
|
271
531
|
}
|
|
532
|
+
return Promise.resolve();
|
|
272
533
|
};
|
|
273
534
|
|
|
274
535
|
document.addEventListener(
|
|
275
536
|
"click",
|
|
276
|
-
(event)
|
|
277
|
-
|
|
537
|
+
function (event) {
|
|
538
|
+
var anchor = findAnchor(event.target);
|
|
278
539
|
if (!canHandleAnchor(anchor, event)) {
|
|
279
540
|
return;
|
|
280
541
|
}
|
|
281
|
-
event.preventDefault
|
|
282
|
-
|
|
542
|
+
if (event.preventDefault) {
|
|
543
|
+
event.preventDefault();
|
|
544
|
+
} else {
|
|
545
|
+
event.returnValue = false;
|
|
546
|
+
}
|
|
547
|
+
navigate(anchor.href, { type: "click" });
|
|
283
548
|
},
|
|
284
|
-
true
|
|
549
|
+
true
|
|
285
550
|
);
|
|
286
551
|
|
|
287
552
|
document.addEventListener(
|
|
288
553
|
"mouseover",
|
|
289
|
-
(event)
|
|
290
|
-
|
|
554
|
+
function (event) {
|
|
555
|
+
var anchor = findAnchor(event.target);
|
|
291
556
|
if (!anchor || !shouldInterceptAnchor(anchor)) {
|
|
292
557
|
return;
|
|
293
558
|
}
|
|
294
|
-
|
|
559
|
+
prefetch(anchor.href);
|
|
295
560
|
},
|
|
296
|
-
true
|
|
561
|
+
true
|
|
297
562
|
);
|
|
298
563
|
|
|
299
564
|
document.addEventListener(
|
|
300
565
|
"focusin",
|
|
301
|
-
(event)
|
|
302
|
-
|
|
566
|
+
function (event) {
|
|
567
|
+
var anchor = findAnchor(event.target);
|
|
303
568
|
if (!anchor || !shouldInterceptAnchor(anchor)) {
|
|
304
569
|
return;
|
|
305
570
|
}
|
|
306
|
-
|
|
571
|
+
prefetch(anchor.href);
|
|
307
572
|
},
|
|
308
|
-
true
|
|
573
|
+
true
|
|
309
574
|
);
|
|
310
575
|
|
|
311
|
-
window.addEventListener("popstate", ()
|
|
312
|
-
|
|
576
|
+
window.addEventListener("popstate", function () {
|
|
577
|
+
var previousHref = currentHref;
|
|
578
|
+
var nextHref = window.location.href;
|
|
579
|
+
if (previousHref && previousHref !== nextHref) {
|
|
580
|
+
saveScrollPosition(previousHref);
|
|
581
|
+
}
|
|
582
|
+
navigate(nextHref, {
|
|
313
583
|
replace: true,
|
|
314
584
|
skipHistory: true,
|
|
315
585
|
disableUrlFallback: false,
|
|
586
|
+
fromHistory: true,
|
|
587
|
+
skipScrollSave: true,
|
|
588
|
+
type: "popstate"
|
|
316
589
|
});
|
|
317
590
|
});
|
|
318
591
|
})();`;
|