crelte 0.1.3 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CrelteRequest.d.ts +11 -6
- package/dist/CrelteRequest.d.ts.map +1 -1
- package/dist/CrelteRequest.js +14 -14
- package/dist/graphql/GraphQl.d.ts +1 -1
- package/dist/graphql/GraphQl.d.ts.map +1 -1
- package/dist/graphql/GraphQl.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/init/client.d.ts.map +1 -1
- package/dist/init/client.js +11 -5
- package/dist/init/server.d.ts +2 -0
- package/dist/init/server.d.ts.map +1 -1
- package/dist/init/server.js +24 -10
- package/dist/init/shared.d.ts +3 -3
- package/dist/init/shared.d.ts.map +1 -1
- package/dist/init/shared.js +1 -1
- package/dist/loadData/index.d.ts +11 -5
- package/dist/loadData/index.d.ts.map +1 -1
- package/dist/loadData/index.js +15 -6
- package/dist/routing/History.d.ts +5 -3
- package/dist/routing/History.d.ts.map +1 -1
- package/dist/routing/History.js +9 -4
- package/dist/routing/InnerRouter.d.ts +31 -21
- package/dist/routing/InnerRouter.d.ts.map +1 -1
- package/dist/routing/InnerRouter.js +98 -76
- package/dist/routing/PageLoader.d.ts +4 -5
- package/dist/routing/PageLoader.d.ts.map +1 -1
- package/dist/routing/PageLoader.js +5 -5
- package/dist/routing/Request.d.ts +15 -2
- package/dist/routing/Request.d.ts.map +1 -1
- package/dist/routing/Request.js +22 -1
- package/dist/routing/Route.d.ts +61 -25
- package/dist/routing/Route.d.ts.map +1 -1
- package/dist/routing/Route.js +90 -41
- package/dist/routing/Router.d.ts +34 -13
- package/dist/routing/Router.d.ts.map +1 -1
- package/dist/routing/Router.js +102 -49
- package/package.json +3 -2
- package/src/CrelteRequest.ts +14 -19
- package/src/graphql/GraphQl.ts +5 -2
- package/src/index.ts +26 -3
- package/src/init/client.ts +14 -10
- package/src/init/server.ts +31 -11
- package/src/init/shared.ts +4 -4
- package/src/loadData/index.ts +47 -15
- package/src/routing/History.ts +12 -5
- package/src/routing/InnerRouter.ts +109 -82
- package/src/routing/PageLoader.ts +7 -17
- package/src/routing/Request.ts +28 -6
- package/src/routing/Route.ts +115 -52
- package/src/routing/Router.ts +123 -59
- package/LICENSE.md +0 -41
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Site, { SiteFromGraphQl } from './Site.js';
|
|
2
2
|
import History from './History.js';
|
|
3
|
-
import Request from './Request.js';
|
|
3
|
+
import Request, { RequestOptions } from './Request.js';
|
|
4
4
|
import Route from './Route.js';
|
|
5
5
|
export type InnerRouterOpts = {
|
|
6
6
|
preloadOnMouseOver: boolean;
|
|
@@ -10,16 +10,21 @@ export type InnerRouterOpts = {
|
|
|
10
10
|
*/
|
|
11
11
|
export default class InnerRouter {
|
|
12
12
|
sites: Site[];
|
|
13
|
+
/**
|
|
14
|
+
* The current route
|
|
15
|
+
*
|
|
16
|
+
* ## Null
|
|
17
|
+
* It might be null on the first targetToRequest, open, and routeFromUrl call
|
|
18
|
+
*/
|
|
13
19
|
route: Route | null;
|
|
14
|
-
site: Site;
|
|
15
20
|
history: History;
|
|
16
21
|
preloadOnMouseOver: boolean;
|
|
17
22
|
/**
|
|
18
23
|
* @param changeHistory returns a function you need to call when you are ready to
|
|
19
24
|
update the window history (note do not call this after another onRoute call was made)
|
|
20
25
|
*/
|
|
21
|
-
onRoute: (route: Request,
|
|
22
|
-
onPreload: (route: Request
|
|
26
|
+
onRoute: (route: Request, changeHistory: () => void) => void;
|
|
27
|
+
onPreload: (route: Request) => void;
|
|
23
28
|
private scrollDebounceTimeout;
|
|
24
29
|
/**
|
|
25
30
|
* Creates a new Router
|
|
@@ -39,8 +44,7 @@ export default class InnerRouter {
|
|
|
39
44
|
/**
|
|
40
45
|
* Get a site and if possible use the accept lang header.
|
|
41
46
|
*
|
|
42
|
-
* @param
|
|
43
|
-
* @return {Site}
|
|
47
|
+
* @param acceptLang Accept Language header.
|
|
44
48
|
*/
|
|
45
49
|
siteByAcceptLang(acceptLang?: string | null): Site;
|
|
46
50
|
/**
|
|
@@ -52,12 +56,13 @@ export default class InnerRouter {
|
|
|
52
56
|
*/
|
|
53
57
|
siteById(id: number): Site | null;
|
|
54
58
|
/**
|
|
55
|
-
* Resolve a url or Route and convert it to a
|
|
59
|
+
* Resolve a url or Route and convert it to a Request
|
|
56
60
|
*
|
|
57
61
|
* @param target
|
|
62
|
+
* @param opts, any option present will override the value in target
|
|
58
63
|
* @return Returns null if the url does not match our host (the protocol get's ignored)
|
|
59
64
|
*/
|
|
60
|
-
targetToRequest(target: string | URL | Route | Request): Request;
|
|
65
|
+
targetToRequest(target: string | URL | Route | Request, opts?: RequestOptions): Request;
|
|
61
66
|
/**
|
|
62
67
|
* Resolve a url and convert it to a Route
|
|
63
68
|
*
|
|
@@ -67,12 +72,16 @@ export default class InnerRouter {
|
|
|
67
72
|
routeFromUrl(fullUrl: URL): Route;
|
|
68
73
|
listen(): void;
|
|
69
74
|
/**
|
|
70
|
-
* Open
|
|
75
|
+
* Open a new route
|
|
71
76
|
*
|
|
72
77
|
* @param route a route object or an url or uri, never input the same route object again
|
|
73
78
|
* @param pushState if true pushed the state to the window.history
|
|
79
|
+
*
|
|
80
|
+
* ## Important
|
|
81
|
+
* Make sure a req always has the correct origin,
|
|
82
|
+
* `push` and `replace` will cause this function to throw an error
|
|
74
83
|
*/
|
|
75
|
-
open(
|
|
84
|
+
open(req: Request): void;
|
|
76
85
|
/**
|
|
77
86
|
* Sets a route
|
|
78
87
|
*
|
|
@@ -81,24 +90,25 @@ export default class InnerRouter {
|
|
|
81
90
|
*
|
|
82
91
|
* @param req
|
|
83
92
|
*/
|
|
84
|
-
setRoute(req: Request): void;
|
|
93
|
+
setRoute(req: Request, preventOnRoute?: boolean): void;
|
|
85
94
|
/**
|
|
86
|
-
* This pushes
|
|
87
|
-
* or currentSiteId change
|
|
95
|
+
* This pushes a new route to the history
|
|
88
96
|
*
|
|
89
|
-
*
|
|
90
|
-
* (search argument) and then call pushState
|
|
97
|
+
* @param req, never input the same route object again
|
|
91
98
|
*
|
|
92
|
-
*
|
|
99
|
+
* ## Important
|
|
100
|
+
* Make sure the route has the correct origin
|
|
93
101
|
*/
|
|
94
|
-
|
|
102
|
+
push(req: Request, preventOnRoute?: boolean): void;
|
|
95
103
|
/**
|
|
96
|
-
* This replaces the
|
|
97
|
-
*
|
|
104
|
+
* This replaces the current route
|
|
105
|
+
*
|
|
106
|
+
* @param req, never input the same route object again
|
|
98
107
|
*
|
|
99
|
-
*
|
|
108
|
+
* ## Important
|
|
109
|
+
* Make sure the route has the correct origin
|
|
100
110
|
*/
|
|
101
|
-
|
|
111
|
+
replace(req: Request): void;
|
|
102
112
|
/**
|
|
103
113
|
* Preload a url
|
|
104
114
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InnerRouter.d.ts","sourceRoot":"","sources":["../../../../src/routing/InnerRouter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,
|
|
1
|
+
{"version":3,"file":"InnerRouter.d.ts","sourceRoot":"","sources":["../../../../src/routing/InnerRouter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,OAAO,EAAE,EAAa,cAAc,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,MAAM,eAAe,GAAG;IAC7B,kBAAkB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;OAKG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC7D,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAEpC,OAAO,CAAC,qBAAqB,CAAa;IAE1C;;;;;OAKG;gBACS,KAAK,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,eAAe;IAkB3D;;OAEG;IACH,UAAU;IAaV;;OAEG;IACH,UAAU;IAEV;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;IAsCxD;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIjC;;;;;;OAMG;IACH,eAAe,CACd,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO,EACtC,IAAI,GAAE,cAAmB,GACvB,OAAO;IAwBV;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK;IAgCjC,MAAM;IA6FN;;;;;;;;;OASG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO;IAuCjB;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,UAAQ;IAM7C;;;;;;;OAOG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,UAAQ;IAsBzC;;;;;;;OAOG;IACH,OAAO,CAAC,GAAG,EAAE,OAAO;IAsBpB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,OAAO;IAW9C,QAAQ,CAAC,GAAG,EAAE,OAAO;CAsErB"}
|
|
@@ -7,8 +7,13 @@ import Route from './Route.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export default class InnerRouter {
|
|
9
9
|
sites;
|
|
10
|
+
/**
|
|
11
|
+
* The current route
|
|
12
|
+
*
|
|
13
|
+
* ## Null
|
|
14
|
+
* It might be null on the first targetToRequest, open, and routeFromUrl call
|
|
15
|
+
*/
|
|
10
16
|
route;
|
|
11
|
-
site;
|
|
12
17
|
history;
|
|
13
18
|
preloadOnMouseOver;
|
|
14
19
|
/**
|
|
@@ -27,7 +32,6 @@ export default class InnerRouter {
|
|
|
27
32
|
constructor(sites, opts) {
|
|
28
33
|
this.sites = sites.map(s => new Site(s));
|
|
29
34
|
this.route = null;
|
|
30
|
-
this.site = this.defaultSite();
|
|
31
35
|
// @ts-ignore
|
|
32
36
|
this.history = import.meta.env.SSR
|
|
33
37
|
? new ServerHistory()
|
|
@@ -44,14 +48,11 @@ export default class InnerRouter {
|
|
|
44
48
|
initClient() {
|
|
45
49
|
this.listen();
|
|
46
50
|
// let's first try to load from the state
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (route.search.get('x-craft-live-preview')) {
|
|
51
|
-
route.origin = 'live-preview-init';
|
|
52
|
-
}
|
|
51
|
+
const req = this.targetToRequest(window.location.href);
|
|
52
|
+
req._fillFromState(window.history.state);
|
|
53
|
+
req.origin = 'init';
|
|
53
54
|
window.history.scrollRestoration = 'manual';
|
|
54
|
-
this.
|
|
55
|
+
this.setRoute(req);
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
58
|
* Initializes the router when running on the server.
|
|
@@ -60,8 +61,7 @@ export default class InnerRouter {
|
|
|
60
61
|
/**
|
|
61
62
|
* Get a site and if possible use the accept lang header.
|
|
62
63
|
*
|
|
63
|
-
* @param
|
|
64
|
-
* @return {Site}
|
|
64
|
+
* @param acceptLang Accept Language header.
|
|
65
65
|
*/
|
|
66
66
|
siteByAcceptLang(acceptLang = null) {
|
|
67
67
|
if (!acceptLang)
|
|
@@ -102,7 +102,7 @@ export default class InnerRouter {
|
|
|
102
102
|
* Get the default site
|
|
103
103
|
*/
|
|
104
104
|
defaultSite() {
|
|
105
|
-
return this.sites[0];
|
|
105
|
+
return this.sites.find(s => s.primary) ?? this.sites[0];
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* Tries to get a site by it's id
|
|
@@ -111,15 +111,18 @@ export default class InnerRouter {
|
|
|
111
111
|
return this.sites.find(s => s.id === id) ?? null;
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
|
-
* Resolve a url or Route and convert it to a
|
|
114
|
+
* Resolve a url or Route and convert it to a Request
|
|
115
115
|
*
|
|
116
116
|
* @param target
|
|
117
|
+
* @param opts, any option present will override the value in target
|
|
117
118
|
* @return Returns null if the url does not match our host (the protocol get's ignored)
|
|
118
119
|
*/
|
|
119
|
-
targetToRequest(target) {
|
|
120
|
+
targetToRequest(target, opts = {}) {
|
|
120
121
|
if (typeof target === 'string') {
|
|
121
122
|
if (target.startsWith('/')) {
|
|
122
|
-
|
|
123
|
+
// todo should we use the language matching or throw if the route does not
|
|
124
|
+
// exists
|
|
125
|
+
const site = this.route?.site ?? this.defaultSite();
|
|
123
126
|
target = new URL(site.uri + target, site.url);
|
|
124
127
|
}
|
|
125
128
|
else {
|
|
@@ -130,8 +133,9 @@ export default class InnerRouter {
|
|
|
130
133
|
target = this.routeFromUrl(target);
|
|
131
134
|
}
|
|
132
135
|
if (!isRequest(target)) {
|
|
133
|
-
return Request.fromRoute(target);
|
|
136
|
+
return Request.fromRoute(target, opts);
|
|
134
137
|
}
|
|
138
|
+
target._updateOpts(opts);
|
|
135
139
|
return target;
|
|
136
140
|
}
|
|
137
141
|
/**
|
|
@@ -161,7 +165,9 @@ export default class InnerRouter {
|
|
|
161
165
|
continue;
|
|
162
166
|
site = s;
|
|
163
167
|
}
|
|
164
|
-
|
|
168
|
+
// todo should we throw if we can't find a site
|
|
169
|
+
// or use the site which matches the language
|
|
170
|
+
route.site = site ?? this.defaultSite();
|
|
165
171
|
return route;
|
|
166
172
|
}
|
|
167
173
|
listen() {
|
|
@@ -177,11 +183,18 @@ export default class InnerRouter {
|
|
|
177
183
|
if (!link.href.startsWith('http'))
|
|
178
184
|
return;
|
|
179
185
|
e.preventDefault();
|
|
180
|
-
const
|
|
181
|
-
|
|
186
|
+
const req = this.targetToRequest(link.href, { origin: 'click' });
|
|
187
|
+
const routeEq = this.route && this.route.eqUrl(req) && this.route.eqSearch(req);
|
|
188
|
+
// the route is the same don't do anything
|
|
189
|
+
// or maybe scroll the page to the hash? todo
|
|
190
|
+
if (routeEq && this.route?.eqHash(req))
|
|
182
191
|
return;
|
|
183
|
-
|
|
184
|
-
|
|
192
|
+
// this means the hash did not match, so we wan't to just scroll but not load
|
|
193
|
+
// data
|
|
194
|
+
if (routeEq) {
|
|
195
|
+
req.disableLoadData = true;
|
|
196
|
+
}
|
|
197
|
+
this.open(req);
|
|
185
198
|
});
|
|
186
199
|
if (this.preloadOnMouseOver) {
|
|
187
200
|
let currentMouseOver = null;
|
|
@@ -220,7 +233,7 @@ export default class InnerRouter {
|
|
|
220
233
|
return;
|
|
221
234
|
// use the latest state
|
|
222
235
|
this.history.replaceState(this.route._toState());
|
|
223
|
-
if (current.
|
|
236
|
+
if (current.inLivePreview()) {
|
|
224
237
|
sessionStorage.setItem('live-preview-scroll',
|
|
225
238
|
// use the latest scrollY
|
|
226
239
|
this.route.scrollY + '');
|
|
@@ -232,24 +245,26 @@ export default class InnerRouter {
|
|
|
232
245
|
window.addEventListener('popstate', async (e) => {
|
|
233
246
|
if (!('route' in e.state))
|
|
234
247
|
return;
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
// for the scrollY in our open call so we just clear the current
|
|
240
|
-
// route since it is now already the new route
|
|
241
|
-
this.route = null;
|
|
242
|
-
this.open(route, false);
|
|
248
|
+
const req = this.targetToRequest(window.location.href);
|
|
249
|
+
req._fillFromState(e.state);
|
|
250
|
+
req.origin = 'pop';
|
|
251
|
+
this.setRoute(req);
|
|
243
252
|
});
|
|
244
253
|
}
|
|
245
254
|
/**
|
|
246
|
-
* Open
|
|
255
|
+
* Open a new route
|
|
247
256
|
*
|
|
248
257
|
* @param route a route object or an url or uri, never input the same route object again
|
|
249
258
|
* @param pushState if true pushed the state to the window.history
|
|
259
|
+
*
|
|
260
|
+
* ## Important
|
|
261
|
+
* Make sure a req always has the correct origin,
|
|
262
|
+
* `push` and `replace` will cause this function to throw an error
|
|
250
263
|
*/
|
|
251
|
-
open(
|
|
252
|
-
|
|
264
|
+
open(req) {
|
|
265
|
+
if (['push', 'replace'].includes(req.origin)) {
|
|
266
|
+
throw new Error('Do not use open with push or replace');
|
|
267
|
+
}
|
|
253
268
|
const current = this.route;
|
|
254
269
|
if (current) {
|
|
255
270
|
// if the scrollY would still be updated we clear the timeout
|
|
@@ -270,18 +285,13 @@ export default class InnerRouter {
|
|
|
270
285
|
if ((current && current.url.origin !== req.url.origin) ||
|
|
271
286
|
// @ts-ignore
|
|
272
287
|
import.meta.env.SSR) {
|
|
273
|
-
this.history.open(req
|
|
288
|
+
this.history.open(req);
|
|
274
289
|
return;
|
|
275
290
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
this.
|
|
279
|
-
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
this.setRoute(req);
|
|
284
|
-
}
|
|
291
|
+
req.index = (current?.index ?? 0) + 1;
|
|
292
|
+
this.onRoute(req, () => {
|
|
293
|
+
this.push(req, true);
|
|
294
|
+
});
|
|
285
295
|
}
|
|
286
296
|
/**
|
|
287
297
|
* Sets a route
|
|
@@ -291,40 +301,56 @@ export default class InnerRouter {
|
|
|
291
301
|
*
|
|
292
302
|
* @param req
|
|
293
303
|
*/
|
|
294
|
-
setRoute(req) {
|
|
304
|
+
setRoute(req, preventOnRoute = false) {
|
|
295
305
|
this.route = req.toRoute();
|
|
296
|
-
if (
|
|
297
|
-
this.
|
|
298
|
-
this.onRoute(req, this.site, () => { });
|
|
306
|
+
if (!preventOnRoute)
|
|
307
|
+
this.onRoute(req, () => { });
|
|
299
308
|
}
|
|
300
309
|
/**
|
|
301
|
-
* This pushes
|
|
302
|
-
* or currentSiteId change
|
|
310
|
+
* This pushes a new route to the history
|
|
303
311
|
*
|
|
304
|
-
*
|
|
305
|
-
* (search argument) and then call pushState
|
|
312
|
+
* @param req, never input the same route object again
|
|
306
313
|
*
|
|
307
|
-
*
|
|
314
|
+
* ## Important
|
|
315
|
+
* Make sure the route has the correct origin
|
|
308
316
|
*/
|
|
309
|
-
|
|
310
|
-
const url =
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (
|
|
314
|
-
|
|
317
|
+
push(req, preventOnRoute = false) {
|
|
318
|
+
const url = req.url;
|
|
319
|
+
// todo a push should also store the previous scrollY
|
|
320
|
+
let nReq = req;
|
|
321
|
+
if (req.scrollY === null) {
|
|
322
|
+
// if there is no scrollY stored we store the current scrollY
|
|
323
|
+
// since a push does not cause a scroll top
|
|
324
|
+
// todo: probably should refactor something probably
|
|
325
|
+
// should not be here
|
|
326
|
+
nReq = req.clone();
|
|
327
|
+
nReq.scrollY = this.history.scrollY();
|
|
328
|
+
}
|
|
329
|
+
this.history.pushState(nReq._toState(), url.pathname + url.search + url.hash);
|
|
330
|
+
this.setRoute(req, preventOnRoute);
|
|
315
331
|
}
|
|
316
332
|
/**
|
|
317
|
-
* This replaces the
|
|
318
|
-
*
|
|
333
|
+
* This replaces the current route
|
|
334
|
+
*
|
|
335
|
+
* @param req, never input the same route object again
|
|
319
336
|
*
|
|
320
|
-
*
|
|
337
|
+
* ## Important
|
|
338
|
+
* Make sure the route has the correct origin
|
|
321
339
|
*/
|
|
322
|
-
|
|
323
|
-
const url =
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
340
|
+
replace(req) {
|
|
341
|
+
const url = req.url;
|
|
342
|
+
let nReq = req;
|
|
343
|
+
if (req.scrollY === null) {
|
|
344
|
+
// if there is no scrollY stored we store the current scrollY
|
|
345
|
+
// since a replace does not cause a scrollTo and we wan't
|
|
346
|
+
// history back to work as intended
|
|
347
|
+
// todo: probably should refactor something probably
|
|
348
|
+
// should not be here
|
|
349
|
+
nReq = req.clone();
|
|
350
|
+
nReq.scrollY = this.history.scrollY();
|
|
351
|
+
}
|
|
352
|
+
this.history.replaceState(nReq._toState(), url.pathname + url.search + url.hash);
|
|
353
|
+
this.setRoute(req);
|
|
328
354
|
}
|
|
329
355
|
/**
|
|
330
356
|
* Preload a url
|
|
@@ -335,18 +361,11 @@ export default class InnerRouter {
|
|
|
335
361
|
*/
|
|
336
362
|
preload(target) {
|
|
337
363
|
const req = this.targetToRequest(target);
|
|
338
|
-
// todo, don't think this makes any sense
|
|
339
|
-
// if the domain of the current site is different than the domain of the
|
|
340
|
-
// new site id does not make sense to preload
|
|
341
|
-
if (this.site.url.origin !== req.url.origin) {
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
364
|
const current = this.route;
|
|
345
|
-
const site = req.site ?? this.site;
|
|
346
365
|
// if the origin matches, the route will be able to be load
|
|
347
366
|
// so let's preload it
|
|
348
367
|
if (current && current.url.origin === req.url.origin) {
|
|
349
|
-
this.onPreload(req
|
|
368
|
+
this.onPreload(req);
|
|
350
369
|
}
|
|
351
370
|
}
|
|
352
371
|
domReady(req) {
|
|
@@ -356,7 +375,7 @@ export default class InnerRouter {
|
|
|
356
375
|
let scrollTo = null;
|
|
357
376
|
// if the route is a live preview init and we have a scrollY stored
|
|
358
377
|
// scroll to that
|
|
359
|
-
if (req.
|
|
378
|
+
if (req.inLivePreview()) {
|
|
360
379
|
const scrollY = sessionStorage.getItem('live-preview-scroll');
|
|
361
380
|
if (scrollY) {
|
|
362
381
|
scrollTo = {
|
|
@@ -386,6 +405,9 @@ export default class InnerRouter {
|
|
|
386
405
|
behavior: 'instant',
|
|
387
406
|
};
|
|
388
407
|
}
|
|
408
|
+
// make sure push and replace don't cause a scroll if it is not intended
|
|
409
|
+
if (!scrollTo && (req.origin === 'push' || req.origin === 'replace'))
|
|
410
|
+
return;
|
|
389
411
|
// scroll to the top if nothing else matches
|
|
390
412
|
if (!scrollTo) {
|
|
391
413
|
scrollTo = {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import Request from './Request.js';
|
|
2
|
-
import Site from './Site.js';
|
|
3
2
|
export type PageLoaderOptions = {
|
|
4
3
|
debugTiming: boolean;
|
|
5
4
|
};
|
|
@@ -7,7 +6,7 @@ export type LoadResponse = {
|
|
|
7
6
|
success: boolean;
|
|
8
7
|
data: any;
|
|
9
8
|
};
|
|
10
|
-
export type LoadFn = (req: Request,
|
|
9
|
+
export type LoadFn = (req: Request, opts: LoadOptions) => Promise<any> | any;
|
|
11
10
|
export type LoadOptions = {
|
|
12
11
|
setProgress: (num: number) => void;
|
|
13
12
|
};
|
|
@@ -18,7 +17,7 @@ export default class PageLoader<More> {
|
|
|
18
17
|
private debugTiming;
|
|
19
18
|
private preloadedUrls;
|
|
20
19
|
private loadingVersion;
|
|
21
|
-
onLoaded: (resp: LoadResponse, req: Request,
|
|
20
|
+
onLoaded: (resp: LoadResponse, req: Request, more: More) => void;
|
|
22
21
|
onProgress: (loading: boolean, progress?: number) => void;
|
|
23
22
|
loadFn: LoadFn;
|
|
24
23
|
/**
|
|
@@ -31,7 +30,7 @@ export default class PageLoader<More> {
|
|
|
31
30
|
* Discard the current page load if one is happening
|
|
32
31
|
*/
|
|
33
32
|
discard(): void;
|
|
34
|
-
load(req: Request,
|
|
35
|
-
preload(req: Request
|
|
33
|
+
load(req: Request, more: More): Promise<void>;
|
|
34
|
+
preload(req: Request): Promise<void>;
|
|
36
35
|
}
|
|
37
36
|
//# sourceMappingURL=PageLoader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageLoader.d.ts","sourceRoot":"","sources":["../../../../src/routing/PageLoader.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"PageLoader.d.ts","sourceRoot":"","sources":["../../../../src/routing/PageLoader.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAE7E,MAAM,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,IAAI;IACnC,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,aAAa,CAAc;IAEnC,OAAO,CAAC,cAAc,CAAS;IAE/B,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACjE,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IAWtC;;OAEG;IACH,OAAO;IAKD,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI;IAiC7B,OAAO,CAAC,GAAG,EAAE,OAAO;CAc1B"}
|
|
@@ -28,7 +28,7 @@ export default class PageLoader {
|
|
|
28
28
|
this.loadingVersion++;
|
|
29
29
|
this.onProgress(false);
|
|
30
30
|
}
|
|
31
|
-
async load(req,
|
|
31
|
+
async load(req, more) {
|
|
32
32
|
this.onProgress(true);
|
|
33
33
|
const version = ++this.loadingVersion;
|
|
34
34
|
const startTime = this.debugTiming ? Date.now() : null;
|
|
@@ -39,7 +39,7 @@ export default class PageLoader {
|
|
|
39
39
|
};
|
|
40
40
|
const resp = { success: false, data: null };
|
|
41
41
|
try {
|
|
42
|
-
resp.data = await this.loadFn(req,
|
|
42
|
+
resp.data = await this.loadFn(req, { setProgress });
|
|
43
43
|
resp.success = true;
|
|
44
44
|
}
|
|
45
45
|
catch (e) {
|
|
@@ -52,16 +52,16 @@ export default class PageLoader {
|
|
|
52
52
|
if (this.loadingVersion !== version)
|
|
53
53
|
return console.log('route changed quickly, ignoring response');
|
|
54
54
|
this.onProgress(false);
|
|
55
|
-
this.onLoaded(resp, req,
|
|
55
|
+
this.onLoaded(resp, req, more);
|
|
56
56
|
}
|
|
57
57
|
// you don't need to wait on this call
|
|
58
|
-
async preload(req
|
|
58
|
+
async preload(req) {
|
|
59
59
|
const url = req.url.origin + req.url.pathname;
|
|
60
60
|
if (this.preloadedUrls.has(url))
|
|
61
61
|
return;
|
|
62
62
|
this.preloadedUrls.add(url);
|
|
63
63
|
try {
|
|
64
|
-
await this.loadFn(req,
|
|
64
|
+
await this.loadFn(req, { setProgress: () => null });
|
|
65
65
|
}
|
|
66
66
|
catch (_e) {
|
|
67
67
|
console.log('preload failed');
|
|
@@ -9,6 +9,8 @@ export type RequestOptions = {
|
|
|
9
9
|
index?: number;
|
|
10
10
|
origin?: RouteOrigin;
|
|
11
11
|
disableScroll?: boolean;
|
|
12
|
+
disableLoadData?: boolean;
|
|
13
|
+
statusCode?: number;
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* A Request is a Route with some extra options
|
|
@@ -21,16 +23,25 @@ export default class Request extends Route {
|
|
|
21
23
|
* @default false
|
|
22
24
|
*/
|
|
23
25
|
disableScroll: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Disable loading data
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
disableLoadData: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The Status code that should be returned for a redirect
|
|
33
|
+
*/
|
|
34
|
+
statusCode: number | null;
|
|
24
35
|
/** @hidden */
|
|
25
36
|
_renderBarrier: RenderBarrier;
|
|
26
37
|
/**
|
|
27
38
|
* Create a new Request
|
|
28
39
|
*/
|
|
29
|
-
constructor(url: string | URL, site: Site
|
|
40
|
+
constructor(url: string | URL, site: Site, opts?: RequestOptions);
|
|
30
41
|
/**
|
|
31
42
|
* Create a Request from a Route
|
|
32
43
|
*/
|
|
33
|
-
static fromRoute(route: Route): Request;
|
|
44
|
+
static fromRoute(route: Route, opts?: RequestOptions): Request;
|
|
34
45
|
/**
|
|
35
46
|
* With delayRender you can make sure that the render waits
|
|
36
47
|
* until you are ready. This is useful for building page transitions.
|
|
@@ -68,6 +79,8 @@ export default class Request extends Route {
|
|
|
68
79
|
* Create a Route from the Request
|
|
69
80
|
*/
|
|
70
81
|
toRoute(): Route;
|
|
82
|
+
/** @hidden */
|
|
83
|
+
_updateOpts(opts?: RequestOptions): void;
|
|
71
84
|
}
|
|
72
85
|
export declare function isRequest(req: any): req is Request;
|
|
73
86
|
declare class RenderBarrier {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../../src/routing/Request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../../src/routing/Request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,KAAK;IACzC;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,cAAc;IACd,cAAc,EAAE,aAAa,CAAC;IAE9B;;OAEG;gBACS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAE,cAAmB;IASpE;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,cAAmB;IASxD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,IAAI,WAAW;IAI1B;;OAEG;IACH,KAAK;IAUL;;OAEG;IACH,OAAO;IAQP,cAAc;IACd,WAAW,CAAC,IAAI,GAAE,cAAmB;CAOrC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,CAElD;AAED,cAAM,aAAa;IAClB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;;IAQlB,MAAM,IAAI,OAAO;IAIjB,GAAG,IAAI,WAAW;IAclB,cAAc;IACd,MAAM;IAQN,cAAc;IACd,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;CAGzB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACzB;;;;;OAKG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC"}
|
package/dist/routing/Request.js
CHANGED
|
@@ -11,6 +11,15 @@ export default class Request extends Route {
|
|
|
11
11
|
* @default false
|
|
12
12
|
*/
|
|
13
13
|
disableScroll;
|
|
14
|
+
/**
|
|
15
|
+
* Disable loading data
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
disableLoadData;
|
|
19
|
+
/**
|
|
20
|
+
* The Status code that should be returned for a redirect
|
|
21
|
+
*/
|
|
22
|
+
statusCode;
|
|
14
23
|
/** @hidden */
|
|
15
24
|
_renderBarrier;
|
|
16
25
|
/**
|
|
@@ -19,16 +28,19 @@ export default class Request extends Route {
|
|
|
19
28
|
constructor(url, site, opts = {}) {
|
|
20
29
|
super(url, site, opts);
|
|
21
30
|
this.disableScroll = opts.disableScroll ?? false;
|
|
31
|
+
this.disableLoadData = opts.disableLoadData ?? false;
|
|
32
|
+
this.statusCode = opts.statusCode ?? null;
|
|
22
33
|
this._renderBarrier = new RenderBarrier();
|
|
23
34
|
}
|
|
24
35
|
/**
|
|
25
36
|
* Create a Request from a Route
|
|
26
37
|
*/
|
|
27
|
-
static fromRoute(route) {
|
|
38
|
+
static fromRoute(route, opts = {}) {
|
|
28
39
|
return new Request(route.url.href, route.site, {
|
|
29
40
|
scrollY: route.scrollY ?? undefined,
|
|
30
41
|
index: route.index,
|
|
31
42
|
origin: route.origin,
|
|
43
|
+
...opts,
|
|
32
44
|
});
|
|
33
45
|
}
|
|
34
46
|
/**
|
|
@@ -71,6 +83,7 @@ export default class Request extends Route {
|
|
|
71
83
|
index: this.index,
|
|
72
84
|
origin: this.origin,
|
|
73
85
|
disableScroll: this.disableScroll,
|
|
86
|
+
statusCode: this.statusCode ?? undefined,
|
|
74
87
|
});
|
|
75
88
|
}
|
|
76
89
|
/**
|
|
@@ -83,6 +96,14 @@ export default class Request extends Route {
|
|
|
83
96
|
origin: this.origin,
|
|
84
97
|
});
|
|
85
98
|
}
|
|
99
|
+
/** @hidden */
|
|
100
|
+
_updateOpts(opts = {}) {
|
|
101
|
+
this.scrollY = opts.scrollY ?? this.scrollY;
|
|
102
|
+
this.index = opts.index ?? this.index;
|
|
103
|
+
this.origin = opts.origin ?? this.origin;
|
|
104
|
+
this.disableScroll = opts.disableScroll ?? this.disableScroll;
|
|
105
|
+
this.statusCode = opts.statusCode ?? this.statusCode;
|
|
106
|
+
}
|
|
86
107
|
}
|
|
87
108
|
export function isRequest(req) {
|
|
88
109
|
return typeof req === 'object' && req !== null && req instanceof Request;
|