aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ng/urlUtils.js40
-rw-r--r--test/ng/locationSpec.js43
2 files changed, 78 insertions, 5 deletions
diff --git a/src/ng/urlUtils.js b/src/ng/urlUtils.js
index e821c08a..51d40f9e 100644
--- a/src/ng/urlUtils.js
+++ b/src/ng/urlUtils.js
@@ -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;
+ }
}
diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js
index 30f2f81a..abd99585 100644
--- a/test/ng/locationSpec.js
+++ b/test/ng/locationSpec.js
@@ -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/');