Repository: Polymer/vulcanize
Pull request #397 (2016-11-09 11:01:46)

assetpath in same directory fix
<!--
  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/
 -->

Fix to Issue #368. This issue occurs when the entry point file imports a component from the same directory, the assetpath attribute for the component gets set to '/', this in turn results in the wrong value being returned from the resolveUrl function.

The fix makes it so the assetpath is set to an empty string. Could also be './' I wasn't sure which would be best. 


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f8acb9..ed502b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,18 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## Unreleased
 
-## 1.15.1 - 2016-12-16
-- Amended README and minor text fixes to CHANGELOG post release.
-
-## 1.15.0 - 2016-12-16
-- Fixed: Preserve style ordering when moving imports and links out of head tag.
-- Don't actually move anything out of head until an html import is encountered.
-
-## 1.14.12 - 2016-11-16
-- Removed update-notifier dependency and functionality
-- Fixed: Stopped moving links with certain rels out of the head tag to avoid breaking
-  favicons, manifests, and other such features.
-- Speed enhancements
+<!-- New PRs should document their changes here. -->
+
+## 1.14.12 - 2016-11-01
+- Fix for how assetpath is set when in the same directory.
 
 ## 1.14.11 - 2016-04-11
 - Radically simpler inlining design. Move all imports and scripts into document
diff --git a/README.md b/README.md
index abfee51..fbd816a 100644
--- a/README.md
+++ b/README.md
@@ -156,7 +156,7 @@ has to make a few compromises to achieve that same script execution order.
 
 1. Contents of all HTML Import documents will be moved to `<body>`
 
-1. Any scripts or styles, inline or linked, which occur after a `<link rel="import">` node in `<head>` will be moved to `<body>` after the contents of the HTML Import.
+1. Any scripts after a `<link rel="import">` node in `<head>` will be moved to `<body>` after the contents of the HTML Import.
 
 ## What happened to [feature] from 0.X?
 - `--csp` mode has been moved into [crisper](https://github.com/PolymerLabs/crisper)
diff --git a/lib/matchers.js b/lib/matchers.js
index bcbd329..ea1fd37 100644
--- a/lib/matchers.js
+++ b/lib/matchers.js
@@ -43,15 +43,6 @@ var polymerExternalStyle = p.AND(
   p.hasAttrValue('type', 'css')
 );
 
-var htmlImport = p.AND(
-  p.hasTagName('link'),
-  p.hasAttrValue('rel', 'import'),
-  p.OR(
-    p.NOT(p.hasAttr('type')),
-    p.hasAttrValue('type', 'text/html')
-  )
-);
-
 var styleMatcher = p.AND(
   p.hasTagName('style'),
   p.OR(
@@ -89,7 +80,6 @@ module.exports = {
   urlAttrs: urlAttrs,
   targetMatcher: targetMatcher,
   polymerExternalStyle: polymerExternalStyle,
-  htmlImport: htmlImport,
   JS: jsMatcher,
   CSS: styleMatcher,
   CSS_LINK: externalStyle,
diff --git a/lib/pathresolver.js b/lib/pathresolver.js
index 9927248..724ee3c 100644
--- a/lib/pathresolver.js
+++ b/lib/pathresolver.js
@@ -45,7 +45,7 @@ PathResolver.prototype = {
             relUrl = this.rewriteURL(importUrl, mainDocUrl, attrValue);
           } else {
             relUrl = this.rewriteRelPath(importUrl, mainDocUrl, attrValue);
-            if (attr === 'assetpath' && relUrl.slice(-1) !== '/') {
+            if (attr === 'assetpath' && relUrl.length > 0 && relUrl.slice(-1) !== '/') {
               relUrl += '/';
             }
           }
diff --git a/lib/vulcan.js b/lib/vulcan.js
index 9a918f0..d335032 100644
--- a/lib/vulcan.js
+++ b/lib/vulcan.js
@@ -177,25 +177,12 @@ Vulcan.prototype = {
   },
 
   moveToBodyMatcher: dom5.predicates.AND(
-    dom5.predicates.NOT(
-        dom5.predicates.parentMatches(
-            dom5.predicates.hasTagName('template'))),
     dom5.predicates.OR(
       dom5.predicates.hasTagName('script'),
-      dom5.predicates.hasTagName('link'),
-      matchers.CSS
+      dom5.predicates.hasTagName('link')
     ),
     dom5.predicates.NOT(
-      dom5.predicates.OR(
-        matchers.polymerExternalStyle,
-        dom5.predicates.hasAttrValue('rel', 'dns-prefetch'),
-        dom5.predicates.hasAttrValue('rel', 'icon'),
-        dom5.predicates.hasAttrValue('rel', 'manifest'),
-        dom5.predicates.hasAttrValue('rel', 'preconnect'),
-        dom5.predicates.hasAttrValue('rel', 'prefetch'),
-        dom5.predicates.hasAttrValue('rel', 'preload'),
-        dom5.predicates.hasAttrValue('rel', 'prerender')
-      )
+      matchers.polymerExternalStyle
     )
   ),
 
@@ -219,9 +206,6 @@ Vulcan.prototype = {
     return false;
   },
 
-  isInsideTemplate: dom5.predicates.parentMatches(
-      dom5.predicates.hasTagName('template')),
-
   flatten: function flatten(tree, isMainDoc) {
     var doc = tree.html.ast;
     var imports = tree.imports;
@@ -243,28 +227,15 @@ Vulcan.prototype = {
     } else {
       moveTarget = dom5.constructors.fragment();
     }
-    var htmlImportEncountered = false;
-
-    // Once we encounter an html import, we need to move things into the body,
-    // because html imports contain things that can't be in document
-    // head.
-    dom5.queryAll(head, this.moveToBodyMatcher).forEach(function(n) {
-      if (!htmlImportEncountered && matchers.htmlImport(n)) {
-        htmlImportEncountered = true;
-      }
-      if (htmlImportEncountered) {
-        this.removeElementAndNewline(n);
-        dom5.append(moveTarget, n);
-      }
+    head.childNodes.filter(this.moveToBodyMatcher).forEach(function(n) {
+      this.removeElementAndNewline(n);
+      dom5.append(moveTarget, n);
     }, this);
     this.prepend(body, moveTarget);
     if (imports) {
       for (var i = 0, im, thisImport; i < imports.length; i++) {
         im = imports[i];
         thisImport = importNodes[i];
-        if (this.isInsideTemplate(thisImport)) {
-          continue;
-        }
         if (this.isDuplicateImport(im) || this.isStrippedImport(im)) {
           this.removeElementAndNewline(thisImport);
           continue;
diff --git a/package.json b/package.json
index cdf1ba8..3e16f1f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "vulcanize",
-  "version": "1.15.1",
+  "version": "1.14.11",
   "description": "Process Web Components into one output file",
   "main": "lib/vulcan.js",
   "bin": {


Test patch:
diff --git a/test/html/default.html b/test/html/default.html
index b722c55..ab4559a 100644
--- a/test/html/default.html
+++ b/test/html/default.html
@@ -11,7 +11,6 @@
 <html lang="en">
 <head>
   <meta charset="UTF-8">
-  <link rel="icon" href="/favicon.ico">
   <link rel="stylesheet" href="imports/regular-style.css">
   <link rel="import" href="imports/simple-import.html">
   <link rel="import" href="imports/simple-import.html">
diff --git a/test/html/imports/doc-linked-style.css b/test/html/imports/doc-linked-style.css
deleted file mode 100644
index 8220d65..0000000
--- a/test/html/imports/doc-linked-style.css
+++ /dev/null
@@ -1,1 +0,0 @@
-.from-doc-linked-style { color: blue; }
diff --git a/test/html/imports/import-linked-style.css b/test/html/imports/import-linked-style.css
deleted file mode 100644
index fb146a5..0000000
--- a/test/html/imports/import-linked-style.css
+++ /dev/null
@@ -1,1 +0,0 @@
-.from-import-linked-style { color: brown; }
diff --git a/test/html/imports/style-order-test-import.html b/test/html/imports/style-order-test-import.html
deleted file mode 100644
index 82711f8..0000000
--- a/test/html/imports/style-order-test-import.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<link rel="stylesheet" href="import-linked-style.css">
-<style type="text/css">
-  .from-import-inline-style { color: purple; }
-</style>
diff --git a/test/html/style-order-test-doc.html b/test/html/style-order-test-doc.html
deleted file mode 100644
index e5dbd22..0000000
--- a/test/html/style-order-test-doc.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<!--
-    @license
-    Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
-    This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
-    The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
-    The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
-    Code distributed by Google as part of the polymer project is also
-    subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
--->
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <link rel="stylesheet" href="imports/doc-linked-style.css">
-  <link rel="import" href="imports/style-order-test-import.html">
-  <title>Sample Build</title>
-  <style type="text/css">
-    .from-style-in-doc-head { color: red; }
-  </style>
-</head>
-<body>
-  <style type="text/css">
-    .from-style-in-doc-body { color: green; }
-  </style>
-</body>
-</html>
diff --git a/test/test.js b/test/test.js
index 0519484..4989445 100644
--- a/test/test.js
+++ b/test/test.js
@@ -265,6 +265,29 @@ suite('Path Resolver', function() {
     assert.equal(actual, base, 'templated urls');
   });
 
+  test('Rewrite assetpath in same directory', function() {
+    var html = [
+      '<dom-module id="my-element" assetpath="./">',
+      '<template>',
+      '</template>',
+      '</dom-module>',
+      '<script>Polymer({is: "my-element"})</script>'
+    ].join('\n');
+
+    var expected = [
+      '<html><head></head><body><dom-module id="my-element" assetpath="">',
+      '<template>',
+      '</template>',
+      '</dom-module>',
+      '<script>Polymer({is: "my-element"})</script></body></html>'
+    ].join('\n');
+
+    var ast = parse(html);
+    pathresolver.resolvePaths(ast, inputPath, inputPath);
+
+    var actual = serialize(ast);
+    assert.equal(actual, expected, 'relative');
+  });
 });
 
 suite('Vulcan', function() {
@@ -313,21 +336,6 @@ suite('Vulcan', function() {
       });
     });
 
-    test('non-import links are left in head', function(done) {
-      var nonImportLinks = preds.AND(
-        preds.hasTagName('link'),
-        preds.NOT(preds.hasAttrValue('rel', 'import'))
-      );
-      process(inputPath, function(err, doc) {
-        if (err) {
-          return done(err);
-        }
-        var head = dom5.query(doc, preds.hasTagName('head'));
-        assert.isAbove(dom5.queryAll(head, nonImportLinks).length, 0);
-        done();
-      });
-    });
-
     test('svg is nested correctly', function(done) {
       process(inputPath, function(err, doc) {
         if (err) {
@@ -811,7 +819,7 @@ suite('Vulcan', function() {
         }
         var links = dom5.queryAll(doc, linkMatcher);
         // one duplicate import is removed
-        assert.equal(links.length, 3);
+        assert.equal(links.length, 2);
         done();
       };
       process('test/html/default.html', callback, options);
@@ -1004,27 +1012,6 @@ suite('Vulcan', function() {
       };
       process('test/html/inline-styles.html', callback, options);
     });
-
-    test('Inlined styles have original order preserved', function(done) {
-      var callback = function(err, doc) {
-        if (err) {
-          return done(err);
-        }
-        var styles = dom5.queryAll(doc, dom5.predicates.hasTagName('style'));
-        var rules = styles.map(function(s) {
-          return dom5.serialize(s).trim();
-        }).join('\n').match(/\.[a-z-]+/g);
-        assert.deepEqual(rules, [
-          '.from-doc-linked-style',
-          '.from-import-linked-style',
-          '.from-import-inline-style',
-          '.from-style-in-doc-head',
-          '.from-style-in-doc-body'
-        ]);
-        done();
-      };
-      process('test/html/style-order-test-doc.html', callback, options);
-    });
   });
 
   suite('Add import', function(){