forked from HenrikJoreteg/feather-route-matcher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeather-route-matcher.js
125 lines (107 loc) · 3.33 KB
/
feather-route-matcher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.createMatcher = factory());
}(this, (function () { 'use strict';
// regexes borrowed from backbone
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
// eslint-disable-next-line no-useless-escape
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
var splatParam = /\*/g;
// Parses a URL pattern such as `/users/:id`
// and builds and returns a regex that can be used to
// match said pattern. Credit for these
// regexes belongs to Jeremy Ashkenas and the
// other maintainers of Backbone.js
//
// It has been modified for extraction of
// named parameters from the URL
var parsePattern = function (pattern) {
var names = [];
pattern = pattern
.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, function (match, optional) {
names.push(match.slice(1));
return optional ? match : '([^/?]+)'
})
.replace(splatParam, function () {
names.push('path');
return '([^?]*?)'
});
return {
regExp: new RegExp('^' + pattern + '(?:\\?([\\s\\S]*))?$'),
namedParams: names
}
};
function index (routes) {
var keys = Object.keys(routes);
var routeCache = {};
// loop through each route we're
// and build the shell of our
// route cache.
for (var item in routes) {
routeCache[item] = {
value: routes[item]
};
}
// main result is a function that can be called
// with the url
return function (url) {
var params;
var route;
// start looking for matches
var matchFound = keys.some(function (key) {
var parsed;
// fetch the route pattern from the cache
// there will always be one
route = routeCache[key];
// if the route doesn't already have
// a regex we never generated one
// so we do that here lazily.
// Parse the pattern to generate the
// regex once, and store the result
// for next time.
if (!route.regExp) {
parsed = parsePattern(key);
route.regExp = parsed.regExp;
route.namedParams = parsed.namedParams;
route.pattern = key;
}
// run our cached regex
var result = route.regExp.exec(url);
// if null there was no match
// returning falsy here continues
// the `Array.prototype.some` loop
if (!result) {
return
}
// remove other cruft from result
result = result.slice(1, -1);
// reduce our match to an object of named parameters
// we've extracted from the url
params = result.reduce(function (obj, val, index) {
if (val) {
obj[route.namedParams[index]] = val;
}
return obj
}, {});
// stops the loop
return true
});
// no routes matched
if (!matchFound) {
return null
}
return {
value: route.value,
params: params,
url: url,
pattern: route.pattern
}
}
}
return index;
})));
//# sourceMappingURL=feather-route-matcher.js.map