mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-05 08:59:35 +08:00
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!
This commit is contained in:
@@ -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<parts.length; i++) {
|
||||
if (parts[i] == ".")
|
||||
continue;
|
||||
else if (parts[i] == "..")
|
||||
stack.pop();
|
||||
else
|
||||
else if (parts[i].length)
|
||||
stack.push(parts[i]);
|
||||
}
|
||||
absHref = serverBase(absHref) + stack.join("/");
|
||||
absHref = appBase + prefix + stack.join('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -779,15 +779,22 @@ describe('$location', function() {
|
||||
|
||||
var root, link, originalBrowser, lastEventPreventDefault;
|
||||
|
||||
function configureService(linkHref, html5Mode, supportHist, attrs, content) {
|
||||
function configureService(linkHref, html5Mode, supportHist, relLink, attrs, content) {
|
||||
if (typeof relLink !== "boolean") {
|
||||
content = attrs;
|
||||
attrs = relLink;
|
||||
relLink = false;
|
||||
}
|
||||
module(function($provide, $locationProvider) {
|
||||
attrs = attrs ? ' ' + attrs + ' ' : '';
|
||||
|
||||
// fake the base behavior
|
||||
if (linkHref[0] == '/') {
|
||||
linkHref = 'http://host.com' + linkHref;
|
||||
} else if(!linkHref.match(/:\/\//)) {
|
||||
linkHref = 'http://host.com/base/' + linkHref;
|
||||
if (!relLink) {
|
||||
if (linkHref[0] == '/') {
|
||||
linkHref = 'http://host.com' + linkHref;
|
||||
} else if(!linkHref.match(/:\/\//)) {
|
||||
linkHref = 'http://host.com/base/' + linkHref;
|
||||
}
|
||||
}
|
||||
|
||||
link = jqLite('<a href="' + linkHref + '"' + attrs + '>' + content + '</a>')[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)) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user