Fixes #156 - makes inliner ignore @import inside comments
authorSimon Altschuler <simon@altschuler.dk>
Mon, 28 Oct 2013 20:17:21 +0000 (21:17 +0100)
committerSimon Altschuler <simon@altschuler.dk>
Mon, 28 Oct 2013 20:26:01 +0000 (21:26 +0100)
lib/imports/inliner.js
test/unit-test.js

index 2a1ecd1..e1e694d 100644 (file)
@@ -9,6 +9,7 @@ module.exports = function Inliner() {
     var nextStart = 0;
     var nextEnd = 0;
     var cursor = 0;
+    var isComment = commentScanner(data);
 
     options.relativeTo = options.relativeTo || options.root;
     options._baseRelativeTo = options._baseRelativeTo || options.relativeTo;
@@ -19,6 +20,11 @@ module.exports = function Inliner() {
       if (nextStart == -1)
         break;
 
+      if (isComment(nextStart)) {
+        cursor = nextStart + 1;
+        continue;
+      }
+
       nextEnd = data.indexOf(';', nextStart);
       if (nextEnd == -1)
         break;
@@ -33,6 +39,52 @@ module.exports = function Inliner() {
       data;
   };
 
+  var commentScanner = function(data) {
+    var commentRegex = /(\/\*(?!\*\/)[\s\S]*?\*\/)/;
+    var lastEndIndex = 0;
+    var noComments = false;
+
+    // test whether an index is located within a comment
+    var scanner = function(idx) {
+      var comment;
+      var localStartIndex = 0;
+      var localEndIndex = 0;
+      var globalStartIndex = 0;
+      var globalEndIndex = 0;
+
+      // return if we know there are no more comments
+      if (noComments)
+        return false;
+
+      comment = data.match(commentRegex);
+
+      if (!comment) {
+        noComments = true;
+        return false;
+      }
+
+      // get the indexes relative to the current data chunk
+      localStartIndex = comment.index;
+      localEndIndex = localStartIndex + comment[0].length;
+
+      // calculate the indexes relative to the full original data
+      globalEndIndex = localEndIndex + lastEndIndex;
+      globalStartIndex = globalEndIndex - comment[0].length;
+
+      // chop off data up to and including current comment block
+      data = data.substring(localEndIndex);
+      lastEndIndex = globalEndIndex;
+
+      // re-run scan if comment ended before the idx
+      if (globalEndIndex < idx)
+        return scanner(idx);
+
+      return globalEndIndex > idx && idx > globalStartIndex;
+    };
+
+    return scanner;
+  };
+
   var inlinedFile = function(data, nextStart, nextEnd, options) {
     var strippedImport = data
       .substring(data.indexOf(' ', nextStart) + 1, nextEnd)
index 0faf673..5f4997f 100644 (file)
@@ -981,6 +981,18 @@ title']",
       '/* @import url(test/data/partials/five.css); */a { color: red; }',
       'a{color:red}'
     ],
+    'used arbitrarily in comment': [
+      '/* @import foo */a { color: red; }',
+      'a{color:red}'
+    ],
+    'used arbitrarily in comment multiple times': [
+      '/* @import foo */a { color: red; }\n/* @import bar */p { color: red; }',
+      'a{color:red}p{color:red}'
+    ],
+    'used arbitrarily in comment including unrelated comment': [
+      '/* foo */a { color: red; }/* bar *//* @import */',
+      'a{color:red}'
+    ],
     'of a file with a comment': [
       '@import url(test/data/partials/comment.css);',
       ''