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

Commit 5e18a15

Browse files
davidchangIgorMinar
authored andcommitted
feat($route): add caseInsensitiveMatch option for url matching
with this property urls can be matched case-insensitively which enables some new use cases.
1 parent 60f1f09 commit 5e18a15

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

src/ng/route.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,18 @@ function $RouteProvider(){
9292
* If the option is set to `false` and url in the browser changes, then
9393
* `$routeUpdate` event is broadcasted on the root scope.
9494
*
95+
* - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
96+
*
97+
* If the option is set to `true`, then the particular route can be matched without being
98+
* case sensitive
99+
*
95100
* @returns {Object} self
96101
*
97102
* @description
98103
* Adds a new route definition to the `$route` service.
99104
*/
100105
this.when = function(path, route) {
101-
routes[path] = extend({reloadOnSearch: true}, route);
106+
routes[path] = extend({reloadOnSearch: true, caseInsensitiveMatch: false}, route);
102107

103108
// create redirection for trailing slashes
104109
if (path) {
@@ -343,14 +348,16 @@ function $RouteProvider(){
343348
/**
344349
* @param on {string} current url
345350
* @param when {string} route when template to match the url against
351+
* @param whenProperties {Object} properties to define when's matching behavior
346352
* @return {?Object}
347353
*/
348-
function switchRouteMatcher(on, when) {
354+
function switchRouteMatcher(on, when, whenProperties) {
349355
// TODO(i): this code is convoluted and inefficient, we should construct the route matching
350356
// regex only once and then reuse it
351357

352358
// Escape regexp special characters.
353359
when = '^' + when.replace(/[-\/\\^$:*+?.()|[\]{}]/g, "\\$&") + '$';
360+
354361
var regex = '',
355362
params = [],
356363
dst = {};
@@ -377,7 +384,7 @@ function $RouteProvider(){
377384
// Append trailing path part.
378385
regex += when.substr(lastMatchedIndex);
379386

380-
var match = on.match(new RegExp(regex));
387+
var match = on.match(new RegExp(regex, whenProperties.caseInsensitiveMatch ? 'i' : ''));
381388
if (match) {
382389
forEach(params, function(name, index) {
383390
dst[name] = match[index + 1];
@@ -466,7 +473,7 @@ function $RouteProvider(){
466473
// Match a route
467474
var params, match;
468475
forEach(routes, function(route, path) {
469-
if (!match && (params = switchRouteMatcher($location.path(), path))) {
476+
if (!match && (params = switchRouteMatcher($location.path(), path, route))) {
470477
match = inherit(route, {
471478
params: extend({}, $location.search(), params),
472479
pathParams: params});

test/ng/routeSpec.js

+66
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,72 @@ describe('$route', function() {
117117
});
118118
});
119119

120+
121+
it('should route and fire change event correctly whenever the case insensitive flag is utilized', function() {
122+
var log = '',
123+
lastRoute,
124+
nextRoute;
125+
126+
module(function($routeProvider) {
127+
$routeProvider.when('/Book1/:book/Chapter/:chapter/*highlight/edit',
128+
{controller: noop, templateUrl: 'Chapter.html', caseInsensitiveMatch: true});
129+
$routeProvider.when('/Book2/:book/*highlight/Chapter/:chapter',
130+
{controller: noop, templateUrl: 'Chapter.html'});
131+
$routeProvider.when('/Blank', {});
132+
});
133+
inject(function($route, $location, $rootScope) {
134+
$rootScope.$on('$routeChangeStart', function(event, next, current) {
135+
log += 'before();';
136+
expect(current).toBe($route.current);
137+
lastRoute = current;
138+
nextRoute = next;
139+
});
140+
$rootScope.$on('$routeChangeSuccess', function(event, current, last) {
141+
log += 'after();';
142+
expect(current).toBe($route.current);
143+
expect(lastRoute).toBe(last);
144+
expect(nextRoute).toBe(current);
145+
});
146+
147+
$location.path('/Book1/Moby/Chapter/Intro/one/edit').search('p=123');
148+
$rootScope.$digest();
149+
$httpBackend.flush();
150+
expect(log).toEqual('before();after();');
151+
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one', p:'123'});
152+
153+
log = '';
154+
$location.path('/BOOK1/Moby/CHAPTER/Intro/one/EDIT').search('p=123');
155+
$rootScope.$digest();
156+
expect(log).toEqual('before();after();');
157+
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one', p:'123'});
158+
159+
log = '';
160+
$location.path('/Blank').search('ignore');
161+
$rootScope.$digest();
162+
expect(log).toEqual('before();after();');
163+
expect($route.current.params).toEqual({ignore:true});
164+
165+
log = '';
166+
$location.path('/BLANK');
167+
$rootScope.$digest();
168+
expect(log).toEqual('before();after();');
169+
expect($route.current).toEqual(null);
170+
171+
log = '';
172+
$location.path('/Book2/Moby/one/two/Chapter/Intro').search('p=123');
173+
$rootScope.$digest();
174+
expect(log).toEqual('before();after();');
175+
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one/two', p:'123'});
176+
177+
log = '';
178+
$location.path('/BOOK2/Moby/one/two/CHAPTER/Intro').search('p=123');
179+
$rootScope.$digest();
180+
expect(log).toEqual('before();after();');
181+
expect($route.current).toEqual(null);
182+
});
183+
});
184+
185+
120186
it('should not change route when location is canceled', function() {
121187
module(function($routeProvider) {
122188
$routeProvider.when('/somePath', {template: 'some path'});

0 commit comments

Comments
 (0)