mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +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
|
||||
// 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);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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) {
|
||||
var href = url;
|
||||
var href = url,
|
||||
pathname;
|
||||
|
||||
if (msie) {
|
||||
// Normalize before parse. Refer Implementation Notes on why this is
|
||||
// done in two steps on IE.
|
||||
|
|
@ -72,7 +80,23 @@ function urlResolve(url) {
|
|||
|
||||
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 {
|
||||
href: urlParsingNode.href,
|
||||
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
||||
|
|
@ -81,9 +105,15 @@ function urlResolve(url) {
|
|||
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
||||
hostname: urlParsingNode.hostname,
|
||||
port: urlParsingNode.port,
|
||||
pathname: urlParsingNode.pathname && urlParsingNode.pathname.charAt(0) === '/' ?
|
||||
urlParsingNode.pathname : '/' + urlParsingNode.pathname
|
||||
pathname: 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');
|
||||
});
|
||||
|
||||
|
||||
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() {
|
||||
beforeEach(function() {
|
||||
url = new LocationHtml5Url('http://www.domain.com:9877/');
|
||||
|
|
|
|||
Loading…
Reference in a new issue