diff --git a/docs/content/guide/$location.ngdoc b/docs/content/guide/$location.ngdoc index db121430cd24..4a5589750dcc 100644 --- a/docs/content/guide/$location.ngdoc +++ b/docs/content/guide/$location.ngdoc @@ -95,6 +95,8 @@ To configure the `$location` service, retrieve the `true` or `enabled:true` - see HTML5 mode
`false` or `enabled:false` - see Hashbang mode
`requireBase:true` - see Relative links
+ `rewriteLinks:true` - see Html link rewriting
+ `rewriteLinks:'string'` - see Html link rewriting
default: `enabled:false` - **hashPrefix(prefix)**: {string}
@@ -326,6 +328,18 @@ reload to the original link. - Links starting with '/' that lead to a different base path
Example: `link` +If `html5Mode.rewriteLinks` is set to `false` in the html5Mode definition object passed to +`$locationProvider.html5Mode()`, the browser will perform a full page reload for every link. +`html5Mode.rewriteLinks` can also be set to a string, which will enable link re-writing only on +links that have the given attribute. + +For example, if `html5Mode.rewriteLinks` is set to "internal-link": +- `link` will be rewritten +- `link` will perform a full page reload + +Note that attribute name (de)normalization does not apply here, so "internalLink" is different from +"internal-link". + ### Relative links @@ -853,6 +867,3 @@ angular.module('locationExample', []) # Related API * {@link ng.$location `$location` API} - - - diff --git a/src/ng/location.js b/src/ng/location.js index a9d04002dfb4..80c2fc4f5c3c 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -750,8 +750,12 @@ function $LocationProvider() { * whether or not a tag is required to be present. If `enabled` and `requireBase` are * true, and a base tag is not present, an error will be thrown when `$location` is injected. * See the {@link guide/$location $location guide for more information} - * - **rewriteLinks** - `{boolean}` - (default: `true`) When html5Mode is enabled, - * enables/disables url rewriting for relative links. + * - **rewriteLinks** - `{boolean|String}` - (default: `true`) When html5Mode is enabled, + * enables/disables url rewriting for relative links. If set to a string, url rewriting will + * only happen on links with an attribute that matches the given string. For example, if set + * to "internal-link", then the URL will only be rewritten for `` links. Note + * that attribute name (de)normalization is not happening here. So "internal-link" is + * different from "internalLink". * * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter */ @@ -769,7 +773,7 @@ function $LocationProvider() { html5Mode.requireBase = mode.requireBase; } - if (isBoolean(mode.rewriteLinks)) { + if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) { html5Mode.rewriteLinks = mode.rewriteLinks; } @@ -866,10 +870,11 @@ function $LocationProvider() { } $rootElement.on('click', function(event) { + var rewriteLinks = html5Mode.rewriteLinks; // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) // currently we open nice url link and redirect then - if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return; + if (!rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return; var elm = jqLite(event.target); @@ -879,6 +884,8 @@ function $LocationProvider() { if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return; } + if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks))) return; + var absHref = elm.prop('href'); // get the actual href attribute - see // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js index 20567017c5c7..00b342e76f1c 100644 --- a/test/ng/locationSpec.js +++ b/test/ng/locationSpec.js @@ -1588,7 +1588,7 @@ describe('$location', function() { it('should not rewrite links when rewriting links is disabled', function() { - configureTestLink({linkHref: 'link?a#b', html5Mode: {enabled: true, rewriteLinks:false}, supportHist: true}); + configureTestLink({linkHref: 'link?a#b'}); initService({html5Mode:{enabled: true, rewriteLinks:false},supportHistory:true}); inject( initBrowser({ url: 'http://host.com/base/index.html', basePath: '/base/index.html' }), @@ -1601,6 +1601,34 @@ describe('$location', function() { }); + it('should rewrite links when the specified rewriteLinks attr is detected', function() { + configureTestLink({linkHref: 'link?a#b', attrs: 'force-rewrite'}); + initService({html5Mode:{enabled: true, rewriteLinks:'force-rewrite'},supportHistory:true}); + inject( + initBrowser({ url: 'http://host.com/base/index.html', basePath: '/base/index.html' }), + setupRewriteChecks(), + function($browser) { + browserTrigger(link, 'click'); + expectRewriteTo($browser, 'http://host.com/base/link?a#b'); + } + ); + }); + + + it('should not rewrite links when the specified rewriteLinks attr is not detected', function() { + configureTestLink({linkHref: 'link?a#b'}); + initService({html5Mode:{enabled: true, rewriteLinks:'yes-rewrite'},supportHistory:true}); + inject( + initBrowser({ url: 'http://host.com/base/index.html', basePath: '/base/index.html' }), + setupRewriteChecks(), + function($browser) { + browserTrigger(link, 'click'); + expectNoRewrite($browser); + } + ); + }); + + it('should rewrite full url links to same domain and base path', function() { configureTestLink({linkHref: 'http://host.com/base/new'}); initService({html5Mode:true,supportHistory:false,hashPrefix:'!'}); @@ -1692,7 +1720,7 @@ describe('$location', function() { it('should not rewrite when full link to different base path when history enabled on old browser', function() { - configureTestLink({linkHref: 'http://host.com/other_base/link', html5Mode: true, supportHist: false}); + configureTestLink({linkHref: 'http://host.com/other_base/link'}); inject( initBrowser({ url: 'http://host.com/base/index.html', basePath: '/base/index.html' }), setupRewriteChecks(), @@ -2357,12 +2385,12 @@ describe('$location', function() { }); - it('should only overwrite existing properties if values are boolean', function() { + it('should only overwrite existing properties if values are the correct type', function() { module(function($locationProvider) { $locationProvider.html5Mode({ enabled: 'duh', requireBase: 'probably', - rewriteLinks: 'nope' + rewriteLinks: 500 }); expect($locationProvider.html5Mode()).toEqual({ @@ -2376,6 +2404,19 @@ describe('$location', function() { }); + it('should allow rewriteLinks config to be set to a string', function() { + module(function($locationProvider) { + $locationProvider.html5Mode({ + rewriteLinks: 'yes-rewrite' + }); + + expect($locationProvider.html5Mode().rewriteLinks).toEqual('yes-rewrite'); + }); + + inject(function() {}); + }); + + it('should not set unknown input properties to html5Mode object', function() { module(function($locationProvider) { $locationProvider.html5Mode({