🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

postcss-css-variables

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcss-css-variables - npm Package Compare versions

Comparing version

to
0.18.0

60

CHANGELOG.md

@@ -1,3 +0,9 @@

# v0.17.0 - 2020-4-24
# v0.18.0 - 2021-05-11
- [breaking] Add basic postcss 8 support (older versions of PostCSS no longer compatible)
- Thank you to [@delucis](https://github.com/delucis) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/129)
# v0.17.0 - 2020-04-24
- Expand variables in AtRule properties

@@ -7,3 +13,3 @@ - Thank you to [@pvande](https://github.com/pvande) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/104)

# v0.16.0 - 2020-4-24
# v0.16.0 - 2020-04-24

@@ -13,3 +19,3 @@ - Add ability to pass callback function to `options.preserve` to determine whether to preserve declaration

# v0.15.0 - 2020-4-24
# v0.15.0 - 2020-04-24

@@ -24,3 +30,3 @@ - Fix algorithm to find balanced `var()` pairs and nested parenthesis

# v0.13.0 - 2019-6-17
# v0.13.0 - 2019-06-17

@@ -32,3 +38,3 @@ - Add `options.preserveAtRulesOrder` so media queries are outputted in the order they are defined (as expected)

# v0.12.0 - 2019-2-21
# v0.12.0 - 2019-02-21

@@ -38,7 +44,7 @@ - Accept whitespace in `var( --var )` expression

# v0.11.0 - 2018-10-9
# v0.11.0 - 2018-10-09
- Fix JS-defined variables using `isImportant`, https://github.com/MadLittleMods/postcss-css-variables/pull/87
# v0.10.0 - 2018-9-25
# v0.10.0 - 2018-09-25

@@ -48,3 +54,3 @@ - Cast `opts.variables` variable values to string

# v0.9.0 - 2018-6-26
# v0.9.0 - 2018-06-26

@@ -54,3 +60,3 @@ - Adds `opts.preserveInjectedVariables`, which when set to `false`, removes the `:root { ... }` custom property declarations added via `opts.variables`

# v0.8.1 - 2018-3-21
# v0.8.1 - 2018-03-21

@@ -60,3 +66,3 @@ - Log `undefined` variables (available in `result.warnings()`)

# v0.8.0 - 2017-8-8
# v0.8.0 - 2017-08-08

@@ -66,3 +72,3 @@ - Remove PostCSS `moveTo`/`append` deprecation warnings, [#50](https://github.com/MadLittleMods/postcss-css-variables/issues/50)

# v0.7.0 - 2017-3-12
# v0.7.0 - 2017-03-12

@@ -72,3 +78,3 @@ - Resolve `var` usage in fallbacks, [#37](https://github.com/MadLittleMods/postcss-css-variables/issues/37)

# v0.6.0 - 2016-9-23
# v0.6.0 - 2016-09-23

@@ -80,3 +86,3 @@ - Update/refactor readme

# v0.5.2 - 2016-8-24
# v0.5.2 - 2016-08-24

@@ -91,19 +97,19 @@ - Fix [#42](https://github.com/MadLittleMods/postcss-css-variables/issues/42) where `opts.preserve` was not working inside at-rules

# v0.5.0 - 2015-9-12
# v0.5.0 - 2015-09-12
- Upgrade to PostCSS v5. Fix [#20](https://github.com/MadLittleMods/postcss-css-variables/issues/20)
# v0.4.0 - 2015-7-2
# v0.4.0 - 2015-07-02
- Fix [#15](https://github.com/MadLittleMods/postcss-css-variables/issues/15) - Remove slowness from cloning the `root` with `node.clone().removeAll()`. Now using `./lib/shallow-clone-node.js` to avoid cloning children which will get removed right after. - Thank you to [@ddprrt](https://github.com/ddprrt) for bringing up the slowness issue in this article, [PostCSS misconceptions](https://medium.com/@ddprrt/postcss-misconceptions-faf5dc5038df).
# v0.3.9 - 2015-6-29
# v0.3.9 - 2015-06-29
- Remove `opts` global leak. Fix [#13](https://github.com/MadLittleMods/postcss-css-variables/issues/13)
# v0.3.8 - 2015-5-28
# v0.3.8 - 2015-05-28
- Add support for pseudo selectors `:hover` `:before`
# v0.3.7 - 2015-5-27
# v0.3.7 - 2015-05-27

@@ -113,7 +119,7 @@ - Fix [#7](https://github.com/MadLittleMods/postcss-css-variables/issues/7): Support for child combinator

# v0.3.6 - 2015-5-21
# v0.3.6 - 2015-05-21
- Fix [#6](https://github.com/MadLittleMods/postcss-css-variables/issues/6). Variable usage in comma separated selector to use proper scope
# v0.3.5 - 2015-5-12
# v0.3.5 - 2015-05-12

@@ -123,11 +129,11 @@ - Big refactor of code to reduce cyclomatic complexity. Still needs work though.

# v0.3.4 - 2015-5-12
# v0.3.4 - 2015-05-12
- Fix variable referencing another variable resolution when being changed by at-rule
# v0.3.3 - 2015-5-11
# v0.3.3 - 2015-05-11
- Add support for last piece of combinator chain in selector resolution matching. - `.foo + .bar` can match variables declared in `.bar`
# v0.3.1 - 2015-5-5
# v0.3.1 - 2015-05-05

@@ -137,11 +143,11 @@ - Large overhaul of code to make it more robust on proper scope resolution.

# v0.2.3 - 2015-5-4
# v0.2.3 - 2015-05-04
- Add support for CSS4 descendant selector `>>` syntax
# v0.2.2 - 2015-5-1
# v0.2.2 - 2015-05-01
- Automatically prefix any variables defined in `options.variables` with `--` (according to CSS custom property syntax).
# v0.2.1 - 2015-4-30
# v0.2.1 - 2015-04-30

@@ -153,4 +159,4 @@ - Added support for descendant selector nesting instead of just physical space nesting

# v0.1.0 - 2015-4-29
# v0.1.0 - 2015-04-29
- First release

@@ -9,3 +9,2 @@ // PostCSS CSS Variables (postcss-css-variables)

var postcss = require("postcss");
var extend = require("extend");

@@ -68,3 +67,3 @@

module.exports = postcss.plugin("postcss-css-variables", function(options) {
module.exports = (options = {}) => {
var opts = extend({}, defaults, options);

@@ -74,222 +73,227 @@

return function(css, result) {
// Transform CSS AST here
return {
postcssPlugin: 'postcss-css-variables',
Once(css, { decl, result, rule }) {
// Transform CSS AST here
/* * /
try {
/* */
/* * /
try {
/* */
// List of nodes that if empty, will be removed
// We use this because we don't want to modify the AST when we still need to reference these later on
var nodesToRemoveAtEnd = [];
// List of nodes that if empty, will be removed
// We use this because we don't want to modify the AST when we still need to reference these later on
var nodesToRemoveAtEnd = [];
// Keep track of the injected from `opts.variables` to remove at the end
// if user passes `opts.preserveInjectedVariables = false`
var injectedDeclsToRemoveAtEnd = [];
// Keep track of the injected from `opts.variables` to remove at the end
// if user passes `opts.preserveInjectedVariables = false`
var injectedDeclsToRemoveAtEnd = [];
// Map of variable names to a list of declarations
var map = {};
// Map of variable names to a list of declarations
var map = {};
// Add the js defined variables `opts.variables` to the map
map = extend(
map,
Object.keys(opts.variables).reduce(function(
prevVariableMap,
variableName
) {
var variableEntry = opts.variables[variableName];
// Automatically prefix any variable with `--` (CSS custom property syntax) if it doesn't have it already
variableName =
variableName.slice(0, 2) === "--"
? variableName
: "--" + variableName;
var variableValue = (variableEntry || {}).value || variableEntry;
var isImportant = (variableEntry || {}).isImportant || false;
// Add the js defined variables `opts.variables` to the map
map = extend(
map,
Object.keys(opts.variables).reduce(function(
prevVariableMap,
variableName
) {
var variableEntry = opts.variables[variableName];
// Automatically prefix any variable with `--` (CSS custom property syntax) if it doesn't have it already
variableName =
variableName.slice(0, 2) === "--"
? variableName
: "--" + variableName;
var variableValue = (variableEntry || {}).value || variableEntry;
var isImportant = (variableEntry || {}).isImportant || false;
// Add a root node to the AST
var variableRootRule = postcss.rule({ selector: ":root" });
css.root().prepend(variableRootRule);
// Add the variable decl to the root node
var varDecl = postcss.decl({
prop: variableName,
value: variableValue,
important: isImportant
});
variableRootRule.append(varDecl);
// Add a root node to the AST
var variableRootRule = rule({ selector: ":root" });
css.root().prepend(variableRootRule);
// Add the variable decl to the root node
var varDecl = decl({
prop: variableName,
value: variableValue,
important: isImportant
});
variableRootRule.append(varDecl);
// Collect JS-injected variables for removal if `opts.preserveInjectedVariables = false`
if (!opts.preserveInjectedVariables) {
injectedDeclsToRemoveAtEnd.push(varDecl);
}
// Collect JS-injected variables for removal if `opts.preserveInjectedVariables = false`
if (!opts.preserveInjectedVariables) {
injectedDeclsToRemoveAtEnd.push(varDecl);
}
// Add the entry to the map
prevVariableMap[variableName] = (
prevVariableMap[variableName] || []
).concat({
decl: varDecl,
prop: variableName,
calculatedInPlaceValue: variableValue,
isImportant: isImportant,
variablesUsed: [],
parent: variableRootRule,
isUnderAtRule: false
// Add the entry to the map
prevVariableMap[variableName] = (
prevVariableMap[variableName] || []
).concat({
decl: varDecl,
prop: variableName,
calculatedInPlaceValue: variableValue,
isImportant: isImportant,
variablesUsed: [],
parent: variableRootRule,
isUnderAtRule: false
});
return prevVariableMap;
},
{})
);
// Chainable helper function to log any messages (warnings)
var logResolveValueResult = function(valueResult) {
// Log any warnings that might of popped up
var warningList = [].concat(valueResult.warnings);
warningList.forEach(function(warningArgs) {
warningArgs = [].concat(warningArgs);
result.warn.apply(result, warningArgs);
});
return prevVariableMap;
},
{})
);
// Keep the chain going
return valueResult;
};
// Chainable helper function to log any messages (warnings)
var logResolveValueResult = function(valueResult) {
// Log any warnings that might of popped up
var warningList = [].concat(valueResult.warnings);
warningList.forEach(function(warningArgs) {
warningArgs = [].concat(warningArgs);
result.warn.apply(result, warningArgs);
});
// Collect all of the variables defined
// ---------------------------------------------------------
// ---------------------------------------------------------
//console.log('Collecting variables defined START');
eachCssVariableDeclaration(css, function(decl) {
var declParentRule = decl.parent;
// Keep the chain going
return valueResult;
};
var valueResults = logResolveValueResult(resolveValue(decl, map));
// Split out each selector piece into its own declaration for easier logic down the road
decl.parent.selectors.forEach(function(selector) {
// Create a detached clone
var splitOutRule = shallowCloneNode(decl.parent);
splitOutRule.selector = selector;
splitOutRule.parent = decl.parent.parent;
// Collect all of the variables defined
// ---------------------------------------------------------
// ---------------------------------------------------------
//console.log('Collecting variables defined START');
eachCssVariableDeclaration(css, function(decl) {
var declParentRule = decl.parent;
var declClone = decl.clone();
splitOutRule.append(declClone);
var valueResults = logResolveValueResult(resolveValue(decl, map));
// Split out each selector piece into its own declaration for easier logic down the road
decl.parent.selectors.forEach(function(selector) {
// Create a detached clone
var splitOutRule = shallowCloneNode(decl.parent);
splitOutRule.selector = selector;
splitOutRule.parent = decl.parent.parent;
var prop = decl.prop;
map[prop] = (map[prop] || []).concat({
decl: declClone,
prop: prop,
calculatedInPlaceValue: valueResults.value,
isImportant: decl.important || false,
variablesUsed: valueResults.variablesUsed,
parent: splitOutRule,
// variables inside root or at-rules (eg. @media, @support)
isUnderAtRule: splitOutRule.parent.type === "atrule"
});
});
var declClone = decl.clone();
splitOutRule.append(declClone);
let preserveDecl;
if (typeof opts.preserve === "function") {
preserveDecl = opts.preserve(decl);
} else {
preserveDecl = opts.preserve;
}
// Remove the variable declaration because they are pretty much useless after we resolve them
if (!preserveDecl) {
decl.remove();
}
// Or we can also just show the computed value used for that variable
else if (preserveDecl === "computed") {
decl.value = valueResults.value;
}
// Otherwise just keep them as var declarations
//else {}
var prop = decl.prop;
map[prop] = (map[prop] || []).concat({
decl: declClone,
prop: prop,
calculatedInPlaceValue: valueResults.value,
isImportant: decl.important || false,
variablesUsed: valueResults.variablesUsed,
parent: splitOutRule,
// variables inside root or at-rules (eg. @media, @support)
isUnderAtRule: splitOutRule.parent.type === "atrule"
});
// We add to the clean up list if we removed some variable declarations to make it become an empty rule
// We clean up later on because we don't want to modify the AST when we still need to reference these later on
if (declParentRule.nodes.length <= 0) {
nodesToRemoveAtEnd.push(declParentRule);
}
});
//console.log('Collecting variables defined END');
let preserveDecl;
if (typeof opts.preserve === "function") {
preserveDecl = opts.preserve(decl);
} else {
preserveDecl = opts.preserve;
}
// Remove the variable declaration because they are pretty much useless after we resolve them
if (!preserveDecl) {
decl.remove();
}
// Or we can also just show the computed value used for that variable
else if (preserveDecl === "computed") {
decl.value = valueResults.value;
}
// Otherwise just keep them as var declarations
//else {}
// Resolve variables everywhere
// ---------------------------------------------------------
// ---------------------------------------------------------
// We add to the clean up list if we removed some variable declarations to make it become an empty rule
// We clean up later on because we don't want to modify the AST when we still need to reference these later on
if (declParentRule.nodes.length <= 0) {
nodesToRemoveAtEnd.push(declParentRule);
}
});
//console.log('Collecting variables defined END');
// Collect all the rules that have declarations that use variables
var rulesThatHaveDeclarationsWithVariablesList = [];
css.walk(function(rule) {
// We're only interested in Containers with children.
if (rule.nodes === undefined) return;
// Resolve variables everywhere
// ---------------------------------------------------------
// ---------------------------------------------------------
var doesRuleUseVariables = rule.nodes.some(function(node) {
if (node.type === "decl") {
var decl = node;
// If it uses variables
// and is not a variable declarations that we may be preserving from earlier
if (
resolveValue.RE_VAR_FUNC.test(decl.value) &&
!RE_VAR_PROP.test(decl.prop)
) {
return true;
}
}
// Collect all the rules that have declarations that use variables
var rulesThatHaveDeclarationsWithVariablesList = [];
css.walk(function(rule) {
// We're only interested in Containers with children.
if (rule.nodes === undefined) return;
return false;
});
var doesRuleUseVariables = rule.nodes.some(function(node) {
if (node.type === "decl") {
var decl = node;
// If it uses variables
// and is not a variable declarations that we may be preserving from earlier
if (
resolveValue.RE_VAR_FUNC.test(decl.value) &&
!RE_VAR_PROP.test(decl.prop)
) {
return true;
}
if (doesRuleUseVariables) {
rulesThatHaveDeclarationsWithVariablesList.push(rule);
}
return false;
});
if (doesRuleUseVariables) {
rulesThatHaveDeclarationsWithVariablesList.push(rule);
}
});
rulesThatHaveDeclarationsWithVariablesList.forEach(function(rule) {
var rulesToWorkOn = [].concat(rule);
// Split out the rule into each comma separated selector piece
// We only need to split if it's actually a Rule with multiple selectors (comma separated)
if (rule.type === "rule" && rule.selectors.length > 1) {
// Reverse the selectors so that we can cloneAfter in the same comma separated order
rulesToWorkOn = rule.selectors.reverse().map(function(selector) {
var ruleClone = rule.cloneAfter();
ruleClone.selector = selector;
rulesThatHaveDeclarationsWithVariablesList.forEach(function(rule) {
var rulesToWorkOn = [].concat(rule);
// Split out the rule into each comma separated selector piece
// We only need to split if it's actually a Rule with multiple selectors (comma separated)
if (rule.type === "rule" && rule.selectors.length > 1) {
// Reverse the selectors so that we can cloneAfter in the same comma separated order
rulesToWorkOn = rule.selectors.reverse().map(function(selector) {
var ruleClone = rule.cloneAfter();
ruleClone.selector = selector;
return ruleClone;
});
return ruleClone;
});
rule.remove();
}
rule.remove();
}
// Resolve the declarations
rulesToWorkOn.forEach(function(ruleToWorkOn) {
ruleToWorkOn.nodes.slice(0).forEach(function(node) {
if (node.type === "decl") {
var decl = node;
resolveDecl(
decl,
map,
opts.preserve,
opts.preserveAtRulesOrder,
logResolveValueResult
);
}
// Resolve the declarations
rulesToWorkOn.forEach(function(ruleToWorkOn) {
ruleToWorkOn.nodes.slice(0).forEach(function(node) {
if (node.type === "decl") {
var decl = node;
resolveDecl(
decl,
map,
opts.preserve,
opts.preserveAtRulesOrder,
logResolveValueResult
);
}
});
});
});
});
// Clean up any nodes we don't want anymore
// We clean up at the end because we don't want to modify the AST when we still need to reference these later on
nodesToRemoveAtEnd.forEach(cleanUpNode);
// Clean up any nodes we don't want anymore
// We clean up at the end because we don't want to modify the AST when we still need to reference these later on
nodesToRemoveAtEnd.forEach(cleanUpNode);
// Clean up JS-injected variables marked for removal
injectedDeclsToRemoveAtEnd.forEach(function(injectedDecl) {
injectedDecl.remove();
});
// Clean up JS-injected variables marked for removal
injectedDeclsToRemoveAtEnd.forEach(function(injectedDecl) {
injectedDecl.remove();
});
//console.log('map', map);
//console.log('map', map);
/* * /
}
catch(e) {
//console.log('e', e.message);
console.log('e', e.message, e.stack);
}
/* */
/* * /
}
catch(e) {
//console.log('e', e.message);
console.log('e', e.message, e.stack);
}
/* */
}
};
});
};
module.exports.postcss = true;
{
"name": "postcss-css-variables",
"version": "0.17.0",
"version": "0.18.0",
"description": "PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation",

@@ -19,4 +19,3 @@ "keywords": [

"escape-string-regexp": "^1.0.3",
"extend": "^3.0.1",
"postcss": "^6.0.8"
"extend": "^3.0.1"
},

@@ -31,5 +30,9 @@ "devDependencies": {

"mocha": "^5.2.0",
"postcss": "^8.2.6",
"postcss-discard-comments": "^4.0.0",
"postcss-normalize-whitespace": "^4.0.0"
},
"peerDependencies": {
"postcss": "^8.2.6"
},
"scripts": {

@@ -36,0 +39,0 @@ "test": "mocha",

@@ -10,3 +10,3 @@ # PostCSS CSS Variables

```
npm install postcss-css-variables --save-dev
npm install postcss postcss-css-variables --save-dev
```

@@ -266,3 +266,3 @@

There is another similar plugin available, [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties), although it restricts itself much more than this plugin, preferring partial spec conformance. This plugin has the same capabilities but also adds imperfect feature support which stem from not being to know what the DOM will look like when you compile your CSS. We instead look at the explicit structure of your CSS selectors.
There is another similar plugin available, [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties), although it restricts itself much more than this plugin, preferring partial spec conformance. This plugin has the same capabilities but also adds imperfect feature support which stem from not being able to know what the DOM will look like when you compile your CSS. We instead look at the explicit structure of your CSS selectors.

@@ -269,0 +269,0 @@ ### Interoperability and differences from `postcss-custom-properties`