UNPKG

judocss

Version:

The functional CSS toolkit designed for minimal effort and maximum efficiency.

188 lines (142 loc) 4.22 kB
'use strict'; (function () { var glob = require('glob-fs')({ gitignore: true }); var htmlparser = require("htmlparser2"); var fs = require('fs'); var dir = require('node-dir'); var ruleset = require('./judo.ruleset.js'); var classRegex = require('./judo.classRegex.js'); var units = "%,cm,em,ex,in,mm,pc,pt,px,vh,vw,vmin".split(","); var parts = function parts(value, fn) { var i = units.length; var index = -1; var unit = ""; while (i--) { unit = units[i]; index = value.indexOf(unit); if (index > -1) { var n = value.substr(0, value.length - unit.length); if (isNaN(n)) { break; } return fn(n, unit); } } throw "Baseline value must consist of a number and a unit. E.g., 7px"; }; var base = function base(baseline) { return parts(baseline, function (n, unit) { return function (x) { return isNaN(x) ? x : x * n + unit; }; }); }; function trim(key) { var i = key.indexOf('$'); return i === -1 ? key : key.substr(0, i); } function createMap(config) { var res = {}; var i = void 0; var key = void 0; for (i in config) { key = trim(i); res[key] = res[key] || []; res[key].push({ regex: classRegex(i), value: config[i] }); } for (i in res) { res[i].sort(function (a, b) { return a.value.length - b.value.length; }); } return res; } //===================== function getStylesGroupedByQuery(classes, classMap) { var cache = {}; Object.keys(classes).forEach(function (className) { ruleset(classMap, className, function (value, query) { cache[query] = cache[query] || {}; cache[query][className] = cache[query][className] || value; }); }); return cache; } //===================== var queryBlockOpen = { "all": function all() { return ""; }, "small": function small(breakpoint) { return '@media screen and (min-width: ' + breakpoint.small + ') {'; }, "medium": function medium(breakpoint) { return '@media screen and (min-width: ' + breakpoint.medium + ') {'; }, "large": function large(breakpoint) { return '@media screen and (min-width: ' + breakpoint.large + ') {'; } }; var queryBlockClose = function queryBlockClose(key) { return key === "all" ? "" : "}"; }; function expandMediaQueries(o, breakpoint) { var q = void 0; var res = []; for (q in o) { //start query res.push(queryBlockOpen[q](breakpoint)); var items = o[q]; var i = void 0; for (i in items) { res.push(items[i]); } //end query res.push(queryBlockClose(q)); } return res.join(' '); } //===================== function onComplete(classes, classMap, config, callback) { var stylesGroupedByQuery = getStylesGroupedByQuery(classes, classMap); var css = expandMediaQueries(stylesGroupedByQuery, config.breakpoint); if (config.out) { fs.writeFile(config.out, css, function (err) { if (err) throw err; console.log('Saved.'); callback(css); }); } else { callback(css); } } var classes = {}; var parser = new htmlparser.Parser({ onopentag: function onopentag(name, attrs) { if (attrs.class) { attrs.class.split(' ').forEach(function (name) { classes[name] = true; }); } } }, { decodeEntities: true }); module.exports = function (config, callback) { classes = {}; callback = callback || function () {}; //load the path relative to the cwd or use the default var mapPath = config.map ? process.cwd() + '/' + config.map : "./judo.map.js"; var confMap = require(mapPath); var baselineFn = base(config.baseline); var classMap = createMap(confMap(baselineFn)); glob.readdirStream(config.in).on('data', function (file) { var content = fs.readFileSync(file.path); parser.write(content); }).on('error', console.error).on('end', function () { onComplete(classes, classMap, config, callback); }); ; }; })();