From 49e7c32bb45ce3984df6768ba7b2f6a723a4ebe7 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Fri, 28 Mar 2014 14:13:25 -0400 Subject: [PATCH] fix($location): fix and test html5Mode url-parsing algorithm for legacy browsers This CL fixes problems and adds test cases for changes from #6421. Changes include fixing the algorithm for preprocessing href attribute values, as well as supporting xlink:href attributes. Credit for the original URL parsing algorithm still goes to @richardcrichardc. Good work, champ! --- src/ng/location.js | 21 +++++++------- test/ng/locationSpec.js | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/ng/location.js b/src/ng/location.js index 1ed352f1d62d..3caa14e8de61 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -653,33 +653,34 @@ function $LocationProvider(){ } // 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 + // 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 - // TODO check browser is in standards mode - var href = elm[0].getAttribute('href'); + // 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('://' == -1)) { // Ignore absolute URLs + if (href.indexOf('://') < 0) { // Ignore absolute URLs + var prefix = '#' + hashPrefix; if (href[0] == '/') { // absolute path - replace old path - absHref = serverBase(absHref) + href; + absHref = appBase + prefix + href; } else if (href[0] == '#') { // local anchor - absHref = serverBase(absHref) + $location.path() + href; + absHref = appBase + prefix + ($location.path() || '/') + href; } else { // relative path - join with current path var stack = $location.path().split("/"), parts = href.split("/"); - stack.pop(); // remove top file 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)) {