Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 8dc10a4

Browse files
committed
fix($location): respect absolute paths correctly
Fixes absolute links on browsers with html5Mode enabled. Previously clicking on a link out of the base href would still rewrite the URL.
1 parent f6f0791 commit 8dc10a4

File tree

2 files changed

+96
-24
lines changed

2 files changed

+96
-24
lines changed

src/ng/location.js

+28-20
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ function $LocationProvider(){
636636
LocationMode = LocationHashbangUrl;
637637
}
638638
$location = new LocationMode(appBase, '#' + hashPrefix);
639-
$location.$$parse($location.$$rewrite(initialUrl));
639+
$location.$$parse($location.$$rewrite(initialUrl) || appBase);
640640

641641
var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
642642

@@ -675,26 +675,34 @@ function $LocationProvider(){
675675

676676
if (href && href.indexOf('://') < 0) { // Ignore absolute URLs
677677
var prefix = '#' + hashPrefix;
678-
if (href[0] == '/') {
679-
// absolute path - replace old path
680-
absHref = appBase + prefix + href;
681-
} else if (href[0] == '#') {
682-
// local anchor
683-
absHref = appBase + prefix + ($location.path() || '/') + href;
684-
} else {
685-
// relative path - join with current path
686-
var stack = $location.path().split("/"),
687-
parts = href.split("/");
688-
if (stack.length === 2 && !stack[1]) stack.length = 1;
689-
for (var i=0; i<parts.length; i++) {
690-
if (parts[i] == ".")
691-
continue;
692-
else if (parts[i] == "..")
693-
stack.pop();
694-
else if (parts[i].length)
695-
stack.push(parts[i]);
678+
var baseHrefNoFile = stripFile(baseHref);
679+
var appOnRoot = stripFile(appBase) == (serverBase(appBase) + '/');
680+
if (href[0] == '/' && (appOnRoot || (baseHref && beginsWith(baseHrefNoFile, href)))) {
681+
// absolute path - within base or when the app is on the root
682+
var hrefNoBase = baseHrefNoFile ? href.substr(baseHrefNoFile.length - 1) : href;
683+
absHref = appBase + prefix + hrefNoBase;
684+
} else if (href[0] != '/') { // Ignore absolute path outside of base
685+
if (beginsWith(prefix + '/', href)) {
686+
// local anchor with absolute path
687+
absHref = appBase + href;
688+
} else if (href[0] == '#') {
689+
// local anchor
690+
absHref = appBase + prefix + ($location.path() || '/') + href;
691+
} else {
692+
// relative path - join with current path
693+
var stack = $location.path().split("/"),
694+
parts = href.split("/");
695+
if (stack.length === 2 && !stack[1]) stack.length = 1;
696+
for (var i=0; i<parts.length; i++) {
697+
if (parts[i] == ".")
698+
continue;
699+
else if (parts[i] == "..")
700+
stack.pop();
701+
else if (parts[i].length)
702+
stack.push(parts[i]);
703+
}
704+
absHref = appBase + prefix + stack.join('/');
696705
}
697-
absHref = appBase + prefix + stack.join('/');
698706
}
699707
}
700708
}

test/ng/locationSpec.js

+68-4
Original file line numberDiff line numberDiff line change
@@ -875,10 +875,19 @@ describe('$location', function() {
875875
});
876876
}
877877

878-
function initBrowser() {
878+
function initBrowser(atRoot, noBase) {
879879
return function($browser){
880-
$browser.url('http://host.com/base');
881-
$browser.$$baseHref = '/base/index.html';
880+
if (atRoot) {
881+
$browser.url('http://host.com/');
882+
if (!noBase) {
883+
$browser.$$baseHref = '/index.html';
884+
}
885+
} else {
886+
$browser.url('http://host.com/base');
887+
if (!noBase) {
888+
$browser.$$baseHref = '/base/index.html';
889+
}
890+
}
882891
};
883892
}
884893

@@ -1206,8 +1215,36 @@ describe('$location', function() {
12061215
});
12071216

12081217

1209-
it('should replace current path when link begins with "/" and history disabled', function() {
1218+
it('should replace current path when link begins with "/" and app is on root and history enabled on old browser', function() {
12101219
configureService('/link', true, false, true);
1220+
inject(
1221+
initBrowser(true),
1222+
initLocation(),
1223+
function($browser, $location) {
1224+
$location.path('/some');
1225+
browserTrigger(link, 'click');
1226+
expectRewriteTo($browser, 'http://host.com/index.html#!/link');
1227+
}
1228+
);
1229+
});
1230+
1231+
1232+
it('should replace current path when relative link begins with "/base/" and history enabled on old browser', function() {
1233+
configureService('/base/link', true, false, true);
1234+
inject(
1235+
initBrowser(),
1236+
initLocation(),
1237+
function($browser, $location) {
1238+
$location.path('/some');
1239+
browserTrigger(link, 'click');
1240+
expectRewriteTo($browser, 'http://host.com/base/index.html#!/link');
1241+
}
1242+
);
1243+
});
1244+
1245+
1246+
it('should replace current path when link begins with "#!/" and history enabled on old browser', function() {
1247+
configureService('#!/link', true, false, true);
12111248
inject(
12121249
initBrowser(),
12131250
initLocation(),
@@ -1220,6 +1257,33 @@ describe('$location', function() {
12201257
});
12211258

12221259

1260+
it('should rewrite when relative link begins with "/" and app is on the root and there is no base tag and history enabled on old browser', function() {
1261+
configureService('/link', true, false, true);
1262+
inject(
1263+
initBrowser(true, true),
1264+
initLocation(),
1265+
function($browser, $location) {
1266+
browserTrigger(link, 'click');
1267+
expectRewriteTo($browser, 'http://host.com/#!/link');
1268+
}
1269+
);
1270+
});
1271+
1272+
1273+
it('should not rewrite when relative link begins with "/" and history enabled on old browser', function() {
1274+
configureService('/other_base/link', true, false, true);
1275+
inject(
1276+
initBrowser(),
1277+
initLocation(),
1278+
function($browser, $location) {
1279+
$location.path('/some');
1280+
browserTrigger(link, 'click');
1281+
expectNoRewrite($browser);
1282+
}
1283+
);
1284+
});
1285+
1286+
12231287
it('should replace current hash fragment when link begins with "#" history disabled', function() {
12241288
configureService('#link', true, false, true);
12251289
inject(

0 commit comments

Comments
 (0)