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.
142 lines
3.4 KiB
142 lines
3.4 KiB
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, |
|
|
|
// compress an AST |
|
compress: compress, |
|
|
|
// css syntax parser/walkers/generator/etc |
|
syntax: csstree |
|
};
|
|
|