UNPKG

gulp-livingcss

Version:

Gulp wrapper for the LivingCSS Style Guide Generator

148 lines (119 loc) 4.42 kB
var through = require('through2'); var path = require('path'); var File = require('vinyl') ; var PluginError = require('plugin-error'); var livingcss = require('livingcss'); var minify = require('html-minifier').minify; /** * Buffer all files before passing the file list to livingcss. * @param {string} dest - Destination path to pass to livingcss. * @param {object} [options] - Options to pass to livingcss. */ module.exports = function (dest, options) { options = options || {}; // list of all files from gulp.src var files = []; /** * Buffer all files before parsing them to livingcss. */ function bufferContents(file, enc, cb) { // ignore empty files if (file.isNull()) { return cb(); } // no streams if (file.isStream()) { this.emit('error', new PluginError('gulp-livingcss', 'Streaming not supported')); return cb(); } files.push(file.path); cb(); } /** * Pass all files to livingcss once buffered. */ function endStream(cb) { var _this = this; options._squelchLogging = true; // because we want to create a file for the stream and not one through fs.write // we need to override the preprocess function to return false so it doesn't go // through that step of the generate script var preprocessFunc = options.preprocess; options.preprocess = function(context, template, Handlebars) { // if no preprocess function then resolve a promise var preprocess = (preprocessFunc ? preprocessFunc(context, template, Handlebars) : Promise.resolve()); // if the user returned anything but false we'll resolve a promise if (!(preprocess instanceof Promise)) { preprocess = (preprocess !== false ? Promise.resolve() : Promise.reject()); } return preprocess .then(function() { // skip processing the stylesheets and handlebars template and just // return the context object return options.streamContext ? Promise.reject() : Promise.resolve(); }) .then(function() { // read the stylesheets from an absolute path so we're not trying to // read them from the livingcss directory var stylesheets = context.stylesheets.map(function(file) { return path.join( process.cwd(), dest || '.', file); }); // inline all stylesheets for polymer shared styles to work // @see https://www.polymer-project.org/1.0/docs/devguide/styling#style-modules return livingcss.utils.readFiles(stylesheets, function(data, file) { context.parsedStylesheets = context.parsedStylesheets || []; context.parsedStylesheets.push(livingcss.utils.fixSVGIssue(data)); }); }) .then(function success() { var html = Handlebars.compile(template)(context); if (options.minify) { html = minify(html, { collapseWhitespace: true, minifyCSS: options.minifyCSS || false }); } // add output file to stream _this.push(new File({ name: context.id + '.html', path: context.id + '.html', contents: new Buffer(html) })); // reject this promise so livingcss doesn't create files return Promise.reject(); }) .catch(function(e) { if (e) { _this.emit('error', new PluginError({ plugin: 'gulp-livingcss', message: e.message })); throw e; } if (options.streamContext) { // add context file to stream _this.push(new File({ name: context.id + '.json', path: context.id + '.json', contents: new Buffer(JSON.stringify(context)) })); } // reject this promise so livingcss doesn't create files return Promise.reject(e); }); } livingcss(files, dest, options).then(function() { cb(); }) .catch(function(e) { _this.emit('error', new PluginError({ plugin: 'gulp-livingcss', message: e.message })); throw e; }); } return through.obj(bufferContents, endStream); }; // add livingcss utility functions to gulp plugin module.exports.utils = livingcss.utils;