UNPKG

6.83 kBJavaScriptView Raw
1/*! Universal Router | MIT License | https://www.kriasoft.com/universal-router/ */
2
3'use strict';
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var pathToRegexp = _interopDefault(require('path-to-regexp'));
8
9/**
10 * Universal Router (https://www.kriasoft.com/universal-router/)
11 *
12 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
13 *
14 * This source code is licensed under the Apache 2.0 license found in the
15 * LICENSE.txt file in the root directory of this source tree.
16 */
17
18var cache = new Map();
19
20function decodeParam(val) {
21 try {
22 return decodeURIComponent(val);
23 } catch (err) {
24 return val;
25 }
26}
27
28function matchPath(routePath, urlPath, end, parentParams) {
29 var key = routePath + '|' + end;
30 var regexp = cache.get(key);
31
32 if (!regexp) {
33 var keys = [];
34 regexp = { pattern: pathToRegexp(routePath, keys, { end: end }), keys: keys };
35 cache.set(key, regexp);
36 }
37
38 var m = regexp.pattern.exec(urlPath);
39 if (!m) {
40 return null;
41 }
42
43 var path = m[0];
44 var params = Object.create(null);
45
46 if (parentParams) {
47 Object.assign(params, parentParams);
48 }
49
50 for (var i = 1; i < m.length; i += 1) {
51 params[regexp.keys[i - 1].name] = m[i] && decodeParam(m[i]);
52 }
53
54 return { path: path === '' ? '/' : path, keys: regexp.keys.slice(), params: params };
55}
56
57/**
58 * Universal Router (https://www.kriasoft.com/universal-router/)
59 *
60 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
61 *
62 * This source code is licensed under the Apache 2.0 license found in the
63 * LICENSE.txt file in the root directory of this source tree.
64 */
65
66function matchRoute(route, baseUrl, path, parentParams) {
67 var match = void 0;
68 var childMatches = void 0;
69 var childIndex = 0;
70
71 return {
72 next: function next() {
73 if (!match) {
74 match = matchPath(route.path, path, !route.children, parentParams);
75
76 if (match) {
77 return {
78 done: false,
79 value: {
80 route: route,
81 baseUrl: baseUrl,
82 path: match.path,
83 keys: match.keys,
84 params: match.params
85 }
86 };
87 }
88 }
89
90 if (match && route.children) {
91 while (childIndex < route.children.length) {
92 if (!childMatches) {
93 var newPath = path.substr(match.path.length);
94 var childRoute = route.children[childIndex];
95 childRoute.parent = route;
96
97 childMatches = matchRoute(childRoute, baseUrl + (match.path === '/' ? '' : match.path), newPath.charAt(0) === '/' ? newPath : '/' + newPath, match.params);
98 }
99
100 var childMatch = childMatches.next();
101 if (!childMatch.done) {
102 return {
103 done: false,
104 value: childMatch.value
105 };
106 }
107
108 childMatches = null;
109 childIndex += 1;
110 }
111 }
112
113 return { done: true };
114 }
115 };
116}
117
118/**
119 * Universal Router (https://www.kriasoft.com/universal-router/)
120 *
121 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
122 *
123 * This source code is licensed under the Apache 2.0 license found in the
124 * LICENSE.txt file in the root directory of this source tree.
125 */
126
127function resolveRoute(context, params) {
128 if (typeof context.route.action === 'function') {
129 return context.route.action(context, params);
130 }
131
132 return null;
133}
134
135var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
136
137function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
138
139/**
140 * Universal Router (https://www.kriasoft.com/universal-router/)
141 *
142 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
143 *
144 * This source code is licensed under the Apache 2.0 license found in the
145 * LICENSE.txt file in the root directory of this source tree.
146 */
147
148function isChildRoute(parentRoute, childRoute) {
149 var route = childRoute;
150 while (route) {
151 route = route.parent;
152 if (route === parentRoute) {
153 return true;
154 }
155 }
156 return false;
157}
158
159var Router = function () {
160 function Router(routes) {
161 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
162
163 _classCallCheck(this, Router);
164
165 if (Object(routes) !== routes) {
166 throw new TypeError('Invalid routes');
167 }
168
169 this.baseUrl = options.baseUrl || '';
170 this.resolveRoute = options.resolveRoute || resolveRoute;
171 this.context = Object.assign({ router: this }, options.context);
172 this.root = Array.isArray(routes) ? { path: '/', children: routes, parent: null } : routes;
173 this.root.parent = null;
174 }
175
176 _createClass(Router, [{
177 key: 'resolve',
178 value: function resolve(pathOrContext) {
179 var context = Object.assign({}, this.context, typeof pathOrContext === 'string' ? { path: pathOrContext } : pathOrContext);
180 var match = matchRoute(this.root, this.baseUrl, context.path.substr(this.baseUrl.length));
181 var resolve = this.resolveRoute;
182 var matches = null;
183 var nextMatches = null;
184
185 function next(resume) {
186 var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : matches.value.route;
187
188 matches = nextMatches || match.next();
189 nextMatches = null;
190
191 if (!resume) {
192 if (matches.done || !isChildRoute(parent, matches.value.route)) {
193 nextMatches = matches;
194 return Promise.resolve(null);
195 }
196 }
197
198 if (matches.done) {
199 return Promise.reject(Object.assign(new Error('Page not found'), { context: context, status: 404, statusCode: 404 }));
200 }
201
202 return Promise.resolve(resolve(Object.assign({}, context, matches.value), matches.value.params)).then(function (result) {
203 if (result !== null && result !== undefined) {
204 return result;
205 }
206
207 return next(resume, parent);
208 });
209 }
210
211 context.url = context.path;
212 context.next = next;
213
214 return next(true, this.root);
215 }
216 }]);
217
218 return Router;
219}();
220
221Router.pathToRegexp = pathToRegexp;
222Router.matchPath = matchPath;
223Router.matchRoute = matchRoute;
224Router.resolveRoute = resolveRoute;
225
226module.exports = Router;
227//# sourceMappingURL=browser.js.map