UNPKG

router-vue-native

Version:

NativeScript Vue Router Extended for NativeScript Vue hybrid Apps.

237 lines 8.24 kB
import { RouterGuardsService } from "./router-guards-service"; import { registerActionDispatcher } from "./router-dispatcher-service"; import routerMixin from "./router-mixin"; import RouterView from "./router-view"; export class RouterService { constructor({ routes = [] }, { routeToCallback = null, routeBackCallback = null, routeBackFallbackPath = "", logger = null, frame = null, vm = null, }) { this.routes = []; this.history = []; this.routerGuardsService = null; this.defaultOptions = { transition: { duration: 100, }, meta: { props: {}, }, }; this.routes = routes; this.routeToCallback = routeToCallback; this.routeBackCallback = routeBackCallback; this.routeBackFallbackPath = routeBackFallbackPath; this.logger = logger || console.log; this.vm = vm; this.frame = frame; this.routerGuardsService = new RouterGuardsService({ to: null, from: null, }); } install(app) { const router = this; this.vm = app; const globals = app.config.globalProperties; globals.$routeTo = router.push.bind(router); globals.$routeBack = router.back.bind(router); globals.$router = router; app.provide("$router", router); if (app.mixin) { app.mixin(routerMixin); } app.component("RouterView", RouterView); registerActionDispatcher(router, app); } push(route, options = {}) { this.navigateTo(route, options); } back(options = {}, emptyRouteFallbackPath = null) { this.navigateBack(options, emptyRouteFallbackPath); } onError(callback) { this.errorCallbacks.push(callback); } beforeEach(callback) { this.routerGuardsService.addBeforeEach(callback); } beforeResolve(callback) { this.routerGuardsService.addBeforeResolve(callback); } invokeBeforeResolve() { const context = this.routerGuardsService.runBeforeResolve(); if (!this.performContextAction(context)) { this.setNavigationState(false); return false; } return true; } afterEach(callback) { this.routerGuardsService.addAfterEach(callback); this.setNavigationState(false); } invokeAfterEach() { this.routerGuardsService.runAfterEach(); } updateVm(vm) { this.vm = vm; } getRoute(route) { if (!route) { return null; } let routePath = ""; if (typeof route === "string") { routePath = route; } else if (typeof route === "object") { routePath = route.name || route.path; } return (this.routes.find(({ path, name }) => path === routePath || name === routePath) || null); } getCurrentRoute() { return this.getRoute(this.currentRoute); } setCurrentRoute(route) { this.currentRoute = route; if (this.vm.config.globalProperties.$route) { this.vm.config.globalProperties.$route = Object.assign({}, this.vm.config.globalProperties.$route, route); } else { this.vm.config.globalProperties.$route = route; } } getNewRoute() { return this.newRoute; } getPreviousRoute() { const historyEntryNo = this.history.length - 1; if (historyEntryNo < 0) { return null; } if (!this.history[historyEntryNo]) { return null; } return this.getRoute(this.history[historyEntryNo]); } setNavigationState(toggle) { this.isNavigating = toggle; if (!this.isNavigating) { this.setNewRoute(null); } } appendRouteHistory(routePath) { this.history.push(routePath); } clearRouteHistory() { this.history.splice(0); } isRouteAvailable(route) { return Object.keys(this.getRoute(route) || {}).length > 0; } setNewRoute(route) { this.newRoute = route; } isValidRoute(route) { let logMessage = ""; if (!this.isRouteAvailable(route)) { const routePath = typeof route === "object" && route && route.path ? route.path : route.toString(); logMessage = `Route ${routePath} is missing`; } if (logMessage && this.logger) { this.logger.warn("ROUTER", logMessage); return false; } return true; } navigateTo(route, options = { frame: "default", }, isNavigatingBack = false) { if (!this.vm) { this.logger.error("ROUTER", "The router needs a Vue instance, this can be added in the createRoute method or use app.use(router)"); return; } if (!this.isValidRoute(route)) { return; } const previousRoute = this.getCurrentRoute(); const newRoute = this.getRoute(route); const routeOptions = Object.assign(Object.assign({}, this.defaultOptions), options); routeOptions.props = routeOptions.props || {}; routeOptions.context = routeOptions.props; newRoute.meta = newRoute.meta || {}; newRoute.meta.props = Object.assign(Object.assign(Object.assign({}, newRoute.meta), (newRoute.meta.props || {})), routeOptions.props); this.setNavigationState(true); this.setNewRoute(newRoute); this.routerGuardsService.setRoutes(newRoute, previousRoute); const context = this.routerGuardsService.runBeforeEach(); if (!this.performContextAction(context)) { this.setNavigationState(false); return; } if (this.vm.config.globalProperties.$modalPage) { const modal = this.vm.config.globalProperties.$modalPage; if (modal.instance && modal.data) { modal.instance.onNavigatingFrom(modal.data); } this.vm.config.globalProperties.$modalPage = null; } if (isNavigatingBack) { if (this.routeBackCallback) { this.routeBackCallback(newRoute, routeOptions); } this.vm.config.globalProperties.$navigateBack(routeOptions); } else { if (this.routeToCallback) { this.routeToCallback(newRoute, routeOptions); } this.vm.config.globalProperties.$navigateTo(newRoute.component, routeOptions); } this.setCurrentRoute(newRoute); if (routeOptions.clearHistory) { this.clearRouteHistory(); } if (!isNavigatingBack && previousRoute) { this.appendRouteHistory(previousRoute.path); } if (isNavigatingBack && this.history.length > 0) { this.history.pop(); } } navigateBack(options = { frame: "default", }, emptyRouteFallbackPath = null) { var _a; let newRoute = this.getPreviousRoute(); if (!newRoute || ((_a = this.frame.topmost()) === null || _a === void 0 ? void 0 : _a.backStack.length) < 1) { const alternativePath = emptyRouteFallbackPath || this.routeBackFallbackPath; if (alternativePath) { newRoute = this.getRoute(alternativePath); options.clearHistory = true; console.log(newRoute, options); this.navigateTo(newRoute, options); } if (!newRoute && this.logger) { this.logger.warn("ROUTER", "No route to go back to"); } return; } this.navigateTo(newRoute, options, true); } performContextAction(context) { if (context === false) { return false; } if (context instanceof Error) { this.onError(context); return false; } if (typeof context === "object" || typeof context === "string") { this.navigateTo(context); return false; } return true; } } //# sourceMappingURL=router-service.js.map