UNPKG

3.4 kBJavaScriptView Raw
1import BackboneSubRoute from 'backbone.subroute';
2import { settings } from './contexts';
3import { global, runtime } from './contexts';
4
5let _stateRouteMapping = {};
6
7class UrlDefinition {
8 constructor(state, controller) {
9 this._state = state;
10 this._controller = controller;
11 }
12
13 get state() {
14 return this._state;
15 }
16
17 get controller() {
18 return this._controller;
19 }
20}
21
22class IncludeDefinition {
23 constructor(router) {
24 this._router = router;
25 }
26
27 get router() {
28 return this._router;
29 }
30}
31
32export function url(state, controller) {
33 return new UrlDefinition(state, controller);
34}
35
36export function include(router) {
37 return new IncludeDefinition(router);
38}
39
40export class RouteUtils {
41 static _urlParamsReplace(url, params) { //eslint-disable-line no-shadow
42 for (let pkey of Object.keys(params)) {
43 let beforeReplace = url;
44 url = url.replace(`:${pkey}`, params[pkey]);
45 if (beforeReplace === url) {
46 throw `Unable to find reverse url for "${beforeReplace}" with params ${JSON.stringify(params)}.`;
47 }
48 }
49 return url;
50 }
51
52 static reverse(state, params = {}, prependHash = true) {
53 var url = _stateRouteMapping[state].route; //eslint-disable-line no-shadow
54 url = RouteUtils._urlParamsReplace(url, params);
55 if (prependHash) {
56 return `#${url}`;
57 }
58 return url;
59 }
60
61 static navigate(state, params = {}) {
62 var routeMapping = _stateRouteMapping[state];
63 var url = _stateRouteMapping[state].route; //eslint-disable-line no-shadow
64 url = RouteUtils._urlParamsReplace(url, params);
65 routeMapping.router.navigate(url, {trigger: true});
66 }
67
68 static query() {
69 var href = window.location.href;
70 var result = {};
71 if (href.includes('#')) {
72 href = href.split('#')[1];
73 }
74 href = href.split('?')[1];
75 if (href) {
76 for (let param of href.split('&')) {
77 let [k, v] = param.split('=');
78 result[decodeURIComponent(k)] = decodeURIComponent(v);
79 }
80 }
81 return result;
82 }
83
84 static isState(state, className = 'active') {
85 if (global.state.indexOf(state) === 0) {
86 return className;
87 }
88 }
89}
90
91export class BaseRouter extends BackboneSubRoute {
92 constructor(prefix, options, mainElement) {
93 super(prefix, options);
94
95 //find subRoutes
96 for (let rt of Object.keys(this.routes)) {
97 let rtObj = this.routes[rt];
98 if (rtObj instanceof IncludeDefinition) {
99 //instantiate sub router
100 new rtObj.router(rt, options, mainElement); //eslint-disable-line new-cap, no-new
101 delete this.routes[rt];
102 } else {
103 _stateRouteMapping[rtObj.state] = {route: rt, router: this};
104 }
105 }
106
107 this.on('route', function (urlDef, args) {
108 var Controller = urlDef.controller;
109 var routeContext = {
110 currentState: urlDef.state,
111 element: mainElement
112 };
113 var midPromises = [];
114 for (var mid of runtime.middleware) {
115 if (mid.preControllerInit) {
116 midPromises.push(mid.preControllerInit());
117 }
118 }
119 Promise.all(midPromises).then(() => {
120 global.state = urlDef.state;
121 new Controller(routeContext).init(...args);
122 }, (error) => {
123 if (error) {
124 console.log(error);
125 }
126 });
127 });
128 }
129
130 get routes() {
131 if (!this._routes) {
132 this._routes = this.urlPatterns;
133 }
134 return this._routes;
135 }
136}