Adds pulling input source maps from source map comment.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Tue, 11 Nov 2014 19:48:28 +0000 (19:48 +0000)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Mon, 8 Dec 2014 09:39:15 +0000 (09:39 +0000)
lib/clean.js
test/data/source-maps/sample.map [new file with mode: 0644]
test/source-map-test.js

index d0c1f9d..7be19d3 100644 (file)
@@ -18,6 +18,11 @@ var UrlsProcessor = require('./text/urls-processor');
 
 var Compatibility = require('./utils/compatibility');
 
+var fs = require('fs');
+var path = require('path');
+
+var SOURCE_MAP_MARKER = '/*# sourceMappingURL=';
+
 var CleanCSS = module.exports = function CleanCSS(options) {
   options = options || {};
 
@@ -57,6 +62,9 @@ CleanCSS.prototype.minify = function(data, callback) {
   if (Buffer.isBuffer(data))
     data = data.toString();
 
+  if (data.indexOf(SOURCE_MAP_MARKER) > 0)
+    overrideSourceMap(self.options, data);
+
   if (options.processImport || data.indexOf('@shallow') > 0) {
     // inline all imports
     var runner = callback ?
@@ -76,6 +84,12 @@ CleanCSS.prototype.minify = function(data, callback) {
   }
 };
 
+function overrideSourceMap(options, source) {
+  var markerAt = source.indexOf(SOURCE_MAP_MARKER);
+  var inputMapPath = source.substring(markerAt + SOURCE_MAP_MARKER.length, source.indexOf('*/', markerAt)).trim();
+  options.sourceMap = fs.readFileSync(path.join(options.root || '', inputMapPath), 'utf-8');
+}
+
 function runMinifier(callback, self) {
   return function (data) {
     data = self.options.debug ?
diff --git a/test/data/source-maps/sample.map b/test/data/source-maps/sample.map
new file mode 100644 (file)
index 0000000..dab8bff
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["styles.less"],"names":[],"mappings":"AAAA,GACE;EACE,UAAA","file":"styles.css"}
\ No newline at end of file
index 8d94c98..e5e9fb7 100644 (file)
@@ -2,7 +2,10 @@ var vows = require('vows');
 var assert = require('assert');
 var CleanCSS = require('../index');
 
-var inputSourceMap = '{"version":3,"sources":["styles.less"],"names":[],"mappings":"AAAA,GACE;EACE,UAAA","file":"styles.css"}';
+var fs = require('fs');
+var path = require('path');
+var inputMapPath = path.join('test', 'data', 'source-maps', 'sample.map');
+var inputMap = fs.readFileSync(inputMapPath, 'utf-8');
 
 vows.describe('source-map')
   .addBatch({
@@ -198,7 +201,63 @@ vows.describe('source-map')
   })
   .addBatch({
     'input map as string': {
-      'topic': new CleanCSS({ sourceMap: inputSourceMap }).minify('div > a {\n  color: red;\n}'),
+      'topic': new CleanCSS({ sourceMap: inputMap }).minify('div > a {\n  color: red;\n}'),
+      'should have 2 mappings': function (minified) {
+        assert.equal(2, minified.sourceMap._mappings.length);
+      },
+      'should have selector mapping': function (minified) {
+        var mapping = {
+          generatedLine: 1,
+          generatedColumn: 1,
+          originalLine: 1,
+          originalColumn: 1,
+          source: 'styles.less',
+          name: 'div>a'
+        };
+        assert.deepEqual(mapping, minified.sourceMap._mappings[0]);
+      },
+      'should have _color:red_ mapping': function (minified) {
+        var mapping = {
+          generatedLine: 1,
+          generatedColumn: 7,
+          originalLine: 3,
+          originalColumn: 4,
+          source: 'styles.less',
+          name: 'color:red'
+        };
+        assert.deepEqual(mapping, minified.sourceMap._mappings[1]);
+      }
+    },
+    'input map from source': {
+      'topic': new CleanCSS().minify('div > a {\n  color: red;\n}/*# sourceMappingURL=' + inputMapPath + ' */'),
+      'should have 2 mappings': function (minified) {
+        assert.equal(2, minified.sourceMap._mappings.length);
+      },
+      'should have selector mapping': function (minified) {
+        var mapping = {
+          generatedLine: 1,
+          generatedColumn: 1,
+          originalLine: 1,
+          originalColumn: 1,
+          source: 'styles.less',
+          name: 'div>a'
+        };
+        assert.deepEqual(mapping, minified.sourceMap._mappings[0]);
+      },
+      'should have _color:red_ mapping': function (minified) {
+        var mapping = {
+          generatedLine: 1,
+          generatedColumn: 7,
+          originalLine: 3,
+          originalColumn: 4,
+          source: 'styles.less',
+          name: 'color:red'
+        };
+        assert.deepEqual(mapping, minified.sourceMap._mappings[1]);
+      }
+    },
+    'input map from source with root': {
+      'topic': new CleanCSS({ root: path.dirname(inputMapPath) }).minify('div > a {\n  color: red;\n}/*# sourceMappingURL=sample.map */'),
       'should have 2 mappings': function (minified) {
         assert.equal(2, minified.sourceMap._mappings.length);
       },