mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-05 05:34:43 +00:00
fix(urlUtils): urlUtils doesn't return right path for file:// on win
Chrome and other browsers on Windows often append the drive name to the pathname, as described in #4680. This would cause the location service to browse to odd URLs, such as /C:/myfile.html, when opening apps using file://. Fixes #4680
This commit is contained in:
parent
e1254b266d
commit
f925e8caa6
2 changed files with 78 additions and 5 deletions
|
|
@ -7,8 +7,14 @@
|
||||||
// exactly the behavior needed here. There is little value is mocking these out for this
|
// exactly the behavior needed here. There is little value is mocking these out for this
|
||||||
// service.
|
// service.
|
||||||
var urlParsingNode = document.createElement("a");
|
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);
|
var originUrl = urlResolve(window.location.href, true);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Implementation Notes for non-IE browsers
|
* Implementation Notes for non-IE browsers
|
||||||
|
|
@ -27,7 +33,7 @@ var originUrl = urlResolve(window.location.href, true);
|
||||||
* browsers. However, the parsed components will not be set if the URL assigned did not specify
|
* browsers. However, the parsed components will not be set if the URL assigned did not specify
|
||||||
* them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
|
* them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
|
||||||
* work around that by performing the parsing in a 2nd step by taking a previously normalized
|
* work around that by performing the parsing in a 2nd step by taking a previously normalized
|
||||||
* URL (e.g. by assining to a.href) and assigning it a.href again. This correctly populates the
|
* URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the
|
||||||
* properties such as protocol, hostname, port, etc.
|
* properties such as protocol, hostname, port, etc.
|
||||||
*
|
*
|
||||||
* IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one
|
* IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one
|
||||||
|
|
@ -62,7 +68,9 @@ var originUrl = urlResolve(window.location.href, true);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function urlResolve(url) {
|
function urlResolve(url) {
|
||||||
var href = url;
|
var href = url,
|
||||||
|
pathname;
|
||||||
|
|
||||||
if (msie) {
|
if (msie) {
|
||||||
// Normalize before parse. Refer Implementation Notes on why this is
|
// Normalize before parse. Refer Implementation Notes on why this is
|
||||||
// done in two steps on IE.
|
// done in two steps on IE.
|
||||||
|
|
@ -72,7 +80,23 @@ function urlResolve(url) {
|
||||||
|
|
||||||
urlParsingNode.setAttribute('href', href);
|
urlParsingNode.setAttribute('href', href);
|
||||||
|
|
||||||
// $$urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
/*
|
||||||
|
* 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);
|
||||||
|
pathname = (pathname.charAt(0) === '/') ? pathname : '/' + pathname;
|
||||||
|
|
||||||
|
|
||||||
|
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
||||||
return {
|
return {
|
||||||
href: urlParsingNode.href,
|
href: urlParsingNode.href,
|
||||||
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
||||||
|
|
@ -81,9 +105,15 @@ function urlResolve(url) {
|
||||||
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
||||||
hostname: urlParsingNode.hostname,
|
hostname: urlParsingNode.hostname,
|
||||||
port: urlParsingNode.port,
|
port: urlParsingNode.port,
|
||||||
pathname: urlParsingNode.pathname && urlParsingNode.pathname.charAt(0) === '/' ?
|
pathname: pathname
|
||||||
urlParsingNode.pathname : '/' + urlParsingNode.pathname
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function removeWindowsDriveName (path) {
|
||||||
|
var firstPathSegmentMatch;
|
||||||
|
|
||||||
|
firstPathSegmentMatch = windowsFilePathExp.exec(path);
|
||||||
|
return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,49 @@ describe('$location', function() {
|
||||||
jqLite(document).off('click');
|
jqLite(document).off('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('File Protocol', function () {
|
||||||
|
var urlParsingNodePlaceholder;
|
||||||
|
|
||||||
|
beforeEach(inject(function ($sniffer) {
|
||||||
|
if ($sniffer.msie) return;
|
||||||
|
|
||||||
|
urlParsingNodePlaceholder = urlParsingNode;
|
||||||
|
|
||||||
|
//temporarily overriding the DOM element
|
||||||
|
//with output from IE, if not in IE
|
||||||
|
urlParsingNode = {
|
||||||
|
hash : "#/C:/",
|
||||||
|
host : "",
|
||||||
|
hostname : "",
|
||||||
|
href : "file:///C:/base#!/C:/foo",
|
||||||
|
pathname : "/C:/foo",
|
||||||
|
port : "",
|
||||||
|
protocol : "file:",
|
||||||
|
search : "",
|
||||||
|
setAttribute: angular.noop
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
afterEach(inject(function ($sniffer) {
|
||||||
|
if ($sniffer.msie) return;
|
||||||
|
//reset urlParsingNode
|
||||||
|
urlParsingNode = urlParsingNodePlaceholder;
|
||||||
|
expect(urlParsingNode.pathname).not.toBe('/C:/foo');
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should not include the drive name in path() on WIN', function (){
|
||||||
|
//See issue #4680 for details
|
||||||
|
url = new LocationHashbangUrl('file:///base', '#!');
|
||||||
|
url.$$parse('file:///base#!/foo?a=b&c#hash');
|
||||||
|
|
||||||
|
expect(url.path()).toBe('/foo');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('NewUrl', function() {
|
describe('NewUrl', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
url = new LocationHtml5Url('http://www.domain.com:9877/');
|
url = new LocationHtml5Url('http://www.domain.com:9877/');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue