Extend readSources to accept array of source hashes (#918)
authorMartin Grandrath <mg@insfx.com>
Mon, 20 Mar 2017 10:46:02 +0000 (11:46 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Mon, 20 Mar 2017 10:46:02 +0000 (11:46 +0100)
* Extend readSources to accept array of source hashes

This change makes it easier to specify the order in which sources are
concatenated.  See issue jakubpawlowicz/clean-css#908 for details.

README.md
lib/reader/read-sources.js
test/module-test.js

index eecc9c4..6f35013 100644 (file)
--- a/README.md
+++ b/README.md
@@ -415,7 +415,7 @@ Clean-css has an associated command line utility that can be installed separatel
 
 ## How to optimize multiple files?
 
-It can be done either by passing an array of paths, or, when sources are already available, a hash:
+It can be done either by passing an array of paths, or, when sources are already available, a hash or an array of hashes:
 
 ```js
 new CleanCSS().minify(['path/to/file/one', 'path/to/file/two']);
@@ -432,6 +432,15 @@ new CleanCSS().minify({
 });
 ```
 
+```js
+new CleanCSS().minify([
+  {'path/to/file/one': {styles: 'contents of file one'}},
+  {'path/to/file/two': {styles: 'contents of file two'}}
+]);
+```
+
+Passing an array of hashes allows you to explicitly specify the order in which the input files are concatenated. Whereas when you use a single hash the order is determined by the [traversal order of object properties](http://2ality.com/2015/10/property-traversal-order-es6.html).
+
 Important note - any `@import` rules already present in the hash will be resolved in memory.
 
 ## How to process remote `@import`s correctly?
index e12e235..ed8c5a4 100644 (file)
@@ -50,27 +50,38 @@ function fromString(input, context, callback) {
 }
 
 function fromArray(input, context, callback) {
-  var inputAsImports = input.reduce(function (accumulator, uri) {
-    var normalizedUri = normalizeUri(uri);
+  var inputAsImports = input.reduce(function (accumulator, uriOrHash) {
+    if (typeof uriOrHash === 'string') {
+      return addStringSource(uriOrHash, accumulator);
+    } else {
+      return addHashSource(uriOrHash, context, accumulator);
+    }
 
-    accumulator.push(restoreAsImport(normalizedUri));
-    return accumulator;
   }, []);
 
   return fromStyles(inputAsImports.join(''), context, { inline: ['all'] }, callback);
 }
 
 function fromHash(input, context, callback) {
+  var inputAsImports = addHashSource(input, context, []);
+  return fromStyles(inputAsImports.join(''), context, { inline: ['all'] }, callback);
+}
+
+function addStringSource(input, imports) {
+  imports.push(restoreAsImport(normalizeUri(input)));
+  return imports;
+}
+
+function addHashSource(input, context, imports) {
   var uri;
   var normalizedUri;
   var source;
-  var inputAsImports = [];
 
   for (uri in input) {
     source = input[uri];
     normalizedUri = normalizeUri(uri);
 
-    inputAsImports.push(restoreAsImport(normalizedUri));
+    imports.push(restoreAsImport(normalizedUri));
 
     context.sourcesContent[normalizedUri] = source.styles;
 
@@ -79,7 +90,7 @@ function fromHash(input, context, callback) {
     }
   }
 
-  return fromStyles(inputAsImports.join(''), context, { inline: ['all'] }, callback);
+  return imports;
 }
 
 function normalizeUri(uri) {
index 52a1d87..d0e423a 100644 (file)
@@ -829,5 +829,16 @@ vows.describe('module tests').addBatch({
         }
       }
     }
+  },
+  'accepts a list of source files as array of hashes': {
+    'topic': function () {
+      return new CleanCSS().minify([
+        sourcesAsHash(['test/fixtures/partials/one.css']),
+        sourcesAsHash(['test/fixtures/partials/three.css'])
+      ]);
+    },
+    'should give right output': function (minified) {
+      assert.equal(minified.styles, '.one{color:red}.three{background-image:url(test/fixtures/partials/extra/down.gif)}');
+    }
   }
 }).export(module);