postcss-advanced-variables
Advanced tools
Comparing version 3.0.1 to 4.0.0
432
index.js
@@ -14,23 +14,21 @@ 'use strict'; | ||
let variable = variables[name]; | ||
if (requiresAncestorVariable(variable, node)) { | ||
variable = getClosestVariable(name, node.parent, opts); | ||
} | ||
if (requiresFnVariable(variable, opts)) { | ||
variable = getFnVariable(name, node, opts.variables); | ||
} | ||
return variable; | ||
} // return the variables object of a node | ||
} | ||
const getVariables = node => Object(Object(node).variables); // return whether the variable should be replaced using an ancestor variable | ||
// return the variables object of a node | ||
const getVariables = node => Object(Object(node).variables); | ||
// return whether the variable should be replaced using an ancestor variable | ||
const requiresAncestorVariable = (variable, node) => undefined === variable && node && node.parent; | ||
const requiresAncestorVariable = (variable, node) => undefined === variable && node && node.parent; // return whether variable should be replaced using a variables function | ||
// return whether variable should be replaced using a variables function | ||
const requiresFnVariable = (value, opts) => value === undefined && Object(opts).variables === Object(Object(opts).variables); | ||
const requiresFnVariable = (value, opts) => value === undefined && Object(opts).variables === Object(Object(opts).variables); // return whether variable should be replaced using a variables function | ||
// return whether variable should be replaced using a variables function | ||
const getFnVariable = (name, node, variables) => 'function' === typeof variables ? variables(name, node) : variables[name]; | ||
@@ -52,2 +50,3 @@ | ||
// return content with its variables replaced by the corresponding values of a node | ||
function getReplacedString(string, node, opts) { | ||
@@ -58,15 +57,17 @@ const replacedString = string.replace(matchVariables, (match, before, name1, name2, name3) => { | ||
return match.slice(1); | ||
} // the first matching variable name | ||
} | ||
// the first matching variable name | ||
const name = name1 || name2 || name3; | ||
const name = name1 || name2 || name3; // the closest variable value | ||
// the closest variable value | ||
const value = getClosestVariable(name, node.parent, opts); | ||
const value = getClosestVariable(name, node.parent, opts); // if a variable has not been resolved | ||
// if a variable has not been resolved | ||
if (undefined === value) { | ||
manageUnresolved(node, opts, name, `Could not resolve the variable "$${name}" within "${string}"`); | ||
return match; | ||
} // the stringified value | ||
} | ||
// the stringified value | ||
const stringifiedValue = `${before}${stringify(value)}`; | ||
@@ -76,6 +77,8 @@ return stringifiedValue; | ||
return replacedString; | ||
} // match all $name, $(name), and #{$name} variables (and catch the character before it) | ||
} | ||
const matchVariables = /(.?)(?:\$([A-z][\w-]*)|\$\(([A-z][\w-]*)\)|#\{\$([A-z][\w-]*)\})/g; // return a sass stringified variable | ||
// match all $name, $(name), and #{$name} variables (and catch the character before it) | ||
const matchVariables = /(.?)(?:\$([A-z][\w-]*)|\$\(([A-z][\w-]*)\)|#\{\$([A-z][\w-]*)\})/g; | ||
// return a sass stringified variable | ||
const stringify = object => Array.isArray(object) ? `(${object.map(stringify).join(',')})` : Object(object) === object ? `(${Object.keys(object).map(key => `${key}:${stringify(object[key])}`).join(',')})` : String(object); | ||
@@ -85,2 +88,3 @@ | ||
// set a variable on a node | ||
function setVariable(node, name, value, opts) { | ||
@@ -90,10 +94,13 @@ // if the value is not a default with a value already defined | ||
// the value without a default suffix | ||
const undefaultedValue = matchDefault.test(value) ? value.replace(matchDefault, '') : value; // ensure the node has a variables object | ||
const undefaultedValue = matchDefault.test(value) ? value.replace(matchDefault, '') : value; | ||
node.variables = node.variables || {}; // set the variable | ||
// ensure the node has a variables object | ||
node.variables = node.variables || {}; | ||
// set the variable | ||
node.variables[name] = undefaultedValue; | ||
} | ||
} // match anything ending with a valid !default | ||
} | ||
// match anything ending with a valid !default | ||
const matchDefault = /\s+!default$/; | ||
@@ -103,17 +110,23 @@ | ||
// transform declarations | ||
function transformDecl(decl, opts) { | ||
// update the declaration value with its variables replaced by their corresponding values | ||
decl.value = getReplacedString(decl.value, decl, opts); // if the declaration is a variable declaration | ||
decl.value = getReplacedString(decl.value, decl, opts); | ||
// if the declaration is a variable declaration | ||
if (isVariableDeclaration(decl)) { | ||
// set the variable on the parent of the declaration | ||
setVariable(decl.parent, decl.prop.slice(1), decl.value, opts); // remove the declaration | ||
setVariable(decl.parent, decl.prop.slice(1), decl.value, opts); | ||
// remove the declaration | ||
decl.remove(); | ||
} else { | ||
decl.prop = getReplacedString(decl.prop, decl, opts); | ||
} | ||
} // return whether the declaration property is a variable declaration | ||
} | ||
const isVariableDeclaration = decl => matchVariable.test(decl.prop); // match a variable ($any-name) | ||
// return whether the declaration property is a variable declaration | ||
const isVariableDeclaration = decl => matchVariable.test(decl.prop); | ||
// match a variable ($any-name) | ||
const matchVariable = /^\$[\w-]+$/; | ||
@@ -123,2 +136,3 @@ | ||
// transform generic at-rules | ||
function transformAtrule(rule, opts) { | ||
@@ -129,52 +143,59 @@ // update the at-rule params with its variables replaced by their corresponding values | ||
function _iterableToArrayLimit(r, l) { | ||
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; | ||
if (null != t) { | ||
var e, | ||
n, | ||
i, | ||
u, | ||
a = [], | ||
f = !0, | ||
o = !1; | ||
try { | ||
if (i = (t = t.call(r)).next, 0 === l) { | ||
if (Object(t) !== t) return; | ||
f = !1; | ||
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); | ||
} catch (r) { | ||
o = !0, n = r; | ||
} finally { | ||
try { | ||
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; | ||
} finally { | ||
if (o) throw n; | ||
} | ||
} | ||
return a; | ||
} | ||
} | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); | ||
} | ||
function _toArray(arr) { | ||
return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); | ||
return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest(); | ||
} | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArray(iter) { | ||
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); | ||
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); | ||
} | ||
function _iterableToArrayLimit(arr, i) { | ||
if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { | ||
return; | ||
} | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(o); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
// return sass-like arrays as literal arrays ('(hello), (goodbye)' to [[hello], [goodbye]]) | ||
function getValueAsObject(value) { | ||
@@ -185,3 +206,2 @@ const hasWrappingParens = matchWrappingParens.test(value); | ||
const firstValue = separatedValue[0]; | ||
if (firstValue === value) { | ||
@@ -194,7 +214,6 @@ return value; | ||
const _ref = subvalue.match(matchDeclaration) || [], | ||
_ref2 = _slicedToArray(_ref, 3), | ||
match = _ref2[0], | ||
key = _ref2[1], | ||
keyvalue = _ref2[2]; | ||
_ref2 = _slicedToArray(_ref, 3), | ||
match = _ref2[0], | ||
key = _ref2[1], | ||
keyvalue = _ref2[2]; | ||
if (match) { | ||
@@ -209,8 +228,11 @@ objectValue[key] = getValueAsObject(keyvalue); | ||
} | ||
} // match wrapping parentheses ((), (anything), (anything (anything))) | ||
} | ||
const matchWrappingParens = /^\(([\W\w]*)\)$/g; // match a property name (any-possible_name) | ||
// match wrapping parentheses ((), (anything), (anything (anything))) | ||
const matchWrappingParens = /^\(([\W\w]*)\)$/g; | ||
const matchDeclaration = /^([\w-]+)\s*:\s*([\W\w]+)\s*$/; // match a trailing comma | ||
// match a property name (any-possible_name) | ||
const matchDeclaration = /^([\w-]+)\s*:\s*([\W\w]+)\s*$/; | ||
// match a trailing comma | ||
const matchTrailingComma = /\s*,\s*$/; | ||
@@ -222,2 +244,3 @@ | ||
// transform @each at-rules | ||
function transformEachAtrule(rule, opts) { | ||
@@ -228,6 +251,5 @@ // if @each is supported | ||
const _getEachOpts = getEachOpts(rule, opts), | ||
varname = _getEachOpts.varname, | ||
incname = _getEachOpts.incname, | ||
list = _getEachOpts.list; | ||
varname = _getEachOpts.varname, | ||
incname = _getEachOpts.incname, | ||
list = _getEachOpts.list; | ||
const replacements = []; | ||
@@ -237,9 +259,10 @@ const ruleClones = []; | ||
// set the current variable | ||
setVariable(rule, varname, list[key], opts); // conditionally set the incremenator variable | ||
setVariable(rule, varname, list[key], opts); | ||
// conditionally set the incremenator variable | ||
if (incname) { | ||
setVariable(rule, incname, key, opts); | ||
} // clone the @each at-rule | ||
} | ||
// clone the @each at-rule | ||
const clone = rule.clone({ | ||
@@ -259,4 +282,5 @@ parent: rule.parent, | ||
} | ||
} // return the @each statement options (@each NAME in LIST, @each NAME ITERATOR in LIST) | ||
} | ||
// return the @each statement options (@each NAME in LIST, @each NAME ITERATOR in LIST) | ||
const getEachOpts = (node, opts) => { | ||
@@ -274,5 +298,5 @@ const params = node.params.split(matchInOperator); | ||
}; | ||
}; // match the opertor separating the name and iterator from the list | ||
}; | ||
// match the opertor separating the name and iterator from the list | ||
const matchInOperator = ' in '; | ||
@@ -282,2 +306,3 @@ | ||
// transform @if at-rules | ||
function transformIfAtrule(rule, opts) { | ||
@@ -287,5 +312,3 @@ // @if options | ||
const next = rule.next(); | ||
const transformAndInsertBeforeParent = node => transformNode(node, opts).then(() => node.parent.insertBefore(node, node.nodes)); | ||
return ifPromise(opts.transform.indexOf('@if') !== -1, () => ifPromise(isTruthy, () => transformAndInsertBeforeParent(rule)).then(() => { | ||
@@ -297,6 +320,5 @@ rule.remove(); | ||
} | ||
const ifPromise = (condition, trueFunction) => Promise.resolve(condition && trueFunction()); | ||
const ifPromise = (condition, trueFunction) => Promise.resolve(condition && trueFunction()); // return whether the @if at-rule is truthy | ||
// return whether the @if at-rule is truthy | ||
const isIfTruthy = (node, opts) => { | ||
@@ -307,14 +329,16 @@ // @if statement options (@if EXPRESSION, @if LEFT OPERATOR RIGHT) | ||
const operator = params[1]; | ||
const right = getInterprettedString(getReplacedString(params[2] || '', node, opts)); // evaluate the expression | ||
const right = getInterprettedString(getReplacedString(params[2] || '', node, opts)); | ||
// evaluate the expression | ||
const isTruthy = !operator && left || operator === '==' && left === right || operator === '!=' && left !== right || operator === '<' && left < right || operator === '<=' && left <= right || operator === '>' && left > right || operator === '>=' && left >= right; | ||
return isTruthy; | ||
}; // return the value as a boolean, number, or string | ||
}; | ||
// return the value as a boolean, number, or string | ||
const getInterprettedString = value => 'true' === value ? true : 'false' === value ? false : isNaN(value) ? value : Number(value); | ||
const getInterprettedString = value => 'true' === value ? true : 'false' === value ? false : isNaN(value) ? value : Number(value); // return whether the node is an else at-rule | ||
// return whether the node is an else at-rule | ||
const isElseRule = node => Object(node) === node && 'atrule' === node.type && 'else' === node.name; | ||
// transform @import at-rules | ||
function transformImportAtrule(rule, opts) { | ||
@@ -325,16 +349,17 @@ // if @import is supported | ||
const _getImportOpts = getImportOpts(rule, opts), | ||
id = _getImportOpts.id, | ||
media = _getImportOpts.media, | ||
cwf = _getImportOpts.cwf, | ||
cwd = _getImportOpts.cwd; // PostCSS options | ||
id = _getImportOpts.id, | ||
media = _getImportOpts.media, | ||
cwf = _getImportOpts.cwf, | ||
cwd = _getImportOpts.cwd; | ||
// PostCSS options | ||
const options = opts.result.opts; | ||
const parser = options.parser || options.syntax && options.syntax.parse || null; | ||
if (opts.importFilter instanceof Function && opts.importFilter(id, media) || opts.importFilter instanceof RegExp && opts.importFilter.test(id)) { | ||
const cwds = [cwd].concat(opts.importPaths); // promise the resolved file and its contents using the file resolver | ||
const cwds = [cwd].concat(opts.importPaths); | ||
// promise the resolved file and its contents using the file resolver | ||
const importPromise = cwds.reduce((promise, thiscwd) => promise.catch(() => opts.importResolve(id, thiscwd, opts)), Promise.reject()); | ||
return importPromise.then( // promise the processed file | ||
return importPromise.then( | ||
// promise the processed file | ||
({ | ||
@@ -354,6 +379,8 @@ file, | ||
parent: cwf | ||
}); // imported nodes | ||
}); | ||
const nodes = root.nodes.slice(0); // if media params were detected | ||
// imported nodes | ||
const nodes = root.nodes.slice(0); | ||
// if media params were detected | ||
if (media) { | ||
@@ -365,6 +392,8 @@ // create a new media rule | ||
source: rule.source | ||
}); // append with the imported nodes | ||
}); | ||
mediaRule.append(nodes); // replace the @import at-rule with the @media at-rule | ||
// append with the imported nodes | ||
mediaRule.append(nodes); | ||
// replace the @import at-rule with the @media at-rule | ||
rule.replaceWith(mediaRule); | ||
@@ -374,5 +403,5 @@ } else { | ||
rule.replaceWith(nodes); | ||
} // transform all nodes from the import | ||
} | ||
// transform all nodes from the import | ||
return transformNode({ | ||
@@ -388,13 +417,21 @@ nodes | ||
} | ||
const processor = postcss__default(); // return the @import statement options (@import ID, @import ID MEDIA) | ||
const noopPlugin = () => { | ||
return { | ||
postcssPlugin: 'noop-plugin', | ||
Once() {} | ||
}; | ||
}; | ||
noopPlugin.postcss = true; | ||
const processor = postcss__default([noopPlugin()]); | ||
// return the @import statement options (@import ID, @import ID MEDIA) | ||
const getImportOpts = (node, opts) => { | ||
const _list$space = postcss.list.space(node.params), | ||
_list$space2 = _toArray(_list$space), | ||
rawid = _list$space2[0], | ||
medias = _list$space2.slice(1); | ||
_list$space2 = _toArray(_list$space), | ||
rawid = _list$space2[0], | ||
medias = _list$space2.slice(1); | ||
const id = getReplacedString(trimWrappingURL(rawid), node, opts); | ||
const media = medias.join(' '); // current working file and directory | ||
const media = medias.join(' '); | ||
// current working file and directory | ||
const cwf = node.source && node.source.input && node.source.input.file || opts.result.from; | ||
@@ -408,10 +445,11 @@ const cwd = cwf ? path.dirname(cwf) : opts.importRoot; | ||
}; | ||
}; // return a string with the wrapping url() and quotes trimmed | ||
}; | ||
// return a string with the wrapping url() and quotes trimmed | ||
const trimWrappingURL = string => trimWrappingQuotes(string.replace(/^url\(([\W\w]*)\)$/, '$1')); | ||
const trimWrappingURL = string => trimWrappingQuotes(string.replace(/^url\(([\W\w]*)\)$/, '$1')); // return a string with the wrapping quotes trimmed | ||
// return a string with the wrapping quotes trimmed | ||
const trimWrappingQuotes = string => string.replace(/^("|')([\W\w]*)\1$/, '$2'); | ||
// transform @include at-rules | ||
function transformIncludeAtrule(rule, opts) { | ||
@@ -422,8 +460,9 @@ // if @include is supported | ||
const _getIncludeOpts = getIncludeOpts(rule), | ||
name = _getIncludeOpts.name, | ||
args = _getIncludeOpts.args; // the closest @mixin variable | ||
name = _getIncludeOpts.name, | ||
args = _getIncludeOpts.args; | ||
// the closest @mixin variable | ||
const mixin = getClosestVariable(`@mixin ${name}`, rule.parent, opts); | ||
const mixin = getClosestVariable(`@mixin ${name}`, rule.parent, opts); // if the @mixin variable exists | ||
// if the @mixin variable exists | ||
if (mixin) { | ||
@@ -434,4 +473,5 @@ // set @mixin variables on the @include at-rule | ||
setVariable(rule, param.name, arg, opts); | ||
}); // clone the @mixin at-rule | ||
}); | ||
// clone the @mixin at-rule | ||
const clone = mixin.rule.clone({ | ||
@@ -441,4 +481,5 @@ original: rule, | ||
variables: rule.variables | ||
}); // transform the clone children | ||
}); | ||
// transform the clone children | ||
return transformNode(clone, opts).then(() => { | ||
@@ -454,11 +495,11 @@ // replace the @include at-rule with the clone children | ||
} | ||
} // return the @include statement options (@include NAME, @include NAME(ARGS)) | ||
} | ||
// return the @include statement options (@include NAME, @include NAME(ARGS)) | ||
const getIncludeOpts = node => { | ||
// @include name and args | ||
const _node$params$split = node.params.split(matchOpeningParen, 2), | ||
_node$params$split2 = _slicedToArray(_node$params$split, 2), | ||
name = _node$params$split2[0], | ||
sourceArgs = _node$params$split2[1]; | ||
_node$params$split2 = _slicedToArray(_node$params$split, 2), | ||
name = _node$params$split2[0], | ||
sourceArgs = _node$params$split2[1]; | ||
const args = sourceArgs ? postcss.list.comma(sourceArgs.slice(0, -1)) : []; | ||
@@ -469,5 +510,5 @@ return { | ||
}; | ||
}; // match an opening parenthesis | ||
}; | ||
// match an opening parenthesis | ||
const matchOpeningParen = '('; | ||
@@ -477,2 +518,3 @@ | ||
// transform @for at-rules | ||
function transformForAtrule(rule, opts) { | ||
@@ -483,15 +525,16 @@ // if @for is supported | ||
const _getForOpts = getForOpts(rule, opts), | ||
varname = _getForOpts.varname, | ||
start = _getForOpts.start, | ||
end = _getForOpts.end, | ||
increment = _getForOpts.increment; | ||
varname = _getForOpts.varname, | ||
start = _getForOpts.start, | ||
end = _getForOpts.end, | ||
increment = _getForOpts.increment; | ||
const direction = start <= end ? 1 : -1; | ||
const replacements = []; | ||
const ruleClones = []; // for each iteration | ||
const ruleClones = []; | ||
// for each iteration | ||
for (let incrementor = start; incrementor * direction <= end * direction; incrementor += increment * direction) { | ||
// set the current variable | ||
setVariable(rule, varname, incrementor, opts); // clone the @for at-rule | ||
setVariable(rule, varname, incrementor, opts); | ||
// clone the @for at-rule | ||
const clone = rule.clone({ | ||
@@ -503,3 +546,2 @@ parent: rule.parent, | ||
} | ||
return waterfall(ruleClones, clone => transformNode(clone, opts).then(() => { | ||
@@ -513,4 +555,5 @@ replacements.push(...clone.nodes); | ||
} | ||
} // return the @for statement options (@for NAME from START through END, @for NAME from START through END by INCREMENT) | ||
} | ||
// return the @for statement options (@for NAME from START through END, @for NAME from START through END by INCREMENT) | ||
const getForOpts = (node, opts) => { | ||
@@ -530,2 +573,3 @@ const params = postcss.list.space(node.params); | ||
// transform @mixin at-rules | ||
function transformMixinAtrule(rule, opts) { | ||
@@ -536,22 +580,23 @@ // if @mixin is supported | ||
const _getMixinOpts = getMixinOpts(rule, opts), | ||
name = _getMixinOpts.name, | ||
params = _getMixinOpts.params; // set the mixin as a variable on the parent of the @mixin at-rule | ||
name = _getMixinOpts.name, | ||
params = _getMixinOpts.params; | ||
// set the mixin as a variable on the parent of the @mixin at-rule | ||
setVariable(rule.parent, `@mixin ${name}`, { | ||
params, | ||
rule | ||
}, opts); // remove the @mixin at-rule | ||
}, opts); | ||
// remove the @mixin at-rule | ||
rule.remove(); | ||
} | ||
} // return the @mixin statement options (@mixin NAME, @mixin NAME(PARAMS)) | ||
} | ||
// return the @mixin statement options (@mixin NAME, @mixin NAME(PARAMS)) | ||
const getMixinOpts = (node, opts) => { | ||
// @mixin name and default params ([{ name, value }, ...]) | ||
const _node$params$split = node.params.split(matchOpeningParen$1, 2), | ||
_node$params$split2 = _slicedToArray(_node$params$split, 2), | ||
name = _node$params$split2[0], | ||
sourceParams = _node$params$split2[1]; | ||
_node$params$split2 = _slicedToArray(_node$params$split, 2), | ||
name = _node$params$split2[0], | ||
sourceParams = _node$params$split2[1]; | ||
const params = sourceParams && sourceParams.slice(0, -1).trim() ? postcss.list.comma(sourceParams.slice(0, -1).trim()).map(param => { | ||
@@ -570,5 +615,5 @@ const parts = postcss.list.split(param, ':'); | ||
}; | ||
}; // match an opening parenthesis | ||
}; | ||
// match an opening parenthesis | ||
const matchOpeningParen$1 = '('; | ||
@@ -578,2 +623,3 @@ | ||
// transform rule nodes | ||
function transformRule(rule, opts) { | ||
@@ -586,2 +632,3 @@ // update the rule selector with its variables replaced by their corresponding values | ||
// transform @content at-rules | ||
function transformContentAtrule(rule, opts) { | ||
@@ -591,4 +638,5 @@ // if @content is supported | ||
// the closest @mixin at-rule | ||
const mixin = getClosestMixin(rule); // if the @mixin at-rule exists | ||
const mixin = getClosestMixin(rule); | ||
// if the @mixin at-rule exists | ||
if (mixin) { | ||
@@ -599,4 +647,5 @@ // clone the @mixin at-rule | ||
variables: rule.variables | ||
}); // transform the clone children | ||
}); | ||
// transform the clone children | ||
return transformNode(clone, opts).then(() => { | ||
@@ -612,4 +661,5 @@ // replace the @content at-rule with the clone children | ||
} | ||
} // return the closest @mixin at-rule | ||
} | ||
// return the closest @mixin at-rule | ||
const getClosestMixin = node => 'atrule' === node.type && 'mixin' === node.name ? node : node.parent && getClosestMixin(node.parent); | ||
@@ -626,10 +676,7 @@ | ||
} | ||
function transformRuleOrDecl(child, opts) { | ||
return Promise.resolve().then(() => { | ||
const type = child.type; | ||
if ('atrule' === type) { | ||
const name = child.name.toLowerCase(); | ||
const name = (child.name || '').toLowerCase(); | ||
if ('content' === name) { | ||
@@ -667,43 +714,46 @@ // transform @content at-rules | ||
}); | ||
} // return the children of a node as an array | ||
} | ||
// return the children of a node as an array | ||
const getNodesArray = node => Array.from(Object(node).nodes || []); | ||
// tooling | ||
const matchProtocol = /^(?:[A-z]+:)?\/\//; | ||
var index = postcss__default.plugin('postcss-advanced-variables', opts => (root, result) => { | ||
// process options | ||
const transformOpt = ['@content', '@each', '@else', '@if', '@include', '@import', '@for', '@mixin'].filter(feature => !(String(Object(opts).disable || '').split(/\s*,\s*|\s+,?\s*|\s,?\s+/).indexOf(feature) !== -1)); | ||
const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); | ||
const variablesOpt = Object(opts).variables; | ||
const importCache = Object(Object(opts).importCache); | ||
const importFilter = Object(opts).importFilter || (id => { | ||
return !matchProtocol.test(id); | ||
}); | ||
const importPaths = [].concat(Object(opts).importPaths || []); | ||
const importResolve = Object(opts).importResolve || ((id, cwd) => resolve(id, { | ||
cwd, | ||
readFile: true, | ||
cache: importCache | ||
})); | ||
const importRoot = Object(opts).importRoot || process.cwd(); | ||
return transformNode(root, { | ||
result, | ||
importCache, | ||
importFilter, | ||
importPaths, | ||
importResolve, | ||
importRoot, | ||
transform: transformOpt, | ||
unresolved: unresolvedOpt, | ||
variables: variablesOpt | ||
}); | ||
// plugin | ||
const plugin = opts => ({ | ||
postcssPlugin: "postcss-advanced-variables", | ||
Root(root, { | ||
result | ||
}) { | ||
// process options | ||
const transformOpt = ['@content', '@each', '@else', '@if', '@include', '@import', '@for', '@mixin'].filter(feature => !(String(Object(opts).disable || '').split(/\s*,\s*|\s+,?\s*|\s,?\s+/).indexOf(feature) !== -1)); | ||
const unresolvedOpt = String(Object(opts).unresolved || 'throw').toLowerCase(); | ||
const variablesOpt = Object(opts).variables; | ||
const importCache = Object(Object(opts).importCache); | ||
const importFilter = Object(opts).importFilter || (id => { | ||
return !matchProtocol.test(id); | ||
}); | ||
const importPaths = [].concat(Object(opts).importPaths || []); | ||
const importResolve = Object(opts).importResolve || ((id, cwd) => resolve(id, { | ||
cwd, | ||
readFile: true, | ||
cache: importCache | ||
})); | ||
const importRoot = Object(opts).importRoot || process.cwd(); | ||
return transformNode(root, { | ||
result, | ||
importCache, | ||
importFilter, | ||
importPaths, | ||
importResolve, | ||
importRoot, | ||
transform: transformOpt, | ||
unresolved: unresolvedOpt, | ||
variables: variablesOpt | ||
}); | ||
} | ||
}); | ||
const matchProtocol = /^(?:[A-z]+:)?\/\//; | ||
plugin.postcss = true; | ||
module.exports = index; | ||
module.exports = plugin; |
{ | ||
"name": "postcss-advanced-variables", | ||
"version": "3.0.1", | ||
"version": "4.0.0", | ||
"description": "Use Sass-like variables, conditionals, and iterators in CSS", | ||
@@ -24,8 +24,10 @@ "author": "Jonathan Neal <jonathantneal@hotmail.com>", | ||
"engines": { | ||
"node": ">=6.0.0" | ||
"node": "^10 || ^12 || >=14" | ||
}, | ||
"dependencies": { | ||
"@csstools/sass-import-resolve": "^1.0.0", | ||
"postcss": "^7.0.6" | ||
"@csstools/sass-import-resolve": "^1.0.0" | ||
}, | ||
"peerDependencies": { | ||
"postcss": "^8.4" | ||
}, | ||
"devDependencies": { | ||
@@ -39,4 +41,5 @@ "@babel/core": "^7.1.6", | ||
"eslint-config-dev": "^2.0.0", | ||
"postcss-scss": "^2.0.0", | ||
"postcss-tape": "2.2", | ||
"postcss": "^8.4", | ||
"postcss-scss": "^3.0.5", | ||
"postcss-tape": "^6.0.1", | ||
"pre-commit": "^1.2.2", | ||
@@ -43,0 +46,0 @@ "rollup": "^0.67.3", |
@@ -5,2 +5,3 @@ # PostCSS Advanced Variables [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS Logo" width="90" height="90" align="right">][postcss] | ||
[![Build Status][cli-img]][cli-url] | ||
[![Test Status][test-img]][test-url] | ||
[![Support Chat][git-img]][git-url] | ||
@@ -567,2 +568,4 @@ | ||
[cli-url]: https://travis-ci.org/jonathantneal/postcss-advanced-variables | ||
[test-img]: https://github.com/csstools/postcss-advanced-variables/actions/workflows/test.yml/badge.svg | ||
[test-url]: https://github.com/csstools/postcss-advanced-variables/actions/workflows/test.yml | ||
[git-img]: https://img.shields.io/badge/chat-gitter-blue.svg | ||
@@ -569,0 +572,0 @@ [git-url]: https://gitter.im/postcss/postcss |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
70129
1247
580
13
5
1
+ Addednanoid@3.3.7(transitive)
+ Addedpicocolors@1.0.1(transitive)
+ Addedpostcss@8.4.38(transitive)
+ Addedsource-map-js@1.2.0(transitive)
- Removedpostcss@^7.0.6
- Removedpicocolors@0.2.1(transitive)
- Removedpostcss@7.0.39(transitive)
- Removedsource-map@0.6.1(transitive)