nativescript-vue-router-extended
Version:
NativeScript Vue Router Extended for NativeScript Vue hybrid Apps.
206 lines • 6.95 kB
JavaScript
import { RouterGuardsService } from "./router-guards-service";
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,
});
}
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;
this.vm.$route = Object.assign(this.vm.$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 = {}, isNavigatingBack = false) {
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.$modalPage) {
const modal = this.vm.$modalPage;
if (modal.instance && modal.data) {
modal.instance.onNavigatingFrom(modal.data);
}
this.vm.$modalPage = null;
}
if (isNavigatingBack) {
if (this.routeBackCallback) {
this.routeBackCallback(newRoute, routeOptions);
}
this.vm.$navigateBack(routeOptions);
}
else {
if (this.routeToCallback) {
this.routeToCallback(newRoute, routeOptions);
}
this.vm.$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 = {}, emptyRouteFallbackPath = null) {
let newRoute = this.getPreviousRoute();
if (!newRoute ||
(this.frame.topmost() && this.frame.topmost().backStack.length < 1)) {
const alternativePath = emptyRouteFallbackPath || this.routeBackFallbackPath;
if (alternativePath) {
newRoute = this.getRoute(alternativePath);
options.clearHistory = true;
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