diff options
Diffstat (limited to 'src/ng/route.js')
| -rw-r--r-- | src/ng/route.js | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/src/ng/route.js b/src/ng/route.js index 361b8ac3..91e4adb3 100644 --- a/src/ng/route.js +++ b/src/ng/route.js @@ -20,8 +20,13 @@ function $RouteProvider(){ * * @param {string} path Route path (matched against `$location.path`). If `$location.path` * contains redundant trailing slash or is missing one, the route will still match and the - * `$location.path` will be updated to add or drop the trailing slash to exacly match the + * `$location.path` will be updated to add or drop the trailing slash to exactly match the * route definition. + * + * `path` can contain named groups starting with a colon (`:name`). All characters up to the + * next slash are matched and stored in `$routeParams` under the given `name` when the route + * matches. + * * @param {Object} route Mapping information to be assigned to `$route.current` on route * match. * @@ -286,8 +291,7 @@ function $RouteProvider(){ * instance of the Controller. */ - var matcher = switchRouteMatcher, - forceReload = false, + var forceReload = false, $route = { routes: routes, @@ -315,21 +319,36 @@ function $RouteProvider(){ ///////////////////////////////////////////////////// + /** + * @param on {string} current url + * @param when {string} route when template to match the url against + * @return {?Object} + */ function switchRouteMatcher(on, when) { // TODO(i): this code is convoluted and inefficient, we should construct the route matching // regex only once and then reuse it - var regex = '^' + when.replace(/([\.\\\(\)\^\$])/g, "\\$1") + '$', + + // Escape regexp special characters. + when = '^' + when.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") + '$'; + var regex = '', params = [], dst = {}; - forEach(when.split(/[^\w:]/), function(param) { - if (param && param.charAt(0) === ':') { - var paramRegExp = new RegExp(param + "([\\W])"); - if (regex.match(paramRegExp)) { - regex = regex.replace(paramRegExp, "([^\\/]*)$1"); - params.push(param.substr(1)); - } - } - }); + + var re = /:(\w+)/g, + paramMatch, + lastMatchedIndex = 0; + + while ((paramMatch = re.exec(when)) !== null) { + // Find each :param in `when` and replace it with a capturing group. + // Append all other sections of when unchanged. + regex += when.slice(lastMatchedIndex, paramMatch.index); + regex += '([^\\/]*)'; + params.push(paramMatch[1]); + lastMatchedIndex = re.lastIndex; + } + // Append trailing path part. + regex += when.substr(lastMatchedIndex); + var match = on.match(new RegExp(regex)); if (match) { forEach(params, function(name, index) { @@ -418,7 +437,7 @@ function $RouteProvider(){ // Match a route var params, match; forEach(routes, function(route, path) { - if (!match && (params = matcher($location.path(), path))) { + if (!match && (params = switchRouteMatcher($location.path(), path))) { match = inherit(route, { params: extend({}, $location.search(), params), pathParams: params}); |
