Skip to content

Commit 88ec720

Browse files
committed
feat: add ability to preserve undefined variables
1 parent 0b8e46d commit 88ec720

File tree

4 files changed

+20
-13
lines changed

4 files changed

+20
-13
lines changed

index.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ var defaults = {
6060
preserveInjectedVariables: true,
6161
// Will write media queries in the same order as in the original file.
6262
// Currently defaulted to false for legacy behavior. We can update to `true` in a major version
63-
preserveAtRulesOrder: false
63+
preserveAtRulesOrder: false,
64+
// Allows you to preserve custom properties which can't calculated during build time
65+
// Currently defaulted to false for legacy behavior which produces undefined when custom properties can't be calculated during build time
66+
preserveUndefinedVariables: false,
6467
};
6568

6669
module.exports = (options = {}) => {
@@ -158,7 +161,7 @@ module.exports = (options = {}) => {
158161
eachCssVariableDeclaration(css, function(decl) {
159162
var declParentRule = decl.parent;
160163

161-
var valueResults = logResolveValueResult(resolveValue(decl, map));
164+
var valueResults = logResolveValueResult(resolveValue(decl, map, undefined, opts.preserveUndefinedVariables));
162165
// Split out each selector piece into its own declaration for easier logic down the road
163166
decl.parent.selectors.forEach(function(selector) {
164167
// Create a detached clone
@@ -263,7 +266,8 @@ module.exports = (options = {}) => {
263266
map,
264267
opts.preserve,
265268
opts.preserveAtRulesOrder,
266-
logResolveValueResult
269+
logResolveValueResult,
270+
opts.preserveUndefinedVariables
267271
);
268272
}
269273
});

lib/resolve-decl.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function eachMapItemDependencyOfDecl(variablesUsedList, map, decl, cb) {
7171

7272
// Resolve the decl with the computed value
7373
// Also add in any media queries that change the value as necessary
74-
function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/preserveAtRulesOrder, /*optional*/logResolveValueResult) {
74+
function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/preserveAtRulesOrder, /*optional*/logResolveValueResult, /*optional*/preserveUndefinedVariables) {
7575
shouldPreserve = (typeof shouldPreserve === "function" ? shouldPreserve(decl) : shouldPreserve) || false;
7676
preserveAtRulesOrder = preserveAtRulesOrder || false;
7777

@@ -88,7 +88,7 @@ function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/preserve
8888

8989
// Grab the balue for this declarations
9090
//console.log('resolveDecl 1');
91-
var valueResults = _logResolveValueResult(resolveValue(decl, map));
91+
var valueResults = _logResolveValueResult(resolveValue(decl, map, undefined, preserveUndefinedVariables));
9292

9393

9494
// Resolve the cascade dependencies
@@ -112,7 +112,7 @@ function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/preserve
112112
}
113113

114114
// No mangle resolve
115-
declClone.value = _logResolveValueResult(resolveValue(mimicDecl, map, true)).value;
115+
declClone.value = _logResolveValueResult(resolveValue(mimicDecl, map, true, preserveUndefinedVariables)).value;
116116

117117
if(mapItem.isUnderAtRule) {
118118
// Create the clean atRule for which we place the declaration under

lib/resolve-value.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ function balancedVar(value) {
6161
// Note: We do not modify the declaration
6262
// Note: Resolving a declaration value without any `var(...)` does not harm the final value.
6363
// This means, feel free to run everything through this function
64-
var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal debugging*/_debugIsInternal) {
65-
var debugIndent = _debugIsInternal ? '\t' : '';
66-
64+
var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*optional*/preserveUndefinedVariables) {
6765
var matchingVarDecl = undefined;
6866
var resultantValue = toString(decl.value);
6967
var warnings = [];
@@ -157,17 +155,22 @@ var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal
157155
}
158156

159157
isResultantValueUndefined = replaceValue === undefined;
160-
if(isResultantValueUndefined) {
158+
159+
if(isResultantValueUndefined && !preserveUndefinedVariables) {
161160
warnings.push(['variable ' + variableName + ' is undefined and used without a fallback', { node: decl }]);
162161
}
163162

163+
replaceValue = isResultantValueUndefined && preserveUndefinedVariables
164+
? 'var(' + matchingVarDecl.body + ')'
165+
: replaceValue
166+
164167
// Replace original declaration with found value
165168
resultantValue = (matchingVarDecl.pre || '') + replaceValue + (matchingVarDecl.post || '')
166169
}
167170

168171
return {
169172
// The resolved value
170-
value: !isResultantValueUndefined ? resultantValue : undefined,
173+
value: isResultantValueUndefined && !preserveUndefinedVariables ? undefined : resultantValue,
171174
// Array of variable names used in resolving this value
172175
variablesUsed: variablesUsedInValue,
173176
// Any warnings generated from parsing this value

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "postcss-css-variables",
3-
"version": "0.19.0",
2+
"name": "postcss-calc-css-variables",
3+
"version": "0.20.0",
44
"description": "PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation",
55
"keywords": [
66
"postcss",

0 commit comments

Comments
 (0)