|
|
var csstree = require('css-tree'); var parse = csstree.parse; var compress = require('./compress'); var generate = csstree.generate;
function debugOutput(name, options, startTime, data) { if (options.debug) { console.error('## ' + name + ' done in %d ms\n', Date.now() - startTime); }
return data; }
function createDefaultLogger(level) { var lastDebug;
return function logger(title, ast) { var line = title;
if (ast) { line = '[' + ((Date.now() - lastDebug) / 1000).toFixed(3) + 's] ' + line; }
if (level > 1 && ast) { var css = generate(ast);
// when level 2, limit css to 256 symbols
if (level === 2 && css.length > 256) { css = css.substr(0, 256) + '...'; }
line += '\n ' + css + '\n'; }
console.error(line); lastDebug = Date.now(); }; }
function copy(obj) { var result = {};
for (var key in obj) { result[key] = obj[key]; }
return result; }
function buildCompressOptions(options) { options = copy(options);
if (typeof options.logger !== 'function' && options.debug) { options.logger = createDefaultLogger(options.debug); }
return options; }
function runHandler(ast, options, handlers) { if (!Array.isArray(handlers)) { handlers = [handlers]; }
handlers.forEach(function(fn) { fn(ast, options); }); }
function minify(context, source, options) { options = options || {};
var filename = options.filename || '<unknown>'; var result;
// parse
var ast = debugOutput('parsing', options, Date.now(), parse(source, { context: context, filename: filename, positions: Boolean(options.sourceMap) }) );
// before compress handlers
if (options.beforeCompress) { debugOutput('beforeCompress', options, Date.now(), runHandler(ast, options, options.beforeCompress) ); }
// compress
var compressResult = debugOutput('compress', options, Date.now(), compress(ast, buildCompressOptions(options)) );
// after compress handlers
if (options.afterCompress) { debugOutput('afterCompress', options, Date.now(), runHandler(compressResult, options, options.afterCompress) ); }
// generate
if (options.sourceMap) { result = debugOutput('generate(sourceMap: true)', options, Date.now(), (function() { var tmp = generate(compressResult.ast, { sourceMap: true }); tmp.map._file = filename; // since other tools can relay on file in source map transform chain
tmp.map.setSourceContent(filename, source); return tmp; }())); } else { result = debugOutput('generate', options, Date.now(), { css: generate(compressResult.ast), map: null }); }
return result; }
function minifyStylesheet(source, options) { return minify('stylesheet', source, options); }
function minifyBlock(source, options) { return minify('declarationList', source, options); }
module.exports = { version: require('../package.json').version,
// main methods
minify: minifyStylesheet, minifyBlock: minifyBlock,
// css syntax parser/walkers/generator/etc
syntax: Object.assign({ compress: compress }, csstree) };
|