diff --git a/src/ng/location.js b/src/ng/location.js index a6c3952a9036..3caa14e8de61 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -268,6 +268,16 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) { return appBaseNoFile; } }; + + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + // include hashPrefix in $$absUrl when $$url is empty so IE8 & 9 do not reload page because of removal of '#' + this.$$absUrl = appBase + hashPrefix + this.$$url; + }; + } @@ -642,6 +652,39 @@ function $LocationProvider(){ absHref = urlResolve(absHref.animVal).href; } + // Make relative links work in HTML5 mode for legacy browsers (or at least IE8 & 9) + // The href should be a regular url e.g. /link/somewhere or link/somewhere or ../somewhere or + // somewhere#anchor or http://example.com/somewhere + if (LocationMode === LocationHashbangInHtml5Url) { + // get the actual href attribute - see + // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx + var href = elm.attr('href') || elm.attr('xlink:href'); + + if (href.indexOf('://') < 0) { // Ignore absolute URLs + var prefix = '#' + hashPrefix; + if (href[0] == '/') { + // absolute path - replace old path + absHref = appBase + prefix + href; + } else if (href[0] == '#') { + // local anchor + absHref = appBase + prefix + ($location.path() || '/') + href; + } else { + // relative path - join with current path + var stack = $location.path().split("/"), + parts = href.split("/"); + for (var i=0; i' + content + '')[0]; @@ -1067,6 +1074,51 @@ describe('$location', function() { }); + it('should rewrite relative links relative to current path when history disabled', function() { + configureService('link', true, false, true); + inject( + initBrowser(), + initLocation(), + function($browser, $location) { + $location.path('/some'); + browserTrigger(link, 'click'); + expectRewriteTo($browser, 'http://host.com/base/index.html#!/some/link'); + } + ); + }); + + + it('should replace current path when link begins with "/" and history disabled', function() { + configureService('/link', true, false, true); + inject( + initBrowser(), + initLocation(), + function($browser, $location) { + $location.path('/some'); + browserTrigger(link, 'click'); + expectRewriteTo($browser, 'http://host.com/base/index.html#!/link'); + } + ); + }); + + + it('should replace current hash fragment when link begins with "#" history disabled', function() { + configureService('#link', true, false, true); + inject( + initBrowser(), + initLocation(), + function($browser, $location) { + // Initialize browser URL + $location.path('/some'); + $location.hash('foo'); + browserTrigger(link, 'click'); + expect($location.hash()).toBe('link'); + expectRewriteTo($browser, 'http://host.com/base/index.html#!/some#link'); + } + ); + }); + + // don't run next tests on IE<9, as browserTrigger does not simulate pressed keys if (!(msie < 9)) {