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

refactor($location): move file://+win path fix to $location #5158

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/ng/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array#indexOf doesn't exist on IE8, you need to use indexOf() helper fn we have

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url is a string here

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;
}
};

/**
Expand Down
48 changes: 4 additions & 44 deletions src/ng/urlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);


Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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.
*
Expand All @@ -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;
}
3 changes: 1 addition & 2 deletions test/ng/locationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ describe('$location', function() {
if ($sniffer.msie) return;
//reset urlParsingNode
urlParsingNode = urlParsingNodePlaceholder;
expect(urlParsingNode.pathname).not.toBe('/C:/foo');
}));


Expand Down Expand Up @@ -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);
Expand Down
9 changes: 8 additions & 1 deletion test/ng/urlUtilsSpec.js
Original file line number Diff line number Diff line change
@@ -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$/);
});
Expand All @@ -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() {
Expand Down