File: //home/arjun/projects/buyercall/node_modules/postcss-mixins/index.js
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 processMixinContent (rule, from) {
rule.walkAtRules('mixin-content', function (content) {
if (from.nodes && from.nodes.length > 0) {
content.replaceWith(from.clone().nodes)
} else {
content.remove()
}
})
}
function insertObject (rule, obj, processMixins) {
var root = jsToCss(obj)
root.each(function (node) {
node.source = rule.source
})
processMixins(root)
processMixinContent(root, rule)
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) processMixinContent(proxy, rule)
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)
}
} else {
throw new Error('Wrong ' + name + ' mixin type ' + typeof mixin)
}
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 = []
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 mixins = { }
function processMixins (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)
}
})
}
function process () {
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))
var parent = ''
if (opts.parent) {
parent = opts.parent
}
result.messages.push({
type: 'dependency',
file: relative,
parent: parent
})
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, { from: relative })
} else {
root = postcss.parse(contents, { from: relative })
}
root.walkAtRules('define-mixin', function (atrule) {
defineMixin(result, mixins, atrule)
})
resolve()
})
} else {
mixins[name] = { mixin: require(relative) }
resolve()
}
})
}))
}).then(process)
}
})