UNPKG

6.75 kBJavaScriptView Raw
1import { RouterGuardsService } from "./router-guards-service";
2export class RouterService {
3 constructor({ routes }, { routeToCallback, routeBackCallback, routeBackFallbackPath = "", logger = null, frame = null, vm = null, }) {
4 this.routes = [];
5 this.history = [];
6 this.routerGuardsService = null;
7 this.defaultOptions = {
8 transition: {
9 duration: 100,
10 },
11 meta: {
12 props: {},
13 },
14 };
15 this.routes = routes;
16 this.routeToCallback = routeToCallback;
17 this.routeBackCallback = routeBackCallback;
18 this.routeBackFallbackPath = routeBackFallbackPath;
19 this.logger = logger || console.log;
20 this.vm = vm;
21 this.frame = frame;
22 this.routerGuardsService = new RouterGuardsService({
23 to: "",
24 from: "",
25 });
26 }
27 push(route, options = {}) {
28 this.navigateTo(route, options);
29 }
30 back(options = {}, emptyRouteFallbackPath = null) {
31 this.navigateBack(options, emptyRouteFallbackPath);
32 }
33 onError(callback) {
34 this.errorCallbacks.push(callback);
35 }
36 beforeEach(callback) {
37 this.routerGuardsService.addBeforeEach(callback);
38 }
39 beforeResolve(callback) {
40 this.routerGuardsService.addBeforeResolve(callback);
41 }
42 invokeBeforeResolve() {
43 const context = this.routerGuardsService.runBeforeResolve();
44 if (!this.performContextAction(context)) {
45 this.setNavigationState(false);
46 return false;
47 }
48 return true;
49 }
50 afterEach(callback) {
51 this.routerGuardsService.addAfterEach(callback);
52 this.setNavigationState(false);
53 }
54 invokeAfterEach() {
55 this.routerGuardsService.runAfterEach();
56 }
57 updateVm(vm) {
58 this.vm = vm;
59 }
60 getRoute(route) {
61 if (!route) {
62 return null;
63 }
64 let routePath = "";
65 if (typeof route === "string") {
66 routePath = route;
67 }
68 else if (typeof route === "object") {
69 routePath = route.name || route.path;
70 }
71 return (this.routes.find(({ path, name }) => path === routePath || name === routePath) || null);
72 }
73 getCurrentRoute() {
74 return this.getRoute(this.currentRoute);
75 }
76 setCurrentRoute(route) {
77 this.currentRoute = route;
78 }
79 getNewRoute() {
80 return this.newRoute;
81 }
82 getPreviousRoute() {
83 const historyEntryNo = this.history.length - 1;
84 if (historyEntryNo < 0) {
85 return null;
86 }
87 if (!this.history[historyEntryNo]) {
88 return null;
89 }
90 return this.getRoute(this.history[historyEntryNo]);
91 }
92 setNavigationState(toggle) {
93 this.isNavigating = toggle;
94 if (!this.isNavigating) {
95 this.setNewRoute(null);
96 }
97 }
98 appendRouteHistory(routePath) {
99 this.history.push(routePath);
100 }
101 clearRouteHistory() {
102 this.history.splice(0);
103 }
104 isRouteAvailable(route) {
105 return Object.keys(this.getRoute(route) || {}).length > 0;
106 }
107 setNewRoute(route) {
108 this.newRoute = route;
109 }
110 isValidRoute(route) {
111 let logMessage = "";
112 if (!this.isRouteAvailable(route)) {
113 const routePath = typeof route === "object" && route && route.path
114 ? route.path
115 : route.toString();
116 logMessage = `Route ${routePath} is missing`;
117 }
118 if (logMessage && this.logger) {
119 this.logger.warn("ROUTER", logMessage);
120 return false;
121 }
122 return true;
123 }
124 navigateTo(route, options = {}, isNavigatingBack = false) {
125 if (!this.isValidRoute(route)) {
126 return;
127 }
128 const previousRoute = this.getCurrentRoute();
129 const newRoute = this.getRoute(route);
130 const routeOptions = Object.assign(Object.assign({}, this.defaultOptions), options);
131 routeOptions.props = routeOptions.props || {};
132 routeOptions.context = routeOptions.props;
133 newRoute.meta = newRoute.meta || {};
134 newRoute.meta.props = Object.assign(Object.assign(Object.assign({}, newRoute.meta), (newRoute.meta.props || {})), routeOptions.props);
135 this.setNavigationState(true);
136 this.setNewRoute(newRoute);
137 this.routerGuardsService.setRoutes(newRoute, previousRoute);
138 const context = this.routerGuardsService.runBeforeEach();
139 if (!this.performContextAction(context)) {
140 this.setNavigationState(false);
141 return;
142 }
143 if (this.vm.$modalPage) {
144 const modal = this.vm.$modalPage;
145 if (modal.instance && modal.data) {
146 modal.instance.onNavigatingFrom(modal.data);
147 }
148 this.vm.$modalPage = null;
149 }
150 if (isNavigatingBack) {
151 this.routeBackCallback(newRoute, routeOptions);
152 this.vm.$navigateBack(routeOptions);
153 }
154 else {
155 this.routeToCallback(newRoute, routeOptions);
156 this.vm.$navigateTo(newRoute.component, routeOptions);
157 }
158 this.setCurrentRoute(newRoute);
159 if (routeOptions.clearHistory) {
160 this.clearRouteHistory();
161 }
162 if (!isNavigatingBack && previousRoute) {
163 this.appendRouteHistory(previousRoute.path);
164 }
165 if (isNavigatingBack && this.history.length > 0) {
166 this.history.pop();
167 }
168 }
169 navigateBack(options = {}, emptyRouteFallbackPath = null) {
170 let newRoute = this.getPreviousRoute();
171 if (!newRoute ||
172 (this.frame.topmost() && this.frame.topmost().backStack.length < 1)) {
173 const alternativePath = emptyRouteFallbackPath || this.routeBackFallbackPath;
174 if (alternativePath) {
175 newRoute = this.getRoute(alternativePath);
176 options.clearHistory = true;
177 this.navigateTo(newRoute, options);
178 }
179 if (!newRoute && this.logger) {
180 this.logger.warn("ROUTER", "No route to go back to");
181 }
182 return;
183 }
184 this.navigateTo(newRoute, options, true);
185 }
186 performContextAction(context) {
187 if (context === false) {
188 return false;
189 }
190 if (typeof context === "object" || typeof context === "string") {
191 this.navigateTo(context);
192 return false;
193 }
194 if (context instanceof Error) {
195 this.onError(context);
196 return false;
197 }
198 return true;
199 }
200}
201//# sourceMappingURL=router-service.js.map
\No newline at end of file