aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Chang2013-02-23 12:45:48 -0800
committerIgor Minar2013-02-27 12:45:30 -0800
commit5e18a15fb01d2e81adda68503754289fa9655082 (patch)
tree5f4bc27b06e5f73643e6b7dc892b907026730a95
parent60f1f099fc7e5197808cd6acb7407cdc40f50a3f (diff)
downloadangular.js-5e18a15fb01d2e81adda68503754289fa9655082.tar.bz2
feat($route): add `caseInsensitiveMatch` option for url matching
with this property urls can be matched case-insensitively which enables some new use cases.
-rw-r--r--src/ng/route.js15
-rw-r--r--test/ng/routeSpec.js66
2 files changed, 77 insertions, 4 deletions
diff --git a/src/ng/route.js b/src/ng/route.js
index 0f8fe3e9..433149d7 100644
--- a/src/ng/route.js
+++ b/src/ng/route.js
@@ -92,13 +92,18 @@ function $RouteProvider(){
* If the option is set to `false` and url in the browser changes, then
* `$routeUpdate` event is broadcasted on the root scope.
*
+ * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
+ *
+ * If the option is set to `true`, then the particular route can be matched without being
+ * case sensitive
+ *
* @returns {Object} self
*
* @description
* Adds a new route definition to the `$route` service.
*/
this.when = function(path, route) {
- routes[path] = extend({reloadOnSearch: true}, route);
+ routes[path] = extend({reloadOnSearch: true, caseInsensitiveMatch: false}, route);
// create redirection for trailing slashes
if (path) {
@@ -343,14 +348,16 @@ 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}
*/
- function switchRouteMatcher(on, when) {
+ 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
// Escape regexp special characters.
when = '^' + when.replace(/[-\/\\^$:*+?.()|[\]{}]/g, "\\$&") + '$';
+
var regex = '',
params = [],
dst = {};
@@ -377,7 +384,7 @@ function $RouteProvider(){
// Append trailing path part.
regex += when.substr(lastMatchedIndex);
- var match = on.match(new RegExp(regex));
+ var match = on.match(new RegExp(regex, whenProperties.caseInsensitiveMatch ? 'i' : ''));
if (match) {
forEach(params, function(name, index) {
dst[name] = match[index + 1];
@@ -466,7 +473,7 @@ function $RouteProvider(){
// Match a route
var params, match;
forEach(routes, function(route, path) {
- if (!match && (params = switchRouteMatcher($location.path(), path))) {
+ if (!match && (params = switchRouteMatcher($location.path(), path, route))) {
match = inherit(route, {
params: extend({}, $location.search(), params),
pathParams: params});
diff --git a/test/ng/routeSpec.js b/test/ng/routeSpec.js
index d43dcfba..1f714f62 100644
--- a/test/ng/routeSpec.js
+++ b/test/ng/routeSpec.js
@@ -117,6 +117,72 @@ describe('$route', function() {
});
});
+
+ it('should route and fire change event correctly whenever the case insensitive flag is utilized', function() {
+ var log = '',
+ lastRoute,
+ nextRoute;
+
+ module(function($routeProvider) {
+ $routeProvider.when('/Book1/:book/Chapter/:chapter/*highlight/edit',
+ {controller: noop, templateUrl: 'Chapter.html', caseInsensitiveMatch: true});
+ $routeProvider.when('/Book2/:book/*highlight/Chapter/:chapter',
+ {controller: noop, templateUrl: 'Chapter.html'});
+ $routeProvider.when('/Blank', {});
+ });
+ inject(function($route, $location, $rootScope) {
+ $rootScope.$on('$routeChangeStart', function(event, next, current) {
+ log += 'before();';
+ expect(current).toBe($route.current);
+ lastRoute = current;
+ nextRoute = next;
+ });
+ $rootScope.$on('$routeChangeSuccess', function(event, current, last) {
+ log += 'after();';
+ expect(current).toBe($route.current);
+ expect(lastRoute).toBe(last);
+ expect(nextRoute).toBe(current);
+ });
+
+ $location.path('/Book1/Moby/Chapter/Intro/one/edit').search('p=123');
+ $rootScope.$digest();
+ $httpBackend.flush();
+ expect(log).toEqual('before();after();');
+ expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one', p:'123'});
+
+ log = '';
+ $location.path('/BOOK1/Moby/CHAPTER/Intro/one/EDIT').search('p=123');
+ $rootScope.$digest();
+ expect(log).toEqual('before();after();');
+ expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one', p:'123'});
+
+ log = '';
+ $location.path('/Blank').search('ignore');
+ $rootScope.$digest();
+ expect(log).toEqual('before();after();');
+ expect($route.current.params).toEqual({ignore:true});
+
+ log = '';
+ $location.path('/BLANK');
+ $rootScope.$digest();
+ expect(log).toEqual('before();after();');
+ expect($route.current).toEqual(null);
+
+ log = '';
+ $location.path('/Book2/Moby/one/two/Chapter/Intro').search('p=123');
+ $rootScope.$digest();
+ expect(log).toEqual('before();after();');
+ expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one/two', p:'123'});
+
+ log = '';
+ $location.path('/BOOK2/Moby/one/two/CHAPTER/Intro').search('p=123');
+ $rootScope.$digest();
+ expect(log).toEqual('before();after();');
+ expect($route.current).toEqual(null);
+ });
+ });
+
+
it('should not change route when location is canceled', function() {
module(function($routeProvider) {
$routeProvider.when('/somePath', {template: 'some path'});