@eolme/vma-router
Version:
Router for VK Mini Apps
99 lines (98 loc) • 3.04 kB
JavaScript
import { error } from '../utils/report';
import { buildPage, matchPage, parsePath } 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 {
constructor(panel = PANEL_MAIN, view = VIEW_MAIN, modal = null, popout = null, params = {}) {
this._params = {};
this.index = -1;
this.id = Route._next++;
this.panel = panel;
this.view = view;
this.modal = modal;
this.popout = popout;
this.params = params;
}
get hasModal() {
return typeof this.modal === 'string';
}
get hasPopout() {
return typeof this.popout === 'string';
}
get hasOverlay() {
return this.hasModal || this.hasPopout;
}
get params() {
return this._params;
}
set params(value) {
this._params = {
...this._params,
...value
};
}
clone() {
return new Route(this.panel, this.view, this.modal, this.popout, this.params);
}
isSameWith(route) {
return (this.panel === route.panel &&
this.view === route.view &&
this.modal === route.modal &&
this.popout === route.popout);
}
compile(page) {
this.page = page;
this.uri = buildPage(page, this.params);
}
static buildFromLocation(routeList, path) {
const parsedPath = parsePath(path);
let match = null;
const page = Object.keys(routeList).find((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, page, params = {}) {
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, state) {
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;
}
}
Route._next = 0;
export { Route };
export default Route;