|
|
- /**
- * 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;
- }
|