From 8f770416ec964a4abf9fcae38cd5022c197e6d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Galfas=C3=B3?= Date: Tue, 30 Jul 2013 10:38:44 -0300 Subject: [PATCH] refactor(ngRoute): compile the route once and reuse the regex Compile the route path once and reuse it in the future --- src/ngRoute/route.js | 67 ++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/ngRoute/route.js b/src/ngRoute/route.js index 743897d625c5..e222d2aa5028 100644 --- a/src/ngRoute/route.js +++ b/src/ngRoute/route.js @@ -361,51 +361,62 @@ function $RouteProvider(){ ///////////////////////////////////////////////////// /** - * @param on {string} current url * @param when {string} route when template to match the url against * @param whenProperties {Object} properties to define when's matching behavior - * @return {?Object} + * @return {function} a function that takes a route and returns the route params + * or null if the route does not match */ - function switchRouteMatcher(on, when, whenProperties) { - // TODO(i): this code is convoluted and inefficient, we should construct the route matching - // regex only once and then reuse it - + function compileRoute(when, whenProperties) { // Escape regexp special characters. when = '^' + when.replace(/[-\/\\^$:*+?.()|[\]{}]/g, "\\$&") + '$'; - var regex = '', - params = [], - dst = {}; - - var re = /\\([:*])(\w+)/g, - paramMatch, - lastMatchedIndex = 0; + var regexString = '', + params = [], + re = /\\([:*])(\w+)/g, + paramMatch, + lastMatchedIndex = 0, + regex; 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); + regexString += when.slice(lastMatchedIndex, paramMatch.index); switch(paramMatch[1]) { - case ':': - regex += '([^\\/]*)'; - break; - case '*': - regex += '(.*)'; - break; + case ':': + regexString += '([^\\/]*)'; + break; + case '*': + regexString += '(.*)'; + break; } params.push(paramMatch[2]); lastMatchedIndex = re.lastIndex; } // Append trailing path part. - regex += when.substr(lastMatchedIndex); + regexString += when.substr(lastMatchedIndex); + regex = new RegExp(regexString, whenProperties.caseInsensitiveMatch ? 'i' : ''); + return function(on) { + var match = on.match(regex), + dst = {}; + if (match) { + forEach(params, function(name, index) { + dst[name] = match[index + 1]; + }); + } + return match ? dst : null; + }; + } - var match = on.match(new RegExp(regex, whenProperties.caseInsensitiveMatch ? 'i' : '')); - if (match) { - forEach(params, function(name, index) { - dst[name] = match[index + 1]; - }); - } - return match ? dst : null; + + /** + * @param on {string} current url + * @param when {string} route when template to match the url against + * @param whenProperties {Object} properties to define when's matching behavior + * @return {?Object} + */ + function switchRouteMatcher(on, when, whenProperties) { + return (whenProperties.routeMatcherFn || + (whenProperties.routeMatcherFn = compileRoute(when, whenProperties)))(on); } function updateRoute() {