Repository: Polymer/vulcanize
Pull request #408 (2017-01-10 21:28:41)

Fix issue with path rewriting, (especially assetpath), for certain import path combinations
<!--
  Thanks for the PR!

  If this change has a user visible change (including
  bug fixes, new features, etc) please describe the change in
  CHANGELOG.md.

  If the change is an entirely package-internal reshuffling/refactoring
  should the change not be described in the CHANGELOG.

  Consider also updating the README.

  More info: http://keepachangelog.com/en/0.3.0/
 -->

 - [x] CHANGELOG.md has been updated



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd82784..8e65718 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
+## Unreleased
+- Fix for how paths are rewritten in nested import scenarios where paths to same
+  directory were ignored instead of treated as "." for relative path.
+
 ## 1.15.2 - 2016-12-16
 - Fix for how assetpath is set when in the same directory, where assetpath attribute
   for components in same directly were incorrectly set to "/".
diff --git a/lib/pathresolver.js b/lib/pathresolver.js
index 724ee3c..187d021 100644
--- a/lib/pathresolver.js
+++ b/lib/pathresolver.js
@@ -39,6 +39,13 @@ PathResolver.prototype = {
       for (var j = 0, attr; j < constants.URL_ATTR.length; j++) {
         attr = constants.URL_ATTR[j];
         attrValue = dom5.getAttribute(node, attr);
+        // When the path is an empty string value the intent is to represent
+        // in URL-speak "the same path that the current document is at".
+        // We'll set it to '.' which better represents this intent to the
+        // rewrite methods.
+        if (attrValue === '') {
+          attrValue = '.';
+        }
         if (attrValue && !this.isTemplatedUrl(attrValue)) {
           var relUrl;
           if (attr === 'style') {
diff --git a/lib/vulcan.js b/lib/vulcan.js
index 9a918f0..5aff456 100644
--- a/lib/vulcan.js
+++ b/lib/vulcan.js
@@ -222,7 +222,11 @@ Vulcan.prototype = {
   isInsideTemplate: dom5.predicates.parentMatches(
       dom5.predicates.hasTagName('template')),
 
-  flatten: function flatten(tree, isMainDoc) {
+  flatten: function flatten(tree, mainDocUrl) {
+    var isMainDoc = (mainDocUrl === undefined);
+    if (isMainDoc) {
+      mainDocUrl = tree.href;
+    }
     var doc = tree.html.ast;
     var imports = tree.imports;
     var head = dom5.query(doc, matchers.head);
@@ -276,7 +280,7 @@ Vulcan.prototype = {
           continue;
         }
         var bodyFragment = dom5.constructors.fragment();
-        var importDoc = this.flatten(im);
+        var importDoc = this.flatten(im, mainDocUrl);
         // rewrite urls
         this.pathResolver.resolvePaths(importDoc, im.href, tree.href);
         var importHead = dom5.query(importDoc, matchers.head);
@@ -459,7 +463,7 @@ Vulcan.prototype = {
     chain = chain.then(function(){
       return analyzer.metadataTree(target);
     }).then(function(tree) {
-      var flatDoc = this.flatten(tree, true);
+      var flatDoc = this.flatten(tree);
       // make sure there's a <meta charset> in the page to force UTF-8
       var meta = dom5.query(flatDoc, matchers.meta);
       var head = dom5.query(flatDoc, matchers.head);


Test patch:
diff --git a/test/html/assetpath/bower_components/test-component/src/elements/test-b.html b/test/html/assetpath/bower_components/test-component/src/elements/test-b.html
new file mode 100644
index 0000000..5e50565
--- /dev/null
+++ b/test/html/assetpath/bower_components/test-component/src/elements/test-b.html
@@ -0,0 +1,2 @@
+<link rel="import" href="../../test-c.html">
+<dom-module id="test-b"></dom-module>
diff --git a/test/html/assetpath/bower_components/test-component/test-a.html b/test/html/assetpath/bower_components/test-component/test-a.html
new file mode 100644
index 0000000..be9df5c
--- /dev/null
+++ b/test/html/assetpath/bower_components/test-component/test-a.html
@@ -0,0 +1,2 @@
+<link rel="import" href="src/elements/test-b.html">
+<dom-module id="test-a"></dom-module>
diff --git a/test/html/assetpath/bower_components/test-component/test-c.html b/test/html/assetpath/bower_components/test-component/test-c.html
new file mode 100644
index 0000000..acde25f
--- /dev/null
+++ b/test/html/assetpath/bower_components/test-component/test-c.html
@@ -0,0 +1,1 @@
+<dom-module id="test-c"></dom-module>
diff --git a/test/html/assetpath/src/app-main/app-main.html b/test/html/assetpath/src/app-main/app-main.html
new file mode 100644
index 0000000..2f6011f
--- /dev/null
+++ b/test/html/assetpath/src/app-main/app-main.html
@@ -0,0 +1,2 @@
+<link rel="import" href="../../bower_components/test-component/test-a.html">
+<dom-module id="app-main"></dom-module>
diff --git a/test/test.js b/test/test.js
index 14df26d..a1f484f 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1125,6 +1125,25 @@ suite('Vulcan', function() {
       }, {inlineScripts: true});
     });
 
+    test('Assetpath rewriting', function(done) {
+      process('test/html/assetpath/src/app-main/app-main.html', function(err, doc) {
+        if (err) {
+          return done(err);
+        }
+        var domModules = dom5.queryAll(doc, preds.hasTagName('dom-module'));
+        var assetpaths = domModules.map(function(domModule) {
+          return [dom5.getAttribute(domModule, 'id'), dom5.getAttribute(domModule, 'assetpath')];
+        });
+        assert.deepEqual(assetpaths, [
+          ['test-c', '../../bower_components/test-component/'],
+          ['test-b', '../../bower_components/test-component/src/elements/'],
+          ['test-a', '../../bower_components/test-component/'],
+          ['app-main', null]
+        ]);
+        done();
+      });
+    });
+
     test('Imports in templates should not inline', function(done) {
       process('test/html/inside-template.html', function(err, doc) {
         var importMatcher = preds.AND(