@tinkoff/router 0.5.116 → 0.5.198
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/lib/components/react/context.d.ts +1 -0
- package/lib/components/react/providers/transitions.browser.js +14 -3
- package/lib/components/react/providers/transitions.es.js +14 -3
- package/lib/components/react/providers/transitions.js +14 -3
- package/lib/components/react/useViewTransition.browser.js +9 -3
- package/lib/components/react/useViewTransition.d.ts +6 -1
- package/lib/components/react/useViewTransition.es.js +9 -3
- package/lib/components/react/useViewTransition.js +9 -3
- package/lib/history/base.browser.js +3 -0
- package/lib/history/base.d.ts +14 -1
- package/lib/history/base.es.js +3 -0
- package/lib/history/base.js +3 -0
- package/lib/history/client.browser.js +22 -2
- package/lib/history/client.d.ts +4 -8
- package/lib/history/client.es.js +22 -2
- package/lib/history/client.js +22 -2
- package/lib/history/server.d.ts +1 -0
- package/lib/history/server.es.js +7 -0
- package/lib/history/server.js +7 -0
- package/lib/history/wrapper.browser.js +8 -3
- package/lib/history/wrapper.d.ts +2 -1
- package/lib/history/wrapper.es.js +8 -3
- package/lib/history/wrapper.js +8 -3
- package/lib/router/abstract.browser.js +38 -13
- package/lib/router/abstract.d.ts +1 -0
- package/lib/router/abstract.es.js +38 -13
- package/lib/router/abstract.js +38 -13
- package/lib/router/browser.browser.js +67 -26
- package/lib/router/browser.d.ts +3 -1
- package/lib/router/client.browser.js +8 -3
- package/lib/router/client.d.ts +1 -0
- package/lib/router/client.es.js +8 -3
- package/lib/router/client.js +8 -3
- package/lib/router/constants.browser.js +6 -0
- package/lib/router/constants.d.ts +5 -0
- package/lib/router/constants.es.js +6 -0
- package/lib/router/constants.js +10 -0
- package/lib/router/server.es.js +3 -1
- package/lib/router/server.js +3 -1
- package/lib/tree/tree.browser.js +1 -0
- package/lib/tree/tree.es.js +1 -0
- package/lib/tree/tree.js +1 -0
- package/lib/types.d.ts +17 -1
- package/package.json +4 -4
|
@@ -7,16 +7,33 @@ import { logger } from '../logger.browser.js';
|
|
|
7
7
|
import { makeNavigateOptions, normalizeManySlashes, normalizeTrailingSlash, isSameHost } from '../utils.browser.js';
|
|
8
8
|
|
|
9
9
|
class AbstractRouter {
|
|
10
|
+
started = false;
|
|
11
|
+
trailingSlash = false;
|
|
12
|
+
strictTrailingSlash = true;
|
|
13
|
+
viewTransitionsEnabled = false;
|
|
14
|
+
mergeSlashes = false;
|
|
15
|
+
currentNavigation;
|
|
16
|
+
lastNavigation;
|
|
17
|
+
history;
|
|
18
|
+
tree;
|
|
19
|
+
guards;
|
|
20
|
+
hooks;
|
|
21
|
+
syncHooks;
|
|
22
|
+
navigateHook;
|
|
23
|
+
updateHook;
|
|
24
|
+
runNavigateHook;
|
|
25
|
+
runUpdateHook;
|
|
26
|
+
redirectHook;
|
|
27
|
+
notfoundHook;
|
|
28
|
+
blockHook;
|
|
29
|
+
hooksFactory;
|
|
30
|
+
plugins;
|
|
31
|
+
currentUuid;
|
|
32
|
+
hooksIndex = 0;
|
|
33
|
+
syncHooksIndex = 0;
|
|
34
|
+
guardsIndex = 0;
|
|
10
35
|
// eslint-disable-next-line max-statements
|
|
11
36
|
constructor({ trailingSlash, mergeSlashes, enableViewTransitions, beforeResolve = [], beforeNavigate = [], afterNavigate = [], beforeUpdateCurrent = [], afterUpdateCurrent = [], guards = [], onChange = [], onRedirect, onNotFound, onBlock, hooksFactory, plugins, }) {
|
|
12
|
-
this.started = false;
|
|
13
|
-
this.trailingSlash = false;
|
|
14
|
-
this.strictTrailingSlash = true;
|
|
15
|
-
this.viewTransitionsEnabled = false;
|
|
16
|
-
this.mergeSlashes = false;
|
|
17
|
-
this.hooksIndex = 0;
|
|
18
|
-
this.syncHooksIndex = 0;
|
|
19
|
-
this.guardsIndex = 0;
|
|
20
37
|
this.trailingSlash = trailingSlash ?? false;
|
|
21
38
|
this.strictTrailingSlash = typeof trailingSlash === 'undefined';
|
|
22
39
|
this.mergeSlashes = mergeSlashes ?? false;
|
|
@@ -85,6 +102,9 @@ class AbstractRouter {
|
|
|
85
102
|
plugin.apply(this);
|
|
86
103
|
});
|
|
87
104
|
}
|
|
105
|
+
onRedirect;
|
|
106
|
+
onNotFound;
|
|
107
|
+
onBlock;
|
|
88
108
|
// start is using as marker that any preparation for proper work has done in the app
|
|
89
109
|
// and now router can manage any navigations
|
|
90
110
|
async start() {
|
|
@@ -157,7 +177,7 @@ class AbstractRouter {
|
|
|
157
177
|
await this.navigateHook.callPromise({ navigateOptions });
|
|
158
178
|
}
|
|
159
179
|
async internalNavigate(navigateOptions, { history, redirect }) {
|
|
160
|
-
const { url, replace, params, navigateState, code, viewTransition } = navigateOptions;
|
|
180
|
+
const { url, replace, params, navigateState, code, isBack, viewTransition, viewTransitionTypes, hasUAVisualTransition, } = navigateOptions;
|
|
161
181
|
const prevNavigation = redirect
|
|
162
182
|
? this.lastNavigation
|
|
163
183
|
: (this.currentNavigation ?? this.lastNavigation);
|
|
@@ -166,7 +186,7 @@ class AbstractRouter {
|
|
|
166
186
|
}
|
|
167
187
|
const resolvedUrl = this.resolveUrl(navigateOptions);
|
|
168
188
|
const { to: from, url: fromUrl } = prevNavigation ?? {};
|
|
169
|
-
const redirectFrom = redirect ? this.
|
|
189
|
+
const redirectFrom = redirect ? this.getCurrentRoute() : undefined;
|
|
170
190
|
let navigation = {
|
|
171
191
|
type: 'navigate',
|
|
172
192
|
from,
|
|
@@ -178,10 +198,13 @@ class AbstractRouter {
|
|
|
178
198
|
code,
|
|
179
199
|
redirect,
|
|
180
200
|
redirectFrom,
|
|
201
|
+
isBack,
|
|
202
|
+
hasUAVisualTransition,
|
|
181
203
|
key: this.uuid(),
|
|
182
204
|
};
|
|
183
|
-
if (this.viewTransitionsEnabled && viewTransition !== undefined) {
|
|
205
|
+
if (this.viewTransitionsEnabled && viewTransition !== undefined && !hasUAVisualTransition) {
|
|
184
206
|
navigation.viewTransition = viewTransition;
|
|
207
|
+
navigation.viewTransitionTypes = viewTransitionTypes;
|
|
185
208
|
}
|
|
186
209
|
await this.runHooks('beforeResolve', navigation);
|
|
187
210
|
const to = this.resolveRoute({ url: resolvedUrl, params, navigateState }, { wildcard: true });
|
|
@@ -238,6 +261,7 @@ class AbstractRouter {
|
|
|
238
261
|
async rehydrate(navigation) {
|
|
239
262
|
throw new Error('Not implemented');
|
|
240
263
|
}
|
|
264
|
+
unsubscribe() { }
|
|
241
265
|
addRoute(route) {
|
|
242
266
|
this.tree?.addRoute(route);
|
|
243
267
|
}
|
|
@@ -356,10 +380,11 @@ class AbstractRouter {
|
|
|
356
380
|
}
|
|
357
381
|
}
|
|
358
382
|
registerGuard(guard) {
|
|
359
|
-
const
|
|
383
|
+
const index = this.guardsIndex++;
|
|
384
|
+
const untap = this.guards.tapPromise(guard.name ?? `guard-${index}`, async (_, { allResults, navigation }) => {
|
|
360
385
|
try {
|
|
361
386
|
const result = await guard(navigation);
|
|
362
|
-
allResults
|
|
387
|
+
allResults[index] = result;
|
|
363
388
|
}
|
|
364
389
|
catch (error) {
|
|
365
390
|
logger.warn({
|
package/lib/router/abstract.d.ts
CHANGED
|
@@ -98,6 +98,7 @@ export declare abstract class AbstractRouter {
|
|
|
98
98
|
isNavigating(): boolean;
|
|
99
99
|
dehydrate(): Promise<Navigation>;
|
|
100
100
|
rehydrate(navigation: Partial<Navigation>): Promise<void>;
|
|
101
|
+
unsubscribe(): void;
|
|
101
102
|
addRoute(route: Route): void;
|
|
102
103
|
protected redirect(navigation: Navigation, target: NavigateOptions): Promise<void>;
|
|
103
104
|
protected notfound(navigation: Navigation): Promise<void>;
|
|
@@ -7,16 +7,33 @@ import { logger } from '../logger.es.js';
|
|
|
7
7
|
import { makeNavigateOptions, normalizeManySlashes, normalizeTrailingSlash, isSameHost } from '../utils.es.js';
|
|
8
8
|
|
|
9
9
|
class AbstractRouter {
|
|
10
|
+
started = false;
|
|
11
|
+
trailingSlash = false;
|
|
12
|
+
strictTrailingSlash = true;
|
|
13
|
+
viewTransitionsEnabled = false;
|
|
14
|
+
mergeSlashes = false;
|
|
15
|
+
currentNavigation;
|
|
16
|
+
lastNavigation;
|
|
17
|
+
history;
|
|
18
|
+
tree;
|
|
19
|
+
guards;
|
|
20
|
+
hooks;
|
|
21
|
+
syncHooks;
|
|
22
|
+
navigateHook;
|
|
23
|
+
updateHook;
|
|
24
|
+
runNavigateHook;
|
|
25
|
+
runUpdateHook;
|
|
26
|
+
redirectHook;
|
|
27
|
+
notfoundHook;
|
|
28
|
+
blockHook;
|
|
29
|
+
hooksFactory;
|
|
30
|
+
plugins;
|
|
31
|
+
currentUuid;
|
|
32
|
+
hooksIndex = 0;
|
|
33
|
+
syncHooksIndex = 0;
|
|
34
|
+
guardsIndex = 0;
|
|
10
35
|
// eslint-disable-next-line max-statements
|
|
11
36
|
constructor({ trailingSlash, mergeSlashes, enableViewTransitions, beforeResolve = [], beforeNavigate = [], afterNavigate = [], beforeUpdateCurrent = [], afterUpdateCurrent = [], guards = [], onChange = [], onRedirect, onNotFound, onBlock, hooksFactory, plugins, }) {
|
|
12
|
-
this.started = false;
|
|
13
|
-
this.trailingSlash = false;
|
|
14
|
-
this.strictTrailingSlash = true;
|
|
15
|
-
this.viewTransitionsEnabled = false;
|
|
16
|
-
this.mergeSlashes = false;
|
|
17
|
-
this.hooksIndex = 0;
|
|
18
|
-
this.syncHooksIndex = 0;
|
|
19
|
-
this.guardsIndex = 0;
|
|
20
37
|
this.trailingSlash = trailingSlash ?? false;
|
|
21
38
|
this.strictTrailingSlash = typeof trailingSlash === 'undefined';
|
|
22
39
|
this.mergeSlashes = mergeSlashes ?? false;
|
|
@@ -85,6 +102,9 @@ class AbstractRouter {
|
|
|
85
102
|
plugin.apply(this);
|
|
86
103
|
});
|
|
87
104
|
}
|
|
105
|
+
onRedirect;
|
|
106
|
+
onNotFound;
|
|
107
|
+
onBlock;
|
|
88
108
|
// start is using as marker that any preparation for proper work has done in the app
|
|
89
109
|
// and now router can manage any navigations
|
|
90
110
|
async start() {
|
|
@@ -157,7 +177,7 @@ class AbstractRouter {
|
|
|
157
177
|
await this.navigateHook.callPromise({ navigateOptions });
|
|
158
178
|
}
|
|
159
179
|
async internalNavigate(navigateOptions, { history, redirect }) {
|
|
160
|
-
const { url, replace, params, navigateState, code, viewTransition } = navigateOptions;
|
|
180
|
+
const { url, replace, params, navigateState, code, isBack, viewTransition, viewTransitionTypes, hasUAVisualTransition, } = navigateOptions;
|
|
161
181
|
const prevNavigation = redirect
|
|
162
182
|
? this.lastNavigation
|
|
163
183
|
: (this.currentNavigation ?? this.lastNavigation);
|
|
@@ -166,7 +186,7 @@ class AbstractRouter {
|
|
|
166
186
|
}
|
|
167
187
|
const resolvedUrl = this.resolveUrl(navigateOptions);
|
|
168
188
|
const { to: from, url: fromUrl } = prevNavigation ?? {};
|
|
169
|
-
const redirectFrom = redirect ? this.
|
|
189
|
+
const redirectFrom = redirect ? this.getCurrentRoute() : undefined;
|
|
170
190
|
let navigation = {
|
|
171
191
|
type: 'navigate',
|
|
172
192
|
from,
|
|
@@ -178,10 +198,13 @@ class AbstractRouter {
|
|
|
178
198
|
code,
|
|
179
199
|
redirect,
|
|
180
200
|
redirectFrom,
|
|
201
|
+
isBack,
|
|
202
|
+
hasUAVisualTransition,
|
|
181
203
|
key: this.uuid(),
|
|
182
204
|
};
|
|
183
|
-
if (this.viewTransitionsEnabled && viewTransition !== undefined) {
|
|
205
|
+
if (this.viewTransitionsEnabled && viewTransition !== undefined && !hasUAVisualTransition) {
|
|
184
206
|
navigation.viewTransition = viewTransition;
|
|
207
|
+
navigation.viewTransitionTypes = viewTransitionTypes;
|
|
185
208
|
}
|
|
186
209
|
await this.runHooks('beforeResolve', navigation);
|
|
187
210
|
const to = this.resolveRoute({ url: resolvedUrl, params, navigateState }, { wildcard: true });
|
|
@@ -238,6 +261,7 @@ class AbstractRouter {
|
|
|
238
261
|
async rehydrate(navigation) {
|
|
239
262
|
throw new Error('Not implemented');
|
|
240
263
|
}
|
|
264
|
+
unsubscribe() { }
|
|
241
265
|
addRoute(route) {
|
|
242
266
|
this.tree?.addRoute(route);
|
|
243
267
|
}
|
|
@@ -356,10 +380,11 @@ class AbstractRouter {
|
|
|
356
380
|
}
|
|
357
381
|
}
|
|
358
382
|
registerGuard(guard) {
|
|
359
|
-
const
|
|
383
|
+
const index = this.guardsIndex++;
|
|
384
|
+
const untap = this.guards.tapPromise(guard.name ?? `guard-${index}`, async (_, { allResults, navigation }) => {
|
|
360
385
|
try {
|
|
361
386
|
const result = await guard(navigation);
|
|
362
|
-
allResults
|
|
387
|
+
allResults[index] = result;
|
|
363
388
|
}
|
|
364
389
|
catch (error) {
|
|
365
390
|
logger.warn({
|
package/lib/router/abstract.js
CHANGED
|
@@ -16,16 +16,33 @@ var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
|
|
|
16
16
|
var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
|
|
17
17
|
|
|
18
18
|
class AbstractRouter {
|
|
19
|
+
started = false;
|
|
20
|
+
trailingSlash = false;
|
|
21
|
+
strictTrailingSlash = true;
|
|
22
|
+
viewTransitionsEnabled = false;
|
|
23
|
+
mergeSlashes = false;
|
|
24
|
+
currentNavigation;
|
|
25
|
+
lastNavigation;
|
|
26
|
+
history;
|
|
27
|
+
tree;
|
|
28
|
+
guards;
|
|
29
|
+
hooks;
|
|
30
|
+
syncHooks;
|
|
31
|
+
navigateHook;
|
|
32
|
+
updateHook;
|
|
33
|
+
runNavigateHook;
|
|
34
|
+
runUpdateHook;
|
|
35
|
+
redirectHook;
|
|
36
|
+
notfoundHook;
|
|
37
|
+
blockHook;
|
|
38
|
+
hooksFactory;
|
|
39
|
+
plugins;
|
|
40
|
+
currentUuid;
|
|
41
|
+
hooksIndex = 0;
|
|
42
|
+
syncHooksIndex = 0;
|
|
43
|
+
guardsIndex = 0;
|
|
19
44
|
// eslint-disable-next-line max-statements
|
|
20
45
|
constructor({ trailingSlash, mergeSlashes, enableViewTransitions, beforeResolve = [], beforeNavigate = [], afterNavigate = [], beforeUpdateCurrent = [], afterUpdateCurrent = [], guards = [], onChange = [], onRedirect, onNotFound, onBlock, hooksFactory, plugins, }) {
|
|
21
|
-
this.started = false;
|
|
22
|
-
this.trailingSlash = false;
|
|
23
|
-
this.strictTrailingSlash = true;
|
|
24
|
-
this.viewTransitionsEnabled = false;
|
|
25
|
-
this.mergeSlashes = false;
|
|
26
|
-
this.hooksIndex = 0;
|
|
27
|
-
this.syncHooksIndex = 0;
|
|
28
|
-
this.guardsIndex = 0;
|
|
29
46
|
this.trailingSlash = trailingSlash ?? false;
|
|
30
47
|
this.strictTrailingSlash = typeof trailingSlash === 'undefined';
|
|
31
48
|
this.mergeSlashes = mergeSlashes ?? false;
|
|
@@ -94,6 +111,9 @@ class AbstractRouter {
|
|
|
94
111
|
plugin.apply(this);
|
|
95
112
|
});
|
|
96
113
|
}
|
|
114
|
+
onRedirect;
|
|
115
|
+
onNotFound;
|
|
116
|
+
onBlock;
|
|
97
117
|
// start is using as marker that any preparation for proper work has done in the app
|
|
98
118
|
// and now router can manage any navigations
|
|
99
119
|
async start() {
|
|
@@ -166,7 +186,7 @@ class AbstractRouter {
|
|
|
166
186
|
await this.navigateHook.callPromise({ navigateOptions });
|
|
167
187
|
}
|
|
168
188
|
async internalNavigate(navigateOptions, { history, redirect }) {
|
|
169
|
-
const { url, replace, params, navigateState, code, viewTransition } = navigateOptions;
|
|
189
|
+
const { url, replace, params, navigateState, code, isBack, viewTransition, viewTransitionTypes, hasUAVisualTransition, } = navigateOptions;
|
|
170
190
|
const prevNavigation = redirect
|
|
171
191
|
? this.lastNavigation
|
|
172
192
|
: (this.currentNavigation ?? this.lastNavigation);
|
|
@@ -175,7 +195,7 @@ class AbstractRouter {
|
|
|
175
195
|
}
|
|
176
196
|
const resolvedUrl = this.resolveUrl(navigateOptions);
|
|
177
197
|
const { to: from, url: fromUrl } = prevNavigation ?? {};
|
|
178
|
-
const redirectFrom = redirect ? this.
|
|
198
|
+
const redirectFrom = redirect ? this.getCurrentRoute() : undefined;
|
|
179
199
|
let navigation = {
|
|
180
200
|
type: 'navigate',
|
|
181
201
|
from,
|
|
@@ -187,10 +207,13 @@ class AbstractRouter {
|
|
|
187
207
|
code,
|
|
188
208
|
redirect,
|
|
189
209
|
redirectFrom,
|
|
210
|
+
isBack,
|
|
211
|
+
hasUAVisualTransition,
|
|
190
212
|
key: this.uuid(),
|
|
191
213
|
};
|
|
192
|
-
if (this.viewTransitionsEnabled && viewTransition !== undefined) {
|
|
214
|
+
if (this.viewTransitionsEnabled && viewTransition !== undefined && !hasUAVisualTransition) {
|
|
193
215
|
navigation.viewTransition = viewTransition;
|
|
216
|
+
navigation.viewTransitionTypes = viewTransitionTypes;
|
|
194
217
|
}
|
|
195
218
|
await this.runHooks('beforeResolve', navigation);
|
|
196
219
|
const to = this.resolveRoute({ url: resolvedUrl, params, navigateState }, { wildcard: true });
|
|
@@ -247,6 +270,7 @@ class AbstractRouter {
|
|
|
247
270
|
async rehydrate(navigation) {
|
|
248
271
|
throw new Error('Not implemented');
|
|
249
272
|
}
|
|
273
|
+
unsubscribe() { }
|
|
250
274
|
addRoute(route) {
|
|
251
275
|
this.tree?.addRoute(route);
|
|
252
276
|
}
|
|
@@ -365,10 +389,11 @@ class AbstractRouter {
|
|
|
365
389
|
}
|
|
366
390
|
}
|
|
367
391
|
registerGuard(guard) {
|
|
368
|
-
const
|
|
392
|
+
const index = this.guardsIndex++;
|
|
393
|
+
const untap = this.guards.tapPromise(guard.name ?? `guard-${index}`, async (_, { allResults, navigation }) => {
|
|
369
394
|
try {
|
|
370
395
|
const result = await guard(navigation);
|
|
371
|
-
allResults
|
|
396
|
+
allResults[index] = result;
|
|
372
397
|
}
|
|
373
398
|
catch (error) {
|
|
374
399
|
logger.logger.warn({
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { ClientRouter } from './client.browser.js';
|
|
2
2
|
import { logger } from '../logger.browser.js';
|
|
3
3
|
import { RouteTree } from '../tree/tree.browser.js';
|
|
4
|
+
import { NAVIGATION_TYPE } from './constants.browser.js';
|
|
4
5
|
|
|
5
6
|
const DELAY_CHECK_INTERVAL = 50;
|
|
6
7
|
const APPLIED_VIEW_TRANSITIONS_KEY = '_t_view_transitions';
|
|
7
8
|
class Router extends ClientRouter {
|
|
9
|
+
delayedNavigation;
|
|
10
|
+
delayedPromise;
|
|
11
|
+
delayedResolve;
|
|
12
|
+
delayedReject;
|
|
13
|
+
// Store applied view transitions, so we can apply them on back navigations
|
|
14
|
+
appliedViewTransitions;
|
|
8
15
|
constructor(options) {
|
|
9
16
|
super(options);
|
|
10
17
|
this.tree = new RouteTree(options.routes);
|
|
@@ -29,8 +36,22 @@ class Router extends ClientRouter {
|
|
|
29
36
|
}
|
|
30
37
|
async run(payload) {
|
|
31
38
|
const navigation = { ...payload };
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
const to = (navigation.to.redirect !== undefined
|
|
40
|
+
? this.resolve(navigation.to.redirect)?.actualPath
|
|
41
|
+
: navigation.to?.actualPath) ?? '';
|
|
42
|
+
const from = navigation.from?.actualPath ?? '';
|
|
43
|
+
if (this.viewTransitionsEnabled && to !== from && !navigation.hasUAVisualTransition) {
|
|
44
|
+
navigation.viewTransition = this.shouldApplyViewTransition(navigation, to);
|
|
45
|
+
const hasNavigationType = !!navigation.viewTransitionTypes &&
|
|
46
|
+
navigation.viewTransitionTypes.some((type) => Object.values(NAVIGATION_TYPE).includes(type));
|
|
47
|
+
// add a navigation type only if it has not been provided
|
|
48
|
+
if (navigation.viewTransition && !hasNavigationType) {
|
|
49
|
+
const navigationType = this.getNavigationType(navigation);
|
|
50
|
+
// add a navigation type to transition types
|
|
51
|
+
navigation.viewTransitionTypes = navigation.viewTransitionTypes
|
|
52
|
+
? [...(navigation.viewTransitionTypes ?? []), navigationType]
|
|
53
|
+
: [navigationType];
|
|
54
|
+
}
|
|
34
55
|
}
|
|
35
56
|
// if router is not started yet delay current navigation without blocking promise resolving
|
|
36
57
|
if (!this.started) {
|
|
@@ -169,39 +190,59 @@ class Router extends ClientRouter {
|
|
|
169
190
|
this.delayedReject = null;
|
|
170
191
|
});
|
|
171
192
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
getNavigationType(navigation) {
|
|
194
|
+
// if it is back navigation
|
|
195
|
+
if (navigation.history && navigation.isBack) {
|
|
196
|
+
return NAVIGATION_TYPE.BACK;
|
|
197
|
+
}
|
|
198
|
+
return NAVIGATION_TYPE.FORWARD;
|
|
199
|
+
}
|
|
200
|
+
shouldApplyViewTransition(navigation, to) {
|
|
201
|
+
const from = navigation.from?.actualPath ?? '';
|
|
202
|
+
const historyState = this.history.getCurrentState();
|
|
203
|
+
if (!historyState) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
const historyIndex = historyState.index;
|
|
207
|
+
const prevTransitionFrom = this.getPrevTransition(navigation);
|
|
208
|
+
// handle back navigation when prev navigation was with VT enabled
|
|
209
|
+
if (navigation.history && prevTransitionFrom === to) {
|
|
186
210
|
return true;
|
|
187
211
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (priorPaths !== undefined && priorPaths.has(to)) {
|
|
212
|
+
if (navigation.viewTransition) {
|
|
213
|
+
// add transition except history navigations with VT enabled
|
|
214
|
+
!navigation.history && this.appliedViewTransitions.set(historyIndex, from);
|
|
192
215
|
return true;
|
|
193
216
|
}
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
217
|
+
// handle forward navigation
|
|
218
|
+
if (navigation.history && !navigation.isBack) {
|
|
219
|
+
// returns true if prev navigation was with VT enabled
|
|
220
|
+
return !!prevTransitionFrom;
|
|
221
|
+
}
|
|
222
|
+
// if we have forward navigation without VT enabled and stored val for this index
|
|
223
|
+
if (!navigation.history && this.appliedViewTransitions.has(historyIndex)) {
|
|
224
|
+
this.appliedViewTransitions.delete(historyIndex);
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
getPrevTransition(navigation) {
|
|
229
|
+
const historyState = this.history.getCurrentState();
|
|
230
|
+
if (!historyState) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
const historyIndex = historyState.index;
|
|
234
|
+
const index = navigation.history && navigation.isBack ? historyIndex : historyIndex - 1;
|
|
235
|
+
return this.appliedViewTransitions.get(index);
|
|
198
236
|
}
|
|
199
237
|
restoreAppliedViewTransitions() {
|
|
200
238
|
try {
|
|
201
239
|
const valueFromStorage = sessionStorage.getItem(APPLIED_VIEW_TRANSITIONS_KEY);
|
|
202
240
|
if (valueFromStorage !== null) {
|
|
203
241
|
const parsedValue = JSON.parse(valueFromStorage);
|
|
204
|
-
this.appliedViewTransitions = new Map(Object.entries(parsedValue).map(([key, value]) => [
|
|
242
|
+
this.appliedViewTransitions = new Map(Object.entries(parsedValue).map(([key, value]) => [
|
|
243
|
+
Number.parseInt(key, 10),
|
|
244
|
+
value,
|
|
245
|
+
]));
|
|
205
246
|
return;
|
|
206
247
|
}
|
|
207
248
|
this.appliedViewTransitions = new Map();
|
|
@@ -215,7 +256,7 @@ class Router extends ClientRouter {
|
|
|
215
256
|
try {
|
|
216
257
|
const valueToSave = {};
|
|
217
258
|
for (const [key, value] of this.appliedViewTransitions) {
|
|
218
|
-
valueToSave[key] =
|
|
259
|
+
valueToSave[key] = value;
|
|
219
260
|
}
|
|
220
261
|
sessionStorage.setItem(APPLIED_VIEW_TRANSITIONS_KEY, JSON.stringify(valueToSave));
|
|
221
262
|
}
|
package/lib/router/browser.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Options } from './abstract';
|
|
2
2
|
import { ClientRouter } from './client';
|
|
3
|
-
import type {
|
|
3
|
+
import type { HookName, Navigation } from '../types';
|
|
4
4
|
export declare class Router extends ClientRouter {
|
|
5
5
|
protected delayedNavigation: Navigation;
|
|
6
6
|
protected delayedPromise: Promise<void>;
|
|
@@ -17,7 +17,9 @@ export declare class Router extends ClientRouter {
|
|
|
17
17
|
protected runHooks(hookName: HookName, navigation: Navigation): Promise<void>;
|
|
18
18
|
private resolveIfDelayFound;
|
|
19
19
|
private flattenDelayedNavigation;
|
|
20
|
+
private getNavigationType;
|
|
20
21
|
private shouldApplyViewTransition;
|
|
22
|
+
private getPrevTransition;
|
|
21
23
|
private restoreAppliedViewTransitions;
|
|
22
24
|
private saveAppliedViewTransitions;
|
|
23
25
|
cancel(): Navigation;
|
|
@@ -5,12 +5,12 @@ import { logger } from '../logger.browser.js';
|
|
|
5
5
|
import { ClientHistory } from '../history/client.browser.js';
|
|
6
6
|
|
|
7
7
|
class ClientRouter extends AbstractRouter {
|
|
8
|
+
// this flag for cases when we don't have initial router state from server - CSR fallback initialization
|
|
9
|
+
fullRehydrationInProcess = null;
|
|
8
10
|
constructor(options) {
|
|
9
11
|
super(options);
|
|
10
|
-
// this flag for cases when we don't have initial router state from server - CSR fallback initialization
|
|
11
|
-
this.fullRehydrationInProcess = null;
|
|
12
12
|
this.history = new ClientHistory();
|
|
13
|
-
this.history.listen(async ({ type, url, navigateState, replace, history }) => {
|
|
13
|
+
this.history.listen(async ({ type, url, navigateState, replace, history, hasUAVisualTransition, ...rest }) => {
|
|
14
14
|
const currentUrl = this.getCurrentUrl();
|
|
15
15
|
const { pathname, query, hash } = this.resolveUrl({ url });
|
|
16
16
|
const isSameUrlNavigation = (currentUrl ? currentUrl.pathname : window.location.pathname) === pathname;
|
|
@@ -47,6 +47,8 @@ class ClientRouter extends AbstractRouter {
|
|
|
47
47
|
url,
|
|
48
48
|
replace,
|
|
49
49
|
navigateState,
|
|
50
|
+
hasUAVisualTransition,
|
|
51
|
+
...rest,
|
|
50
52
|
}, { history });
|
|
51
53
|
}
|
|
52
54
|
});
|
|
@@ -146,6 +148,9 @@ class ClientRouter extends AbstractRouter {
|
|
|
146
148
|
redirect: true,
|
|
147
149
|
});
|
|
148
150
|
}
|
|
151
|
+
unsubscribe() {
|
|
152
|
+
this.history.unsubscribe();
|
|
153
|
+
}
|
|
149
154
|
}
|
|
150
155
|
|
|
151
156
|
export { ClientRouter };
|
package/lib/router/client.d.ts
CHANGED
|
@@ -9,5 +9,6 @@ export declare abstract class ClientRouter extends AbstractRouter {
|
|
|
9
9
|
protected notfound(navigation: Navigation): Promise<void>;
|
|
10
10
|
protected block(navigation: Navigation): Promise<void>;
|
|
11
11
|
protected redirect(navigation: Navigation, target: NavigateOptions): Promise<void>;
|
|
12
|
+
unsubscribe(): void;
|
|
12
13
|
}
|
|
13
14
|
//# sourceMappingURL=client.d.ts.map
|
package/lib/router/client.es.js
CHANGED
|
@@ -5,12 +5,12 @@ import { logger } from '../logger.es.js';
|
|
|
5
5
|
import { ClientHistory } from '../history/client.es.js';
|
|
6
6
|
|
|
7
7
|
class ClientRouter extends AbstractRouter {
|
|
8
|
+
// this flag for cases when we don't have initial router state from server - CSR fallback initialization
|
|
9
|
+
fullRehydrationInProcess = null;
|
|
8
10
|
constructor(options) {
|
|
9
11
|
super(options);
|
|
10
|
-
// this flag for cases when we don't have initial router state from server - CSR fallback initialization
|
|
11
|
-
this.fullRehydrationInProcess = null;
|
|
12
12
|
this.history = new ClientHistory();
|
|
13
|
-
this.history.listen(async ({ type, url, navigateState, replace, history }) => {
|
|
13
|
+
this.history.listen(async ({ type, url, navigateState, replace, history, hasUAVisualTransition, ...rest }) => {
|
|
14
14
|
const currentUrl = this.getCurrentUrl();
|
|
15
15
|
const { pathname, query, hash } = this.resolveUrl({ url });
|
|
16
16
|
const isSameUrlNavigation = (currentUrl ? currentUrl.pathname : window.location.pathname) === pathname;
|
|
@@ -47,6 +47,8 @@ class ClientRouter extends AbstractRouter {
|
|
|
47
47
|
url,
|
|
48
48
|
replace,
|
|
49
49
|
navigateState,
|
|
50
|
+
hasUAVisualTransition,
|
|
51
|
+
...rest,
|
|
50
52
|
}, { history });
|
|
51
53
|
}
|
|
52
54
|
});
|
|
@@ -146,6 +148,9 @@ class ClientRouter extends AbstractRouter {
|
|
|
146
148
|
redirect: true,
|
|
147
149
|
});
|
|
148
150
|
}
|
|
151
|
+
unsubscribe() {
|
|
152
|
+
this.history.unsubscribe();
|
|
153
|
+
}
|
|
149
154
|
}
|
|
150
155
|
|
|
151
156
|
export { ClientRouter };
|
package/lib/router/client.js
CHANGED
|
@@ -9,12 +9,12 @@ var logger = require('../logger.js');
|
|
|
9
9
|
var client = require('../history/client.js');
|
|
10
10
|
|
|
11
11
|
class ClientRouter extends abstract.AbstractRouter {
|
|
12
|
+
// this flag for cases when we don't have initial router state from server - CSR fallback initialization
|
|
13
|
+
fullRehydrationInProcess = null;
|
|
12
14
|
constructor(options) {
|
|
13
15
|
super(options);
|
|
14
|
-
// this flag for cases when we don't have initial router state from server - CSR fallback initialization
|
|
15
|
-
this.fullRehydrationInProcess = null;
|
|
16
16
|
this.history = new client.ClientHistory();
|
|
17
|
-
this.history.listen(async ({ type, url, navigateState, replace, history }) => {
|
|
17
|
+
this.history.listen(async ({ type, url, navigateState, replace, history, hasUAVisualTransition, ...rest }) => {
|
|
18
18
|
const currentUrl = this.getCurrentUrl();
|
|
19
19
|
const { pathname, query, hash } = this.resolveUrl({ url });
|
|
20
20
|
const isSameUrlNavigation = (currentUrl ? currentUrl.pathname : window.location.pathname) === pathname;
|
|
@@ -51,6 +51,8 @@ class ClientRouter extends abstract.AbstractRouter {
|
|
|
51
51
|
url,
|
|
52
52
|
replace,
|
|
53
53
|
navigateState,
|
|
54
|
+
hasUAVisualTransition,
|
|
55
|
+
...rest,
|
|
54
56
|
}, { history });
|
|
55
57
|
}
|
|
56
58
|
});
|
|
@@ -150,6 +152,9 @@ class ClientRouter extends abstract.AbstractRouter {
|
|
|
150
152
|
redirect: true,
|
|
151
153
|
});
|
|
152
154
|
}
|
|
155
|
+
unsubscribe() {
|
|
156
|
+
this.history.unsubscribe();
|
|
157
|
+
}
|
|
153
158
|
}
|
|
154
159
|
|
|
155
160
|
exports.ClientRouter = ClientRouter;
|
package/lib/router/server.es.js
CHANGED
|
@@ -5,9 +5,11 @@ import { RouteTree } from '../tree/tree.es.js';
|
|
|
5
5
|
import { logger } from '../logger.es.js';
|
|
6
6
|
|
|
7
7
|
class Router extends AbstractRouter {
|
|
8
|
+
defaultRedirectCode;
|
|
9
|
+
blocked = false;
|
|
10
|
+
redirectCode;
|
|
8
11
|
constructor(options) {
|
|
9
12
|
super(options);
|
|
10
|
-
this.blocked = false;
|
|
11
13
|
this.tree = new RouteTree(options.routes);
|
|
12
14
|
this.defaultRedirectCode = options.defaultRedirectCode ?? 308;
|
|
13
15
|
this.history = new ServerHistory();
|
package/lib/router/server.js
CHANGED
|
@@ -9,9 +9,11 @@ var tree = require('../tree/tree.js');
|
|
|
9
9
|
var logger = require('../logger.js');
|
|
10
10
|
|
|
11
11
|
class Router extends abstract.AbstractRouter {
|
|
12
|
+
defaultRedirectCode;
|
|
13
|
+
blocked = false;
|
|
14
|
+
redirectCode;
|
|
12
15
|
constructor(options) {
|
|
13
16
|
super(options);
|
|
14
|
-
this.blocked = false;
|
|
15
17
|
this.tree = new tree.RouteTree(options.routes);
|
|
16
18
|
this.defaultRedirectCode = options.defaultRedirectCode ?? 308;
|
|
17
19
|
this.history = new server.ServerHistory();
|