2017-06-08_509bba0/509bba0_unpacked_with_node_.../~/postcss-mixins/index.js

206 lines
6.4 KiB
JavaScript
Raw Permalink Normal View History

2022-07-26 17:06:20 +00:00
var jsToCss = require('postcss-js/parser');
var postcss = require('postcss');
var sugarss = require('sugarss');
var globby = require('globby');
var vars = require('postcss-simple-vars');
var path = require('path');
var fs = require('fs');
var isWindows = require('os').platform().indexOf('win32') !== -1;
function insideDefine(rule) {
var parent = rule.parent;
if ( !parent ) {
return false;
} else if ( parent.name === 'define-mixin' ) {
return true;
} else {
return insideDefine(parent);
}
}
function insertObject(rule, obj, processMixins) {
var root = jsToCss(obj);
root.each(function (node) {
node.source = rule.source;
});
processMixins(root);
rule.parent.insertBefore(rule, root);
}
function insertMixin(result, mixins, rule, processMixins, opts) {
var name = rule.params.split(/\s/, 1)[0];
var rest = rule.params.slice(name.length).trim();
var params;
if ( rest.trim() === '' ) {
params = [];
} else {
params = postcss.list.comma(rest);
}
var meta = mixins[name];
var mixin = meta && meta.mixin;
if ( !meta ) {
if ( !opts.silent ) {
throw rule.error('Undefined mixin ' + name);
}
} else if ( mixin.name === 'define-mixin' ) {
var i;
var values = { };
for ( i = 0; i < meta.args.length; i++ ) {
values[meta.args[i][0]] = params[i] || meta.args[i][1];
}
var proxy = postcss.root();
for ( i = 0; i < mixin.nodes.length; i++ ) {
var node = mixin.nodes[i].clone();
delete node.raws.before;
proxy.append( node );
}
if ( meta.args.length ) {
vars({ only: values })(proxy);
}
if ( meta.content ) {
proxy.walkAtRules('mixin-content', function (content) {
if ( rule.nodes && rule.nodes.length > 0 ) {
content.replaceWith(rule.nodes);
} else {
content.remove();
}
});
}
processMixins(proxy);
rule.parent.insertBefore(rule, proxy);
} else if ( typeof mixin === 'object' ) {
insertObject(rule, mixin, processMixins);
} else if ( typeof mixin === 'function' ) {
var args = [rule].concat(params);
rule.walkAtRules(function (atRule) {
insertMixin(result, mixins, atRule, processMixins, opts);
});
var nodes = mixin.apply(this, args);
if ( typeof nodes === 'object' ) {
insertObject(rule, nodes, processMixins);
}
}
if ( rule.parent ) rule.remove();
}
function defineMixin(result, mixins, rule) {
var name = rule.params.split(/\s/, 1)[0];
var other = rule.params.slice(name.length).trim();
var args = [];
if ( other.length ) {
args = postcss.list.comma(other).map(function (str) {
var arg = str.split(':', 1)[0];
var defaults = str.slice(arg.length + 1);
return [arg.slice(1).trim(), defaults.trim()];
});
}
var content = false;
rule.walkAtRules('mixin-content', function () {
content = true;
return false;
});
mixins[name] = { mixin: rule, args: args, content: content };
rule.remove();
}
module.exports = postcss.plugin('postcss-mixins', function (opts) {
if ( typeof opts === 'undefined' ) opts = { };
var cwd = process.cwd();
var globs = [];
var mixins = { };
if ( opts.mixinsDir ) {
if ( !Array.isArray(opts.mixinsDir) ) {
opts.mixinsDir = [opts.mixinsDir];
}
globs = opts.mixinsDir.map(function (dir) {
return path.join(dir, '*.{js,json,css,sss,pcss}');
});
}
if ( opts.mixinsFiles ) globs = globs.concat(opts.mixinsFiles);
return function (css, result) {
var processMixins = function (root) {
root.walkAtRules(function (i) {
if ( i.name === 'mixin' || i.name === 'add-mixin' ) {
if ( !insideDefine(i) ) {
insertMixin(result, mixins, i, processMixins, opts);
}
} else if ( i.name === 'define-mixin' ) {
defineMixin(result, mixins, i);
}
});
};
var process = function () {
if ( typeof opts.mixins === 'object' ) {
for ( var i in opts.mixins ) {
mixins[i] = { mixin: opts.mixins[i] };
}
}
processMixins(css);
};
if ( globs.length === 0 ) {
process();
return;
}
// Windows bug with { nocase: true } due to node-glob issue
// https://github.com/isaacs/node-glob/issues/123
return globby(globs, { nocase: !isWindows }).then(function (files) {
return Promise.all(files.map(function (file) {
var ext = path.extname(file).toLowerCase();
var name = path.basename(file, path.extname(file));
var relative = path.join(cwd, path.relative(cwd, file));
return new Promise(function (resolve, reject) {
if ( ext === '.css' || ext === '.pcss' || ext === '.sss' ) {
fs.readFile(relative, function (err, contents) {
/* istanbul ignore if */
if ( err ) {
reject(err);
return;
}
var root;
if ( ext === '.sss' ) {
root = sugarss.parse(contents);
} else {
root = postcss.parse(contents);
}
root.walkAtRules('define-mixin', function (atrule) {
defineMixin(result, mixins, atrule);
});
resolve();
});
} else {
mixins[name] = { mixin: require(relative) };
resolve();
}
});
}));
}).then(process);
};
});
//////////////////
// WEBPACK FOOTER
// ./~/postcss-mixins/index.js
// module id = 1205
// module chunks = 4