-
Notifications
You must be signed in to change notification settings - Fork 13.5k
/
Copy pathstack-utils.ts
115 lines (103 loc) · 2.99 KB
/
stack-utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { ComponentRef } from '@angular/core';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import type { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core/components';
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection): RouteView[] => {
if (direction === 'root') {
return setRoot(views, view);
} else if (direction === 'forward') {
return setForward(views, view);
} else {
return setBack(views, view);
}
};
const setRoot = (views: RouteView[], view: RouteView) => {
views = views.filter((v) => v.stackId !== view.stackId);
view.root = true;
views.push(view);
return views;
};
const setForward = (views: RouteView[], view: RouteView) => {
const index = views.indexOf(view);
if (index >= 0) {
views = views.filter((v) => v.stackId !== view.stackId || v.id <= view.id);
} else {
views.push(view);
}
return views;
};
const setBack = (views: RouteView[], view: RouteView) => {
const index = views.indexOf(view);
if (index >= 0) {
return views.filter((v) => v.stackId !== view.stackId || v.id <= view.id);
} else {
return setRoot(views, view);
}
};
export const getUrl = (router: Router, activatedRoute: ActivatedRoute): string => {
const urlTree = router.createUrlTree(['.'], { relativeTo: activatedRoute });
return router.serializeUrl(urlTree);
};
export const isTabSwitch = (enteringView: RouteView, leavingView: RouteView | undefined): boolean => {
if (!leavingView) {
return true;
}
return enteringView.stackId !== leavingView.stackId;
};
export const computeStackId = (prefixUrl: string[] | undefined, url: string): string | undefined => {
if (!prefixUrl) {
return undefined;
}
const segments = toSegments(url);
for (let i = 0; i < segments.length; i++) {
if (i >= prefixUrl.length) {
return segments[i];
}
if (segments[i] !== prefixUrl[i]) {
return undefined;
}
}
return undefined;
};
export const toSegments = (path: string): string[] => {
return path
.split('/')
.map((s) => s.trim())
.filter((s) => s !== '');
};
export const destroyView = (view: RouteView | undefined): void => {
if (view) {
view.ref.destroy();
view.unlistenEvents();
}
};
export interface StackWillChangeEvent {
enteringView: RouteView;
/**
* `true` if the event is trigged as a result of a switch
* between tab navigation stacks.
*/
tabSwitch: boolean;
}
export interface StackDidChangeEvent {
enteringView: RouteView;
direction: RouterDirection;
animation: NavDirection | undefined;
/**
* `true` if the event is trigged as a result of a switch
* between tab navigation stacks.
*/
tabSwitch: boolean;
}
// TODO(FW-2827): types
export interface RouteView {
id: number;
url: string;
stackId: string | undefined;
element: HTMLElement;
ref: ComponentRef<any>;
savedData?: any;
savedExtras?: NavigationExtras;
unlistenEvents: () => void;
animationBuilder?: AnimationBuilder;
root?: boolean;
}