Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

refactor(ngRoute): compile the route once and reuse the regex #3393

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 39 additions & 28 deletions src/ngRoute/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down