UNPKG

4.35 kBJavaScriptView Raw
1
2export var Route = {
3
4 _routes: [],
5 _routeSegments: {},
6
7 /**
8 * Check if current URL is attached to route (1st param)
9 * or if second optional param passed - checks against haystack_url not current URL
10 * @param uri
11 * @param haystack_url
12 * @returns {boolean}
13 */
14 is: function(uri, haystack_url = window.location.pathname) {
15 var original_segments = haystack_url.split('/');
16 var route_segments = uri.split('/');
17 var original_length = original_segments.length;
18 var route_length = route_segments.length;
19 if (original_length !== route_length) {
20 return false;
21 }
22 for (var i = 1; i < original_length; i++) {
23 if (route_segments[i].indexOf('{') === -1 && route_segments[i] !== original_segments[i]) {
24 return false;
25 }
26 }
27 return true;
28 },
29
30 /**
31 * Get route params
32 * @param uri
33 * @returns {{}}
34 */
35 params: function(uri) {
36 var original_segments = window.location.pathname.split('/');
37 var route_segments = uri.split('/');
38 var route_length = route_segments.length;
39 var params = {};
40 for (var i = 1; i < route_length; i++) {
41 if (route_segments[i].indexOf('{') !== -1) {
42 var name = route_segments[i].substr(1, route_segments[i].length-2);
43 params[name] = original_segments[i];
44 }
45 }
46 return params;
47 },
48
49 /**
50 * Define new route
51 * If it is required to set route handler as an object method not a closure/function
52 * and set 'this' keyword to reference the correct object
53 * pass object to 2nd argument and method name as a string to 3rd argument
54 * Or use Route.get(uri, Object.method.bind(Object))
55 *
56 * @param {string} uri
57 * @param {callback} callback
58 * @param {string|null} method = null
59 * @returns {boolean}
60 */
61 get: function(uri, callback, method = null) {
62
63 var route = this.defined(uri);
64 if (route === false) {
65 this._routes[uri] = {
66 handler: callback,
67 method: method
68 }
69 } else {
70 console.error('Route "' + uri + '" already defined.');
71 return false;
72 }
73
74 },
75
76 /**
77 * Check if route is defined. Returns route if found or false
78 * @param uri
79 * @returns {*}
80 */
81 defined: function(uri) {
82
83 if (this._routes[uri] !== undefined) {
84 return uri;
85 }
86
87 for (var route in this._routes) {
88 if (this.is(route, uri)) {
89 return route;
90 }
91 }
92
93 return false;
94 },
95
96 /**
97 * Call closure/controller attached to route
98 * @param uri
99 * @returns {boolean}
100 */
101 call: function(uri) {
102 var route = this.defined(uri);
103 if (route !== false) {
104
105 if (this._routes[route].method === null) {
106 var f = this._routes[route].handler.bind(this._routes[route].handler);
107 f(this.params(route));
108 } else {
109 var Obj = this._routes[route].handler;
110 var method = this._routes[route].method;
111 Obj[method](this.params(route));
112 }
113
114 } else {
115 console.error('Route "' + uri + '" is not defined.');
116 return false;
117 }
118 },
119
120 /**
121 * Redirect to new route
122 * @param uri
123 * @returns {boolean}
124 */
125 to: function(uri) {
126 if (this.defined(uri)) {
127 history.pushState(null, null, uri);
128 var event = new CustomEvent('onRouteChange');
129 event.route = uri;
130 document.dispatchEvent(event, uri);
131 } else {
132 console.error('Route "' + uri + '" is not defined.');
133 return false;
134 }
135 }
136
137};
138
139document.addEventListener('DOMContentLoaded', function() {
140 if (Route.defined(window.location.pathname)) {
141 Route.call(window.location.pathname);
142 }
143}, false);
144
145document.addEventListener('onRouteChange', function(e) {
146 if (Route.defined(e.route)) {
147 Route.call(e.route);
148 }
149}, false);