Fixes #207 - bug in parsing protocol `@import`s.
authorGoalSmashers <jakub@goalsmashers.com>
Sat, 11 Jan 2014 15:56:34 +0000 (16:56 +0100)
committerGoalSmashers <jakub@goalsmashers.com>
Sat, 11 Jan 2014 15:56:34 +0000 (16:56 +0100)
Spaces inside url part of import declaration were incorrectly parsed.

History.md
lib/imports/inliner.js
test/protocol-imports-test.js

index 396c05a..b1539f9 100644 (file)
@@ -11,6 +11,7 @@
 * Fixed issue [#163](https://github.com/GoalSmashers/clean-css/issues/163) - round pixels to 2nd decimal place.
 * Fixed issue [#165](https://github.com/GoalSmashers/clean-css/issues/165) - extra space after trailing parenthesis.
 * Fixed issue [#186](https://github.com/GoalSmashers/clean-css/issues/186) - strip unit from 0rem.
+* Fixed issue [#207](https://github.com/GoalSmashers/clean-css/issues/207) - bug in parsing protocol `@import`s.
 
 [2.0.6 / 2014-01-04](https://github.com/GoalSmashers/clean-css/compare/v2.0.5...v2.0.6)
 ==================
index 6384bfb..29d309c 100644 (file)
@@ -126,17 +126,26 @@ module.exports = function Inliner(context, options) {
   };
 
   var inline = function(data, nextStart, nextEnd, options) {
-    var strippedImport = data
+    var importDeclaration = data
       .substring(data.indexOf(' ', nextStart) + 1, nextEnd)
-      .replace(/^url\(/, '')
-      .replace(/['"]/g, '');
-
-    var separatorIndex = strippedImport.indexOf(' ');
-    var importedFile = strippedImport
-      .substring(0, separatorIndex > 0 ? separatorIndex : strippedImport.length)
-      .replace(')', '');
-    var mediaQuery = strippedImport
-      .substring(importedFile.length + 1)
+      .trim();
+
+    var viaUrl = importDeclaration.indexOf('url(') === 0;
+    var urlStartsAt = viaUrl ? 4 : 0;
+    var isQuoted = /^['"]/.exec(importDeclaration.substring(urlStartsAt, urlStartsAt + 2));
+    var urlEndsAt = isQuoted ?
+      importDeclaration.indexOf(isQuoted[0], urlStartsAt + 1) :
+      importDeclaration.split(' ')[0].length;
+
+    var importedFile = importDeclaration
+      .substring(urlStartsAt, urlEndsAt)
+      .replace(/['"]/g, '')
+      .replace(/\)$/, '')
+      .trim();
+
+    var mediaQuery = importDeclaration
+      .substring(urlEndsAt + 1)
+      .replace(/^\)/, '')
       .trim();
 
     var isRemote = options.isRemote ||
index f0d1a3b..b440a93 100644 (file)
@@ -50,6 +50,25 @@ vows.describe('protocol imports').addBatch({
       nock.restore();
     }
   },
+  'of an existing file with spaces in path': {
+    topic: function() {
+      this.reqMocks = nock('http://fonts.googleapis.com')
+        .get('/css?family=Oleo%20Script%20Swash%20Caps')
+        .reply(200, 'p{font-size:13px}');
+
+      new CleanCSS().minify('@import url(\'//fonts.googleapis.com/css?family=Oleo Script Swash Caps\');', this.callback);
+    },
+    'should not raise errors': function(errors, minified) {
+      assert.isNull(errors);
+    },
+    'should process @import': function(errors, minified) {
+      assert.equal(minified, 'p{font-size:13px}');
+    },
+    teardown: function() {
+      assert.equal(this.reqMocks.isDone(), true);
+      nock.restore();
+    }
+  },
   'of an existing file via HTTPS': {
     topic: function() {
       this.reqMocks = nock('https://goalsmashers.com')