Fixes #398 - restoring important comments.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Thu, 18 Dec 2014 00:26:22 +0000 (00:26 +0000)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Thu, 18 Dec 2014 00:28:11 +0000 (00:28 +0000)
* Should be rather done on tokenization step. To be improved in 3.1.

History.md
lib/properties/optimizer.js
lib/selectors/source-map-stringifier.js
lib/selectors/stringifier.js
test/integration-test.js
test/source-map-test.js

index 91578be..319f0e9 100644 (file)
@@ -23,6 +23,7 @@
 * Fixed issue [#363](https://github.com/GoalSmashers/clean-css/issues/363) - `rem` units overriding `px`.
 * Fixed issue [#373](https://github.com/GoalSmashers/clean-css/issues/373) - proper background shorthand merging.
 * Fixed issue [#395](https://github.com/GoalSmashers/clean-css/issues/395) - unescaped brackets in data URIs.
+* Fixed issue [#398](https://github.com/GoalSmashers/clean-css/issues/398) - restoring important comments.
 * Fixed issue [#400](https://github.com/GoalSmashers/clean-css/issues/400) - API to accept an array of filenames.
 * Fixed issue [#403](https://github.com/GoalSmashers/clean-css/issues/403) - tracking input files in source maps.
 * Fixed issue [#404](https://github.com/GoalSmashers/clean-css/issues/404) - no state sharing in API.
index 4ae72c4..22e604d 100644 (file)
@@ -238,8 +238,8 @@ module.exports = function Optimizer(options, context) {
         eligibleForCompacting = true;
 
       // FIXME: the check should be gone with #396
-      var property = tokens[i][0].indexOf('__ESCAPED_') === 0 ?
-        tokens[i][0] :
+      var property = !tokens[i][0] && tokens[i][1].indexOf('__ESCAPED_') === 0 ?
+        tokens[i][1] :
         tokens[i][0] + ':' + tokens[i][1];
       tokenized.push({ value: property, metadata: tokens[i][4] });
       list.push(property);
index ddffc2e..f9a7d3e 100644 (file)
@@ -38,9 +38,21 @@ Rebuilder.prototype.relativePathResolver = function (sourcePath, sourceRelativeT
 };
 
 Rebuilder.prototype.rebuildValue = function (list, separator) {
+  var lastEscaped = false;
+
   for (var i = 0, l = list.length; i < l; i++) {
-    this.store(list[i]);
-    this.store(i < l - 1 ? separator : '');
+    var el = list[i];
+
+    if (el.value.indexOf('__ESCAPED_') === 0) {
+      if (!lastEscaped)
+        this.output.pop();
+      this.store(el);
+      lastEscaped = true;
+    } else {
+      this.store(el);
+      this.store(i < l - 1 ? separator : '');
+      lastEscaped = false;
+    }
   }
 };
 
index 685a0cf..baa0010 100644 (file)
@@ -7,9 +7,19 @@ function Stringifier(options, restoreCallback) {
 
 function valueRebuilder(list, separator) {
   var merged = '';
+  var lastEscaped = false;
 
-  for (var i = 0, l = list.length; i < l; i++)
-    merged += list[i].value + (i < l - 1 ? separator : '');
+  for (var i = 0, l = list.length; i < l; i++) {
+    var el = list[i];
+
+    if (el.value.indexOf('__ESCAPED_') === 0) {
+      merged = (lastEscaped ? merged : merged.substring(0, merged.length - 1)) + el.value;
+      lastEscaped = true;
+    } else {
+      merged += list[i].value + (i < l - 1 ? separator : '');
+      lastEscaped = false;
+    }
+  }
 
   return merged;
 }
index 1194761..7f6fff7 100644 (file)
@@ -295,6 +295,14 @@ vows.describe('integration tests').addBatch({
     'with quote marks': [
       '/*"*//* */',
       ''
+    ],
+    'important after value': [
+      'div{color:red!important;/*!comment*/}',
+      'div{color:red!important/*!comment*/}'
+    ],
+    'two important after value': [
+      'div{color:red!important;/*!1*//*!2*/}',
+      'div{color:red!important/*!1*//*!2*/}'
     ]
   }),
   'escaping': cssContext({
index f9fa76c..5359d54 100644 (file)
@@ -663,4 +663,18 @@ vows.describe('source-map')
       }
     }
   })
+  .addBatch({
+    'important comment after a property': {
+      'topic': new CleanCSS({ sourceMap: true }).minify('div { color: #f00 !important; /*!comment*/ }'),
+      'has right output': function (errors, minified) {
+        assert.equal(minified.styles, 'div{color:red!important/*!comment*/}');
+      }
+    },
+    'important comments after a property': {
+      'topic': new CleanCSS({ sourceMap: true }).minify('div { color: #f00 !important; /*!1*//*!2*/ }'),
+      'has right output': function (errors, minified) {
+        assert.equal(minified.styles, 'div{color:red!important/*!1*//*!2*/}');
+      }
+    }
+  })
   .export(module);