You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					173 lines
				
				5.2 KiB
			
		
		
			
		
	
	
					173 lines
				
				5.2 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Clean-css - https://github.com/jakubpawlowicz/clean-css
							 | 
						||
| 
								 | 
							
								 * Released under the terms of MIT license
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2017 JakubPawlowicz.com
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var level0Optimize = require('./optimizer/level-0/optimize');
							 | 
						||
| 
								 | 
							
								var level1Optimize = require('./optimizer/level-1/optimize');
							 | 
						||
| 
								 | 
							
								var level2Optimize = require('./optimizer/level-2/optimize');
							 | 
						||
| 
								 | 
							
								var validator = require('./optimizer/validator');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var compatibilityFrom = require('./options/compatibility');
							 | 
						||
| 
								 | 
							
								var fetchFrom = require('./options/fetch');
							 | 
						||
| 
								 | 
							
								var formatFrom = require('./options/format').formatFrom;
							 | 
						||
| 
								 | 
							
								var inlineFrom = require('./options/inline');
							 | 
						||
| 
								 | 
							
								var inlineRequestFrom = require('./options/inline-request');
							 | 
						||
| 
								 | 
							
								var inlineTimeoutFrom = require('./options/inline-timeout');
							 | 
						||
| 
								 | 
							
								var OptimizationLevel = require('./options/optimization-level').OptimizationLevel;
							 | 
						||
| 
								 | 
							
								var optimizationLevelFrom = require('./options/optimization-level').optimizationLevelFrom;
							 | 
						||
| 
								 | 
							
								var rebaseFrom = require('./options/rebase');
							 | 
						||
| 
								 | 
							
								var rebaseToFrom = require('./options/rebase-to');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var inputSourceMapTracker = require('./reader/input-source-map-tracker');
							 | 
						||
| 
								 | 
							
								var readSources = require('./reader/read-sources');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var serializeStyles = require('./writer/simple');
							 | 
						||
| 
								 | 
							
								var serializeStylesAndSourceMap = require('./writer/source-maps');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var CleanCSS = module.exports = function CleanCSS(options) {
							 | 
						||
| 
								 | 
							
								  options = options || {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.options = {
							 | 
						||
| 
								 | 
							
								    compatibility: compatibilityFrom(options.compatibility),
							 | 
						||
| 
								 | 
							
								    fetch: fetchFrom(options.fetch),
							 | 
						||
| 
								 | 
							
								    format: formatFrom(options.format),
							 | 
						||
| 
								 | 
							
								    inline: inlineFrom(options.inline),
							 | 
						||
| 
								 | 
							
								    inlineRequest: inlineRequestFrom(options.inlineRequest),
							 | 
						||
| 
								 | 
							
								    inlineTimeout: inlineTimeoutFrom(options.inlineTimeout),
							 | 
						||
| 
								 | 
							
								    level: optimizationLevelFrom(options.level),
							 | 
						||
| 
								 | 
							
								    rebase: rebaseFrom(options.rebase),
							 | 
						||
| 
								 | 
							
								    rebaseTo: rebaseToFrom(options.rebaseTo),
							 | 
						||
| 
								 | 
							
								    returnPromise: !!options.returnPromise,
							 | 
						||
| 
								 | 
							
								    sourceMap: !!options.sourceMap,
							 | 
						||
| 
								 | 
							
								    sourceMapInlineSources: !!options.sourceMapInlineSources
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// for compatibility with optimize-css-assets-webpack-plugin
							 | 
						||
| 
								 | 
							
								CleanCSS.process = function (input, opts) {
							 | 
						||
| 
								 | 
							
								  var cleanCss;
							 | 
						||
| 
								 | 
							
								  var optsTo = opts.to;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  delete opts.to;
							 | 
						||
| 
								 | 
							
								  cleanCss = new CleanCSS(Object.assign({ returnPromise: true, rebaseTo: optsTo }, opts));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return cleanCss.minify(input)
							 | 
						||
| 
								 | 
							
								    .then(function(output) {
							 | 
						||
| 
								 | 
							
								      return { css: output.styles };
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CleanCSS.prototype.minify = function (input, maybeSourceMap, maybeCallback) {
							 | 
						||
| 
								 | 
							
								  var options = this.options;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (options.returnPromise) {
							 | 
						||
| 
								 | 
							
								    return new Promise(function (resolve, reject) {
							 | 
						||
| 
								 | 
							
								      minify(input, options, maybeSourceMap, function (errors, output) {
							 | 
						||
| 
								 | 
							
								        return errors ?
							 | 
						||
| 
								 | 
							
								          reject(errors) :
							 | 
						||
| 
								 | 
							
								          resolve(output);
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    return minify(input, options, maybeSourceMap, maybeCallback);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function minify(input, options, maybeSourceMap, maybeCallback) {
							 | 
						||
| 
								 | 
							
								  var sourceMap = typeof maybeSourceMap != 'function' ?
							 | 
						||
| 
								 | 
							
								    maybeSourceMap :
							 | 
						||
| 
								 | 
							
								    null;
							 | 
						||
| 
								 | 
							
								  var callback = typeof maybeCallback == 'function' ?
							 | 
						||
| 
								 | 
							
								    maybeCallback :
							 | 
						||
| 
								 | 
							
								    (typeof maybeSourceMap == 'function' ? maybeSourceMap : null);
							 | 
						||
| 
								 | 
							
								  var context = {
							 | 
						||
| 
								 | 
							
								    stats: {
							 | 
						||
| 
								 | 
							
								      efficiency: 0,
							 | 
						||
| 
								 | 
							
								      minifiedSize: 0,
							 | 
						||
| 
								 | 
							
								      originalSize: 0,
							 | 
						||
| 
								 | 
							
								      startedAt: Date.now(),
							 | 
						||
| 
								 | 
							
								      timeSpent: 0
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    cache: {
							 | 
						||
| 
								 | 
							
								      specificity: {}
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    errors: [],
							 | 
						||
| 
								 | 
							
								    inlinedStylesheets: [],
							 | 
						||
| 
								 | 
							
								    inputSourceMapTracker: inputSourceMapTracker(),
							 | 
						||
| 
								 | 
							
								    localOnly: !callback,
							 | 
						||
| 
								 | 
							
								    options: options,
							 | 
						||
| 
								 | 
							
								    source: null,
							 | 
						||
| 
								 | 
							
								    sourcesContent: {},
							 | 
						||
| 
								 | 
							
								    validator: validator(options.compatibility),
							 | 
						||
| 
								 | 
							
								    warnings: []
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (sourceMap) {
							 | 
						||
| 
								 | 
							
								    context.inputSourceMapTracker.track(undefined, sourceMap);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return runner(context.localOnly)(function () {
							 | 
						||
| 
								 | 
							
								    return readSources(input, context, function (tokens) {
							 | 
						||
| 
								 | 
							
								      var serialize = context.options.sourceMap ?
							 | 
						||
| 
								 | 
							
								        serializeStylesAndSourceMap :
							 | 
						||
| 
								 | 
							
								        serializeStyles;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var optimizedTokens = optimize(tokens, context);
							 | 
						||
| 
								 | 
							
								      var optimizedStyles = serialize(optimizedTokens, context);
							 | 
						||
| 
								 | 
							
								      var output = withMetadata(optimizedStyles, context);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return callback ?
							 | 
						||
| 
								 | 
							
								        callback(context.errors.length > 0 ? context.errors : null, output) :
							 | 
						||
| 
								 | 
							
								        output;
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function runner(localOnly) {
							 | 
						||
| 
								 | 
							
								  // to always execute code asynchronously when a callback is given
							 | 
						||
| 
								 | 
							
								  // more at blog.izs.me/post/59142742143/designing-apis-for-asynchrony
							 | 
						||
| 
								 | 
							
								  return localOnly ?
							 | 
						||
| 
								 | 
							
								    function (callback) { return callback(); } :
							 | 
						||
| 
								 | 
							
								    process.nextTick;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function optimize(tokens, context) {
							 | 
						||
| 
								 | 
							
								  var optimized;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  optimized = level0Optimize(tokens, context);
							 | 
						||
| 
								 | 
							
								  optimized = OptimizationLevel.One in context.options.level ?
							 | 
						||
| 
								 | 
							
								    level1Optimize(tokens, context) :
							 | 
						||
| 
								 | 
							
								    tokens;
							 | 
						||
| 
								 | 
							
								  optimized = OptimizationLevel.Two in context.options.level ?
							 | 
						||
| 
								 | 
							
								    level2Optimize(tokens, context, true) :
							 | 
						||
| 
								 | 
							
								    optimized;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return optimized;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function withMetadata(output, context) {
							 | 
						||
| 
								 | 
							
								  output.stats = calculateStatsFrom(output.styles, context);
							 | 
						||
| 
								 | 
							
								  output.errors = context.errors;
							 | 
						||
| 
								 | 
							
								  output.inlinedStylesheets = context.inlinedStylesheets;
							 | 
						||
| 
								 | 
							
								  output.warnings = context.warnings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return output;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function calculateStatsFrom(styles, context) {
							 | 
						||
| 
								 | 
							
								  var finishedAt = Date.now();
							 | 
						||
| 
								 | 
							
								  var timeSpent = finishedAt - context.stats.startedAt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  delete context.stats.startedAt;
							 | 
						||
| 
								 | 
							
								  context.stats.timeSpent = timeSpent;
							 | 
						||
| 
								 | 
							
								  context.stats.efficiency = 1 - styles.length / context.stats.originalSize;
							 | 
						||
| 
								 | 
							
								  context.stats.minifiedSize = styles.length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return context.stats;
							 | 
						||
| 
								 | 
							
								}
							 |