From a92ff749b30df71111a7d85eb383f28d086c6732 Mon Sep 17 00:00:00 2001 From: Steve Orvell Date: Fri, 23 Aug 2013 12:22:00 -0700 Subject: [PATCH] Improve relative path resolution; fixes issue #31 --- src/HTMLImports.js | 26 +++++++++++++++++--------- test/html/path.html | 12 +++++++++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/HTMLImports.js b/src/HTMLImports.js index 3df66ba..275e14f 100644 --- a/src/HTMLImports.js +++ b/src/HTMLImports.js @@ -162,7 +162,7 @@ function makeDocument(resource, url) { doc._URL = url; // establish a relative path via var base = doc.createElement('base'); - base.setAttribute('href', document.baseURI); + base.setAttribute('href', document.baseURI || document.URL); doc.head.appendChild(base); // TODO(sorvell): MDV Polyfill intrusion: boostrap template polyfill if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) { @@ -293,7 +293,7 @@ var path = { if (this.isAbsUrl(url)) { return url; } - return path.makeRelPath(path.documentURL, this.resolveUrl(baseUrl, url)); + return this.makeDocumentRelPath(this.resolveUrl(baseUrl, url)); }, isAbsUrl: function(url) { return /(^data:)|(^http[s]?:)|(^\/)/.test(url); @@ -322,15 +322,22 @@ var path = { } return parts.join('/') + search; }, + makeDocumentRelPath: function(url) { + // test url against document to see if we can construct a relative path + path.urlElt.href = url; + // IE does not set host if same as document + if (!path.urlElt.host || + (path.urlElt.host === window.location.host && + path.urlElt.protocol === window.location.protocol)) { + return this.makeRelPath(path.documentURL, path.urlElt.href); + } else { + return url; + } + }, // make a relative path from source to target makeRelPath: function(source, target) { - var s, t; - s = this.compressUrl(source).split("/"); - t = this.compressUrl(target).split("/"); - // bail if target is not relative to source - if (!s.length || s[0] !== t[0]) { - return target; - } + var s = source.split("/"); + var t = target.split("/"); while (s.length && s[0] === t[0]){ s.shift(); t.shift(); @@ -397,6 +404,7 @@ var path = { }; path.documentURL = path.getDocumentUrl(document); +path.urlElt = document.createElement('a'); xhr = xhr || { async: true, diff --git a/test/html/path.html b/test/html/path.html index 59dce3a..c5a99a0 100644 --- a/test/html/path.html +++ b/test/html/path.html @@ -12,7 +12,7 @@ var absBase = parts.join('/'); var l = document.createElement('link'); l.setAttribute('rel', 'import'); - l.href = absBase + '/imports/abs.html'; + l.setAttribute('href', absBase + '/imports/abs.html'); document.head.appendChild(l); @@ -25,6 +25,16 @@ url = 'http://foo/bar?baz="foo/../bar"'; chai.assert.equal(path.compressUrl(url), url, 'query string is not counted in path compression'); + url = '../foo.png'; + chai.assert.equal(path.makeDocumentRelPath(url), url, 'document relative path correctly resolves'); + + url = window.location.host + '/zonk/zim/foo.png'; + chai.assert.equal(path.makeDocumentRelPath(url), url, 'abs / url is relative to document'); + + url = window.location.protocol + '//' + window.location.hostname + ':9999/zonk/zim/foo.png'; + chai.assert.equal(path.makeDocumentRelPath(url), url, 'other host url is absolute'); + + url = '/foo/bar/baz"'; chai.assert.equal(path.compressUrl(url), url, 'compressUrl handles url\'s starting with / as abs'); document.addEventListener('HTMLImportsLoaded', function() {