UNPKG

@eolme/vma-router

Version:
164 lines (131 loc) 3.21 kB
import { error } from '../utils/report'; import type { Page, View, Panel, Modal, Popout, RouteLike, RouteParams, Structure, RouteList } from '../types'; import { buildPage, matchPage, parsePath, MatchedPath } from '../utils/route'; import hasOwn from '../utils/hasOwn'; export const VIEW_MAIN = 'view_main'; export const PANEL_MAIN = 'panel_main'; export const PAGE_MAIN = '/'; class Route { private static _next: number = 0; readonly id: number; uri: string; page: Page; view: View; panel: Panel; history: Structure[]; modal: Modal; get hasModal() { return typeof this.modal === 'string'; } popout: Popout; get hasPopout() { return typeof this.popout === 'string'; } get hasOverlay() { return this.hasModal || this.hasPopout; } private _params: RouteParams = {}; get params(): Readonly<RouteParams> { return this._params; } set params(value) { this._params = { ...this._params, ...value }; } index: number = -1; constructor( panel: Panel = PANEL_MAIN, view: View = VIEW_MAIN, modal: Modal = null, popout: Popout = null, params: RouteParams = {} ) { this.id = Route._next++; this.panel = panel; this.view = view; this.modal = modal; this.popout = popout; this.params = params; } clone() { return new Route( this.panel, this.view, this.modal, this.popout, this.params ); } isSameWith(route: RouteLike) { return ( this.panel === route.panel && this.view === route.view && this.modal === route.modal && this.popout === route.popout ); } compile(page: Page) { this.page = page; this.uri = buildPage(page, this.params); } static buildFromLocation(routeList: RouteList, path: string) { const parsedPath = parsePath(path); let match: MatchedPath = null; const page = Object.keys(routeList).find((page: Page) => { match = matchPage(page, parsedPath.url); return match && match.exact; }); if (!match) { error('Builder cant find route for ' + path); } const route = routeList[page]; if (!route) { error('Builder cant find route for ' + path); } const build = route.clone(); build.params = match.params; build.compile(page); return build; } static buildFromPage(routeList: RouteList, page: Page, params: RouteParams = {}) { const route = routeList[page]; if (!route) { error('Builder cant find route for ' + page); } const build = route.clone(); build.params = params; build.compile(page); return build; } static buildFromState(routeList: RouteList, state: RouteLike) { if (!state.page) { error('Builder cant resolve page for ' + state); } const route = routeList[state.page]; if (!route) { error('Builder cant find route for ' + state.page); } const build = route.clone(); Object.keys(state).forEach((key) => { if (hasOwn(build, key)) { build[key] = route[key]; } }); build.compile(state.page); return build; } } export { Route }; export default Route;