mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
refactor($location): move file://+win path fix to $location
The urlResolve method was fixed to automatically remove the volume label from path names to fix issues with the file protocol on windows where $location.path() was returning paths where the first segment would be the volume name, such as "/C:/mypath". See #4942 and #4928 However, the solution was specific to the $location non- HTML5 mode, and was implemented at a lower level of abstraction than it should have been. This refactor moves the fix to inside of the LocationHashBangUrl $$parse method. Closes #5041
This commit is contained in:
parent
947562220d
commit
736c8fbbae
4 changed files with 53 additions and 47 deletions
|
|
@ -179,7 +179,47 @@ function LocationHashbangUrl(appBase, hashPrefix) {
|
|||
hashPrefix);
|
||||
}
|
||||
parseAppUrl(withoutHashUrl, this, appBase);
|
||||
|
||||
this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
|
||||
|
||||
this.$$compose();
|
||||
|
||||
/*
|
||||
* In Windows, on an anchor node on documents loaded from
|
||||
* the filesystem, the browser will return a pathname
|
||||
* prefixed with the drive name ('/C:/path') when a
|
||||
* pathname without a drive is set:
|
||||
* * a.setAttribute('href', '/foo')
|
||||
* * a.pathname === '/C:/foo' //true
|
||||
*
|
||||
* Inside of Angular, we're always using pathnames that
|
||||
* do not include drive names for routing.
|
||||
*/
|
||||
function removeWindowsDriveName (path, url, base) {
|
||||
/*
|
||||
Matches paths for file protocol on windows,
|
||||
such as /C:/foo/bar, and captures only /foo/bar.
|
||||
*/
|
||||
var windowsFilePathExp = /^\/?.*?:(\/.*)/;
|
||||
|
||||
var firstPathSegmentMatch;
|
||||
|
||||
//Get the relative path from the input URL.
|
||||
if (url.indexOf(base) === 0) {
|
||||
url = url.replace(base, '');
|
||||
}
|
||||
|
||||
/*
|
||||
* The input URL intentionally contains a
|
||||
* first path segment that ends with a colon.
|
||||
*/
|
||||
if (windowsFilePathExp.exec(url)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
firstPathSegmentMatch = windowsFilePathExp.exec(path);
|
||||
return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,11 +7,6 @@
|
|||
// exactly the behavior needed here. There is little value is mocking these out for this
|
||||
// service.
|
||||
var urlParsingNode = document.createElement("a");
|
||||
/*
|
||||
Matches paths for file protocol on windows,
|
||||
such as /C:/foo/bar, and captures only /foo/bar.
|
||||
*/
|
||||
var windowsFilePathExp = /^\/?.*?:(\/.*)/;
|
||||
var originUrl = urlResolve(window.location.href, true);
|
||||
|
||||
|
||||
|
|
@ -68,8 +63,7 @@ var originUrl = urlResolve(window.location.href, true);
|
|||
*
|
||||
*/
|
||||
function urlResolve(url, base) {
|
||||
var href = url,
|
||||
pathname;
|
||||
var href = url;
|
||||
|
||||
if (msie) {
|
||||
// Normalize before parse. Refer Implementation Notes on why this is
|
||||
|
|
@ -80,21 +74,6 @@ function urlResolve(url, base) {
|
|||
|
||||
urlParsingNode.setAttribute('href', href);
|
||||
|
||||
/*
|
||||
* In Windows, on an anchor node on documents loaded from
|
||||
* the filesystem, the browser will return a pathname
|
||||
* prefixed with the drive name ('/C:/path') when a
|
||||
* pathname without a drive is set:
|
||||
* * a.setAttribute('href', '/foo')
|
||||
* * a.pathname === '/C:/foo' //true
|
||||
*
|
||||
* Inside of Angular, we're always using pathnames that
|
||||
* do not include drive names for routing.
|
||||
*/
|
||||
|
||||
pathname = removeWindowsDriveName(urlParsingNode.pathname, url, base);
|
||||
pathname = (pathname.charAt(0) === '/') ? pathname : '/' + pathname;
|
||||
|
||||
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
||||
return {
|
||||
href: urlParsingNode.href,
|
||||
|
|
@ -104,11 +83,12 @@ function urlResolve(url, base) {
|
|||
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
||||
hostname: urlParsingNode.hostname,
|
||||
port: urlParsingNode.port,
|
||||
pathname: pathname
|
||||
pathname: (urlParsingNode.pathname.charAt(0) === '/')
|
||||
? urlParsingNode.pathname
|
||||
: '/' + urlParsingNode.pathname
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a request URL and determine whether this is a same-origin request as the application document.
|
||||
*
|
||||
|
|
@ -121,23 +101,3 @@ function urlIsSameOrigin(requestUrl) {
|
|||
return (parsed.protocol === originUrl.protocol &&
|
||||
parsed.host === originUrl.host);
|
||||
}
|
||||
|
||||
function removeWindowsDriveName (path, url, base) {
|
||||
var firstPathSegmentMatch;
|
||||
|
||||
//Get the relative path from the input URL.
|
||||
if (url.indexOf(base) === 0) {
|
||||
url = url.replace(base, '');
|
||||
}
|
||||
|
||||
/*
|
||||
* The input URL intentionally contains a
|
||||
* first path segment that ends with a colon.
|
||||
*/
|
||||
if (windowsFilePathExp.exec(url)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
firstPathSegmentMatch = windowsFilePathExp.exec(path);
|
||||
return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
|
||||
}
|
||||
|
|
@ -38,7 +38,6 @@ describe('$location', function() {
|
|||
if ($sniffer.msie) return;
|
||||
//reset urlParsingNode
|
||||
urlParsingNode = urlParsingNodePlaceholder;
|
||||
expect(urlParsingNode.pathname).not.toBe('/C:/foo');
|
||||
}));
|
||||
|
||||
|
||||
|
|
@ -324,7 +323,7 @@ describe('$location', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should parse hashband url into path and search', function() {
|
||||
it('should parse hashbang url into path and search', function() {
|
||||
expect(url.protocol()).toBe('http');
|
||||
expect(url.host()).toBe('www.server.org');
|
||||
expect(url.port()).toBe(1234);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
describe('urlUtils', function() {
|
||||
describe('parse', function() {
|
||||
describe('urlResolve', function() {
|
||||
it('should normalize a relative url', function () {
|
||||
expect(urlResolve("foo").href).toMatch(/^https?:\/\/[^/]+\/foo$/);
|
||||
});
|
||||
|
|
@ -14,6 +14,13 @@ describe('urlUtils', function() {
|
|||
expect(parsed.hostname).not.toBe("");
|
||||
expect(parsed.pathname).not.toBe("");
|
||||
});
|
||||
|
||||
|
||||
it('should return pathname as / if empty path provided', function () {
|
||||
//IE counts / as empty, necessary to use / so that pathname is not context.html
|
||||
var parsed = urlResolve('/');
|
||||
expect(parsed.pathname).toBe('/');
|
||||
})
|
||||
});
|
||||
|
||||
describe('isSameOrigin', function() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue