2016-06-23 12:47:54 -04:00
|
|
|
/**
|
|
|
|
* @license
|
2020-05-19 15:08:49 -04:00
|
|
|
* Copyright Google LLC All Rights Reserved.
|
2016-06-23 12:47:54 -04:00
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2018-02-27 17:06:06 -05:00
|
|
|
import {BehaviorSubject} from 'rxjs';
|
2016-06-08 14:13:41 -04:00
|
|
|
|
2016-11-30 02:21:41 -05:00
|
|
|
import {DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
|
2016-06-08 14:13:41 -04:00
|
|
|
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from './router_state';
|
|
|
|
import {TreeNode} from './utils/tree';
|
2016-06-01 16:29:28 -04:00
|
|
|
|
2016-11-30 02:21:41 -05:00
|
|
|
export function createRouterState(
|
|
|
|
routeReuseStrategy: RouteReuseStrategy, curr: RouterStateSnapshot,
|
|
|
|
prevState: RouterState): RouterState {
|
|
|
|
const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
|
2016-08-02 18:31:56 -04:00
|
|
|
return new RouterState(root, curr);
|
2016-06-01 16:29:28 -04:00
|
|
|
}
|
|
|
|
|
2016-11-30 02:21:41 -05:00
|
|
|
function createNode(
|
|
|
|
routeReuseStrategy: RouteReuseStrategy, curr: TreeNode<ActivatedRouteSnapshot>,
|
|
|
|
prevState?: TreeNode<ActivatedRoute>): TreeNode<ActivatedRoute> {
|
|
|
|
// reuse an activated route that is currently displayed on the screen
|
|
|
|
if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
|
2016-06-01 16:29:28 -04:00
|
|
|
const value = prevState.value;
|
2016-06-02 17:44:57 -04:00
|
|
|
value._futureSnapshot = curr.value;
|
2016-11-30 02:21:41 -05:00
|
|
|
const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
|
2016-06-01 16:29:28 -04:00
|
|
|
return new TreeNode<ActivatedRoute>(value, children);
|
|
|
|
} else {
|
2019-05-04 14:18:14 -04:00
|
|
|
if (routeReuseStrategy.shouldAttach(curr.value)) {
|
|
|
|
// retrieve an activated route that is used to be displayed, but is not currently displayed
|
|
|
|
const detachedRouteHandle = routeReuseStrategy.retrieve(curr.value);
|
|
|
|
if (detachedRouteHandle !== null) {
|
|
|
|
const tree = (detachedRouteHandle as DetachedRouteHandleInternal).route;
|
|
|
|
setFutureSnapshotsOfActivatedRoutes(curr, tree);
|
|
|
|
return tree;
|
|
|
|
}
|
2018-02-27 09:04:36 -05:00
|
|
|
}
|
2019-05-04 14:18:14 -04:00
|
|
|
|
|
|
|
const value = createActivatedRoute(curr.value);
|
|
|
|
const children = curr.children.map(c => createNode(routeReuseStrategy, c));
|
|
|
|
return new TreeNode<ActivatedRoute>(value, children);
|
2016-06-01 16:29:28 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-30 02:21:41 -05:00
|
|
|
function setFutureSnapshotsOfActivatedRoutes(
|
|
|
|
curr: TreeNode<ActivatedRouteSnapshot>, result: TreeNode<ActivatedRoute>): void {
|
|
|
|
if (curr.value.routeConfig !== result.value.routeConfig) {
|
|
|
|
throw new Error('Cannot reattach ActivatedRouteSnapshot created from a different route');
|
|
|
|
}
|
|
|
|
if (curr.children.length !== result.children.length) {
|
|
|
|
throw new Error('Cannot reattach ActivatedRouteSnapshot with a different number of children');
|
|
|
|
}
|
|
|
|
result.value._futureSnapshot = curr.value;
|
|
|
|
for (let i = 0; i < curr.children.length; ++i) {
|
|
|
|
setFutureSnapshotsOfActivatedRoutes(curr.children[i], result.children[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-08 14:13:41 -04:00
|
|
|
function createOrReuseChildren(
|
2016-11-30 02:21:41 -05:00
|
|
|
routeReuseStrategy: RouteReuseStrategy, curr: TreeNode<ActivatedRouteSnapshot>,
|
|
|
|
prevState: TreeNode<ActivatedRoute>) {
|
2016-06-01 16:29:28 -04:00
|
|
|
return curr.children.map(child => {
|
2016-06-24 18:37:46 -04:00
|
|
|
for (const p of prevState.children) {
|
2018-09-25 11:18:31 -04:00
|
|
|
if (routeReuseStrategy.shouldReuseRoute(child.value, p.value.snapshot)) {
|
2016-11-30 02:21:41 -05:00
|
|
|
return createNode(routeReuseStrategy, child, p);
|
2016-06-24 18:37:46 -04:00
|
|
|
}
|
2016-06-01 16:29:28 -04:00
|
|
|
}
|
2016-11-30 02:21:41 -05:00
|
|
|
return createNode(routeReuseStrategy, child);
|
2016-06-01 16:29:28 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-06-08 14:13:41 -04:00
|
|
|
function createActivatedRoute(c: ActivatedRouteSnapshot) {
|
|
|
|
return new ActivatedRoute(
|
2016-08-02 18:31:56 -04:00
|
|
|
new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams),
|
|
|
|
new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
|
2018-02-27 17:06:06 -05:00
|
|
|
}
|