From 0d9af2cce3f06d9fc64b0a29139bc905d23bffeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20PREVOT?= Date: Fri, 24 Jun 2016 10:41:32 +0200 Subject: [PATCH] feat urlMatcherFactory: add type "urlEncode" param Add a "urlEncode" type parameter This parameter allow to ignore the URL encoding of the URL parameters when generating an href. The use case for this is to allow to have a state param that contains "/" that should be restored as real "/" in the generated URL path. --- src/urlMatcherFactory.js | 9 +++++---- test/urlMatcherFactorySpec.js | 13 +++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/urlMatcherFactory.js b/src/urlMatcherFactory.js index bc4e1eb4e..676cbf4a2 100644 --- a/src/urlMatcherFactory.js +++ b/src/urlMatcherFactory.js @@ -342,8 +342,8 @@ UrlMatcher.prototype.format = function (values) { var i, search = false, nPath = segments.length - 1, nTotal = params.length, result = segments[0]; - function encodeDashes(str) { // Replace dashes with encoded "\-" - return encodeURIComponent(str).replace(/-/g, function(c) { return '%5C%' + c.charCodeAt(0).toString(16).toUpperCase(); }); + function encodeDashes(urlEncode, str) { // Replace dashes with encoded "\-" + return (urlEncode ? encodeURIComponent(str) : str).replace(/-/g, function(c) { return '%5C%' + c.charCodeAt(0).toString(16).toUpperCase(); }); } for (i = 0; i < nTotal; i++) { @@ -352,6 +352,7 @@ UrlMatcher.prototype.format = function (values) { var isDefaultValue = param.isOptional && param.type.equals(param.value(), value); var squash = isDefaultValue ? param.squash : false; var encoded = param.type.encode(value); + var urlEncode = param.type.urlEncode === undefined || param.type.urlEncode === null ? true : urlEncode; if (isPathParam) { var nextSegment = segments[i + 1]; @@ -360,9 +361,9 @@ UrlMatcher.prototype.format = function (values) { if (squash === false) { if (encoded != null) { if (isArray(encoded)) { - result += map(encoded, encodeDashes).join("-"); + result += map(encoded, encodeDashes.bind(null, urlEncode)).join("-"); } else { - result += encodeURIComponent(encoded); + result += urlEncode ? encodeURIComponent(encoded) : encoded; } } result += nextSegment; diff --git a/test/urlMatcherFactorySpec.js b/test/urlMatcherFactorySpec.js index 003d86edd..7819a9696 100755 --- a/test/urlMatcherFactorySpec.js +++ b/test/urlMatcherFactorySpec.js @@ -138,7 +138,7 @@ describe("UrlMatcher", function () { err = "Invalid parameter name 'periods.' in pattern '/users/?from&to&periods.'"; expect(function() { new UrlMatcher('/users/?from&to&periods.'); }).toThrow(err); }); - }); + }); describe(".exec()", function() { it("should capture parameter values", function () { @@ -196,6 +196,11 @@ describe("UrlMatcher", function () { expect(new UrlMatcher('/users/:id').format({ id:'100%'})).toEqual('/users/100%25'); }); + it("should not encode URL parameters", function () { + provider.type("unencodedUrlType", { urlEncode: false }); + expect(new UrlMatcher('/users/{id:unencodedUrlType}').format({ id:'100%'})).toEqual('/users/100%'); + }); + it("encodes URL parameters with hashes", function () { var m = new UrlMatcher('/users/:id#:section'), params = { id: 'bob', section: 'contact-details' }; @@ -234,7 +239,7 @@ describe("UrlMatcher", function () { provider.strictMode(false); m = m.concat("foo"); expect(m.exec("/foo")).toEqual({}); - expect(m.exec("/foo/")).toEqual({}) + expect(m.exec("/foo/")).toEqual({}); }); it("should respect $urlMatcherFactoryProvider.caseInsensitive", function() { @@ -387,7 +392,7 @@ describe("UrlMatcher", function () { "param5": [] }; - expect(parsed).toEqualData(expected) + expect(parsed).toEqualData(expected); expect(m.params.$$values(parsed)).toEqualData(expected); })); @@ -673,7 +678,7 @@ describe("urlMatcherFactory", function () { expect(m.exec($location.path(), $location.search())).toEqual( { fooid: 5, bar: [ 1, 2, 3 ] } ); expect(m.format({ fooid: 5, bar: [ 1, 2, 3 ] })).toEqual("/foo/5?bar=1&bar=2&bar=3"); - m.format() + m.format(); })); it("should allow custom types to handle multiple search param values manually", inject(function($location) {