Splits `inliner` option in two.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Mon, 26 Dec 2016 15:03:11 +0000 (16:03 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Mon, 26 Dec 2016 15:35:10 +0000 (16:35 +0100)
* `{ inliner: { request: ... } }` becomes `{ inlineRequest: ... }`;
* `{ inliner: { timeout: N } }` becomes `{ inlineTimeout: N }`;
* `--timeout` becomes `--inline-timeout`.

Why:

* To relate it directly to the new `inline` option.
* Also `--timeout` option relates to `@import` inlining only
  so it should not be "global".

History.md
README.md
bin/cleancss
lib/clean.js
lib/reader/apply-source-maps.js
lib/reader/load-original-sources.js
lib/reader/load-remote-resource.js
lib/reader/read-sources.js
test/binary-test.js
test/protocol-imports-test.js
test/source-map-test.js

index 6b9c447..ae47b84 100644 (file)
@@ -7,6 +7,7 @@
 * Replaces the old tokenizer with a new one which doesn't use any escaping.
 * Replaces the old `@import` inlining with one on top of the new tokenizer.
 * Simplifies URL rebasing with a single `rebaseTo` option in API or inferred from `--output` in CLI.
+* Splits `inliner` option into `inlineRequest` and `inlineTimeout`.
 * Fixed issue [#209](https://github.com/jakubpawlowicz/clean-css/issues/209) - adds output formatting via `beautify` flag.
 * Fixed issue [#432](https://github.com/jakubpawlowicz/clean-css/issues/432) - adds URLs normalization.
 * Fixed issue [#657](https://github.com/jakubpawlowicz/clean-css/issues/657) - adds property name validation.
index a11616e..f8f752a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -32,6 +32,8 @@ There will be some breaking changes:
 * `roundingPrecision` is disabled by default
 * `roundingPrecision` applies to **all** units now, not only `px` as in 3.x;
 * `processImport` and `processImportFrom` are merged into `inline` option which defaults to `local`. Remote `@import` rules are **NOT** inlined by default anymore.
+* renames CLI `--timeout` option to `--inline-timeout`;
+* splits API `inliner: { request: ..., timeout: ... }` option into `inlineRequest` and `inlineTimeout` options;
 
 Please note this list is not final. You are more than welcome to comment these changes in [4.0 release discussion](https://github.com/jakubpawlowicz/clean-css/issues/842) thread.
 
@@ -61,9 +63,9 @@ cleancss [options] source-file, [source-file, ...]
 -c, --compatibility [ie7|ie8]  Force compatibility mode (see Readme for advanced examples)
 -d, --debug                    Shows debug information (minification time & compression efficiency)
 -o, --output [output-file]     Use [output-file] as output instead of STDOUT
--t, --timeout [seconds]        Per connection timeout when fetching remote @imports (defaults to 5 seconds)
 --beautify                     Formats output CSS by using indentation and one rule or property per line
 --inline [rules]               Enables inlining for listed sources (defaults to `local`)
+--inline-timeout [seconds]     Per connection timeout when fetching remote stylesheets (defaults to 5 seconds)
 --rounding-precision [n]       Rounds pixel values to `N` decimal places. `off` disables rounding (defaults to `off`)
 --s0                           Remove all special comments, i.e. /*! comment */
 --s1                           Remove all special comments but the first one
@@ -128,7 +130,8 @@ CleanCSS constructor accepts a hash as a parameter, i.e.,
 * `benchmark` - turns on benchmarking mode measuring time spent on cleaning up (run `npm run bench` to see example)
 * `compatibility` - enables compatibility mode, see [below for more examples](#how-to-set-a-compatibility-mode)
 * `inline` - whether to inline `@import` rules, can be `['all']`, `['local']` (default), `['remote']`, or a blacklisted domain/path e.g. `['!fonts.googleapis.com']`
-* `inliner` - a hash of options for `@import` inliner, see [test/protocol-imports-test.js](https://github.com/jakubpawlowicz/clean-css/blob/master/test/protocol-imports-test.js#L372) for examples, or [this comment](https://github.com/jakubpawlowicz/clean-css/issues/612#issuecomment-119594185) for a proxy use case.
+* `inlineRequest` - an object with [HTTP(S) request options](https://nodejs.org/api/http.html#http_http_request_options_callback) for inlining remote `@import` rules
+* `inlineTimeout` - an integer denoting a number of milliseconds after which inlining a remote `@import` fails (defaults to 5000 ms)
 * `keepBreaks` - whether to keep line breaks (default is false)
 * `keepSpecialComments` - `*` for keeping all (default), `1` for keeping first one only, `0` for removing all
 * `mediaMerging` - whether to merge `@media` at-rules (default is true)
index 9e09004..27136aa 100755 (executable)
@@ -19,9 +19,9 @@ commands
   .option('-c, --compatibility [ie7|ie8]', 'Force compatibility mode (see Readme for advanced examples)')
   .option('-d, --debug', 'Shows debug information (minification time & compression efficiency)')
   .option('-o, --output [output-file]', 'Use [output-file] as output instead of STDOUT')
-  .option('-t, --timeout [seconds]', 'Per connection timeout when fetching remote @imports (defaults to 5 seconds)')
   .option('--beautify', 'Formats output CSS by using indentation and one rule or property per line')
   .option('--inline [rules]', 'Enables inlining for listed sources (defaults to `local`)')
+  .option('--inline-timeout [seconds]', 'Per connection timeout when fetching remote stylesheets (defaults to 5 seconds)', parseFloat)
   .option('--rounding-precision [n]', 'Rounds pixel values to `N` decimal places. -1 disables rounding (defaults to -1)')
   .option('--s0', 'Remove all special comments, i.e. /*! comment */')
   .option('--s1', 'Remove all special comments but the first one')
@@ -66,7 +66,7 @@ var options = {
   beautify: commands.beautify,
   compatibility: commands.compatibility,
   inline: commands.inline || 'local',
-  inliner: commands.timeout ? { timeout: parseFloat(commands.timeout) * 1000 } : undefined,
+  inlineTimeout: commands.inlineTimeout * 1000,
   keepBreaks: !!commands.keepLineBreaks,
   keepSpecialComments: commands.s0 ? 0 : (commands.s1 ? 1 : '*'),
   mediaMerging: commands.skipMediaMerging ? false : true,
index 7108104..584e2ad 100644 (file)
@@ -31,7 +31,8 @@ var CleanCSS = module.exports = function CleanCSS(options) {
     benchmark: options.benchmark,
     compatibility: compatibility(options.compatibility),
     inline: inlineOptionsFrom(options.inline),
-    inliner: options.inliner || {},
+    inlineRequest: options.inlineRequest || {},
+    inlineTimeout: options.inlineTimeout || DEFAULT_TIMEOUT,
     keepBreaks: options.keepBreaks || false,
     keepSpecialComments: 'keepSpecialComments' in options ? options.keepSpecialComments : '*',
     mediaMerging: undefined === options.mediaMerging ? true : !!options.mediaMerging,
@@ -45,11 +46,10 @@ var CleanCSS = module.exports = function CleanCSS(options) {
     sourceMapInlineSources: !!options.sourceMapInlineSources
   };
 
-  this.options.inliner.timeout = this.options.inliner.timeout || DEFAULT_TIMEOUT;
-  this.options.inliner.request = override(
+  this.options.inlineRequest = override(
     /* jshint camelcase: false */
     proxyOptionsFrom(process.env.HTTP_PROXY || process.env.http_proxy),
-    this.options.inliner.request || {}
+    this.options.inlineRequest
   );
 };
 
index de58bea..1066b1e 100644 (file)
@@ -18,7 +18,8 @@ function applySourceMaps(tokens, context, callback) {
     callback: callback,
     index: 0,
     inline: context.options.inline,
-    inliner: context.options.inliner,
+    inlineRequest: context.options.inlineRequest,
+    inlineTimeout: context.options.inlineTimeout,
     inputSourceMapTracker: context.inputSourceMapTracker,
     localOnly: context.localOnly,
     processedTokens: [],
@@ -145,7 +146,7 @@ function loadInputSourceMapFromRemoteUri(uri, applyContext, whenLoaded) {
     return whenLoaded(null);
   }
 
-  loadRemoteResource(uri, applyContext.inliner, function (error, body) {
+  loadRemoteResource(uri, applyContext.inlineRequest, applyContext.inlineTimeout, function (error, body) {
     if (error) {
       applyContext.warnings.push('Missing source map at "' + uri + '" - ' + error);
       return whenLoaded(null);
index 1bf5508..735dd56 100644 (file)
@@ -11,7 +11,8 @@ function loadOriginalSources(context, callback) {
     callback: callback,
     index: 0,
     inline: context.options.inline,
-    inliner: context.options.inliner,
+    inlineRequest: context.options.inlineRequest,
+    inlineTimeout: context.options.inlineTimeout,
     localOnly: context.localOnly,
     rebaseTo: context.options.rebaseTo,
     sourcesContent: context.sourcesContent,
@@ -91,7 +92,7 @@ function loadOriginalSourceFromRemoteUri(uri, loadContext, whenLoaded) {
     return whenLoaded(null);
   }
 
-  loadRemoteResource(uri, loadContext.inliner, function (error, content) {
+  loadRemoteResource(uri, loadContext.inlineRequest, loadContext.inlineTimeout, function (error, content) {
     if (error) {
       loadContext.warnings.push('Missing original source at "' + uri + '" - ' + error);
     }
index 371a20a..04e2dab 100644 (file)
@@ -9,8 +9,8 @@ var override = require('../utils/override');
 
 var HTTP_PROTOCOL = 'http:';
 
-function loadRemoteResource(uri, inlinerOptions, callback) {
-  var proxyProtocol = inlinerOptions.request.protocol || inlinerOptions.request.hostname;
+function loadRemoteResource(uri, inlineRequest, inlineTimeout, callback) {
+  var proxyProtocol = inlineRequest.protocol || inlineRequest.hostname;
   var errorHandled = false;
   var requestOptions;
   var fetch;
@@ -21,12 +21,12 @@ function loadRemoteResource(uri, inlinerOptions, callback) {
 
   requestOptions = override(
     url.parse(uri),
-    inlinerOptions.request || {}
+    inlineRequest || {}
   );
 
-  if (inlinerOptions.request.hostname !== undefined) {
+  if (inlineRequest.hostname !== undefined) {
     // overwrite as we always expect a http proxy currently
-    requestOptions.protocol = inlinerOptions.request.protocol || HTTP_PROTOCOL;
+    requestOptions.protocol = inlineRequest.protocol || HTTP_PROTOCOL;
     requestOptions.path = requestOptions.href;
   }
 
@@ -42,7 +42,7 @@ function loadRemoteResource(uri, inlinerOptions, callback) {
       return callback(res.statusCode, null);
     } else if (res.statusCode > 299) {
       movedUri = url.resolve(uri, res.headers.location);
-      return loadRemoteResource(movedUri, inlinerOptions, callback);
+      return loadRemoteResource(movedUri, inlineRequest, inlineTimeout, callback);
     }
 
     res.on('data', function (chunk) {
@@ -69,7 +69,7 @@ function loadRemoteResource(uri, inlinerOptions, callback) {
     errorHandled = true;
     callback('timeout', null);
   })
-  .setTimeout(inlinerOptions.timeout);
+  .setTimeout(inlineTimeout);
 }
 
 module.exports = loadRemoteResource;
index fc6f41e..9e68c64 100644 (file)
@@ -148,7 +148,8 @@ function inline(tokens, externalContext, parentInlinerContext, callback) {
     externalContext: externalContext,
     inlinedStylesheets: parentInlinerContext.inlinedStylesheets || externalContext.inlinedStylesheets,
     inline: parentInlinerContext.inline,
-    inlinerOptions: externalContext.options.inliner,
+    inlineRequest: externalContext.options.inlineRequest,
+    inlineTimeout: externalContext.options.inlineTimeout,
     isRemote: parentInlinerContext.isRemote || false,
     localOnly: externalContext.localOnly,
     outputTokens: [],
@@ -254,7 +255,7 @@ function inlineRemoteStylesheet(uri, mediaQuery, metadata, inlinerContext) {
 
   return isLoaded ?
     whenLoaded(null, inlinerContext.externalContext.sourcesContent[uri]) :
-    loadRemoteResource(uri, inlinerContext.inlinerOptions, whenLoaded);
+    loadRemoteResource(uri, inlinerContext.inlineRequest, inlinerContext.inlineTimeout, whenLoaded);
 }
 
 function inlineLocalStylesheet(uri, mediaQuery, metadata, inlinerContext) {
index 7d157d3..ce8d408 100644 (file)
@@ -336,7 +336,7 @@ vows.describe('./bin/cleancss')
           setTimeout(function () {}, 1000);
         });
         this.server.listen('24682', function () {
-          exec('echo "' + source + '" | ./bin/cleancss --timeout 0.01 --inline all', self.callback);
+          exec('echo "' + source + '" | ./bin/cleancss --inline all --inline-timeout 0.01', self.callback);
         });
       },
       'should raise warning': function (error, stdout, stderr) {
index 7a7474a..9f466f7 100644 (file)
@@ -417,10 +417,8 @@ vows.describe('protocol imports').addBatch({
 
       new CleanCSS({
         inline: 'all',
-        inliner: {
-          request: {
-            method: 'POST'
-          }
+        inlineRequest: {
+          method: 'POST'
         }
       }).minify('@import url(http://127.0.0.1/computed.css);a{color:red}', this.callback);
     },
@@ -556,9 +554,7 @@ vows.describe('protocol imports').addBatch({
       this.server.listen(port, function () {
         new CleanCSS({
           inline: 'all',
-          inliner: {
-            timeout: timeout
-          }
+          inlineTimeout: timeout
         }).minify('@import url(http://localhost:' + port + '/timeout.css);a{color:red}', self.callback);
       });
       enableDestroy(self.server);
@@ -595,11 +591,9 @@ vows.describe('protocol imports').addBatch({
       this.proxyServer.listen(8080, function () {
         var options = {
           inline: 'all',
-          inliner: {
-            request: {
-              hostname: '127.0.0.1',
-              port: 8080
-            }
+          inlineRequest: {
+            hostname: '127.0.0.1',
+            port: 8080
           }
         };
 
@@ -640,11 +634,9 @@ vows.describe('protocol imports').addBatch({
       this.proxyServer.listen(8080, function () {
         var options = {
           inline: 'all',
-          inliner: {
-            request: {
-              hostname: '127.0.0.1',
-              port: 8080
-            }
+          inlineRequest: {
+            hostname: '127.0.0.1',
+            port: 8080
           }
         };
 
@@ -721,11 +713,9 @@ vows.describe('protocol imports').addBatch({
       this.proxyServer.listen(8082, function () {
         var options = {
           inline: 'all',
-          inliner: {
-            request: {
-              hostname: '127.0.0.1',
-              port: 8082
-            }
+          inlineRequest: {
+            hostname: '127.0.0.1',
+            port: 8082
           }
         };
 
index b95d118..36f8e55 100644 (file)
@@ -976,7 +976,7 @@ vows.describe('source-map')
           }
         });
         this.server.listen(port, '127.0.0.1', function () {
-          new CleanCSS({ inline: 'all', sourceMap: true, inliner: { timeout: timeout } })
+          new CleanCSS({ inline: 'all', inlineTimeout: timeout, sourceMap: true })
             .minify('@import url(http://127.0.0.1:' + port + '/remote.css);', self.callback);
         });
         enableDestroy(this.server);
@@ -1067,7 +1067,7 @@ vows.describe('source-map')
           .post('/remote.css.map')
           .reply(200, inputMap);
 
-        new CleanCSS({ inline: 'all', sourceMap: true, inliner: { request: { method: 'POST' } } })
+        new CleanCSS({ inline: 'all', inlineRequest: { method: 'POST' }, sourceMap: true })
           .minify('@import url(http://127.0.0.1/remote.css);', this.callback);
       },
       'has mapping': function (errors, minified) {