From 46a3b8e2f821d0219608993dc6539b51bfab2d1b Mon Sep 17 00:00:00 2001 From: Adam Detrick Date: Tue, 26 Jun 2018 15:22:54 -0400 Subject: [PATCH 1/3] Add `opts.preserveInjectedVariables` (#74) Adds `opts.preserveInjectedVariables`, which when set to false, removes custom property declarations added via `opts.variables`. --- README.md | 7 ++++ index.js | 19 ++++++++++- .../fixtures/js-defined-preserve-injected.css | 5 +++ .../js-defined-preserve-injected.expected.css | 8 +++++ test/fixtures/js-defined-preserve.css | 5 +++ .../fixtures/js-defined-preserve.expected.css | 18 ++++++++++ test/test.js | 33 ++++++++++++++----- 7 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/js-defined-preserve-injected.css create mode 100644 test/fixtures/js-defined-preserve-injected.expected.css create mode 100644 test/fixtures/js-defined-preserve.css create mode 100644 test/fixtures/js-defined-preserve.expected.css diff --git a/README.md b/README.md index f74a8c2..acdf7a6 100644 --- a/README.md +++ b/README.md @@ -368,6 +368,13 @@ Can be a simple key-value pair or an object with a `value` property and an optio The object keys are automatically prefixed with `--` (according to CSS custom property syntax) if you do not provide it. +### `preserveInjectedVariables` (default: `true`) + +Whether to preserve the custom property declarations inserted via the `variables` option from final output. + +A typical use case is [CSS Modules](https://github.com/css-modules/css-modules), where you would want to avoid +repeating custom property definitions in every module passed through this plugin. Setting this option to `false` +prevents JS-injected variables from appearing in output CSS. ```js var postcss = require('postcss'); diff --git a/index.js b/index.js index 2d00b8a..73486f9 100644 --- a/index.js +++ b/index.js @@ -62,7 +62,10 @@ var defaults = { // Define variables via JS // Simple key-value pair // or an object with a `value` property and an optional `isImportant` bool property - variables: {} + variables: {}, + // Preserve variables injected via JS with the `variables` option above + // before serializing to CSS (`false` will remove these variables from output) + preserveInjectedVariables: true }; module.exports = postcss.plugin('postcss-css-variables', function(options) { @@ -82,6 +85,10 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) { // 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 = []; + // Map of variable names to a list of declarations var map = {}; @@ -106,6 +113,11 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) { }); variableRootRule.append(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, @@ -249,6 +261,11 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) { // 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(); + }); + //console.log('map', map); diff --git a/test/fixtures/js-defined-preserve-injected.css b/test/fixtures/js-defined-preserve-injected.css new file mode 100644 index 0000000..135dd4a --- /dev/null +++ b/test/fixtures/js-defined-preserve-injected.css @@ -0,0 +1,5 @@ +.box1 { + width: var(--js-defined1); + height: var(--js-defined2); + background: var(--js-defined-no-prefix); +} diff --git a/test/fixtures/js-defined-preserve-injected.expected.css b/test/fixtures/js-defined-preserve-injected.expected.css new file mode 100644 index 0000000..c217850 --- /dev/null +++ b/test/fixtures/js-defined-preserve-injected.expected.css @@ -0,0 +1,8 @@ +.box1 { + width: 75px; + width: var(--js-defined1); + height: 80px; + height: var(--js-defined2); + background: #ff0000; + background: var(--js-defined-no-prefix); +} diff --git a/test/fixtures/js-defined-preserve.css b/test/fixtures/js-defined-preserve.css new file mode 100644 index 0000000..135dd4a --- /dev/null +++ b/test/fixtures/js-defined-preserve.css @@ -0,0 +1,5 @@ +.box1 { + width: var(--js-defined1); + height: var(--js-defined2); + background: var(--js-defined-no-prefix); +} diff --git a/test/fixtures/js-defined-preserve.expected.css b/test/fixtures/js-defined-preserve.expected.css new file mode 100644 index 0000000..ad4a6eb --- /dev/null +++ b/test/fixtures/js-defined-preserve.expected.css @@ -0,0 +1,18 @@ +:root { + --js-defined-no-prefix: #ff0000; +} +:root { + --js-defined2: 80px; +} +:root { + --js-defined1: 75px; +} + +.box1 { + width: 75px; + width: var(--js-defined1); + height: 80px; + height: var(--js-defined2); + background: #ff0000; + background: var(--js-defined-no-prefix); +} diff --git a/test/test.js b/test/test.js index dda3982..098852f 100644 --- a/test/test.js +++ b/test/test.js @@ -12,6 +12,14 @@ var cssvariables = require('../'); var CleanCSS = require('clean-css'); +var MOCK_JS_VARIABLES = { + '--js-defined1': '75px', + '--js-defined2': { + value: '80px' + }, + // Should be automatically prefixed with `--` + 'js-defined-no-prefix': '#ff0000' +}; var testPlugin = function(filePath, expectedFilePath, options) { options = options || {}; @@ -146,20 +154,27 @@ describe('postcss-css-variables', function() { test( 'should work with JS defined variables', 'js-defined', + { variables: MOCK_JS_VARIABLES } + ); + test( + 'should preserve -- declarations and var() values with `options.variables` AND `options.preserve`', + 'js-defined-preserve', + { + variables: MOCK_JS_VARIABLES, + preserve: true + } + ); + test( + 'should preserve var() values and clean injected declarations with `options.variables` AND `options.preserve` AND `options.preserveInjectedVariables: false`', + 'js-defined-preserve-injected', { - variables: { - '--js-defined1': '75px', - '--js-defined2': { - value: '80px' - }, - // Should be automatically prefixed with `--` - 'js-defined-no-prefix': '#ff0000' - } + variables: MOCK_JS_VARIABLES, + preserve: true, + preserveInjectedVariables: false, } ); }); - describe('with `options.preserve`', function() { test( 'preserves variables when `preserve` is `true`', From ccb2fd78927e9839b2f0f6d1283eaa3c397acae4 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 26 Jun 2018 14:25:15 -0500 Subject: [PATCH 2/3] Prepare changelog for 0.9.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e648496..bc090d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +# v0.9.0 - 2018-6-26 + + - Adds `opts.preserveInjectedVariables`, which when set to `false`, removes the `:root { ... }` custom property declarations added via `opts.variables` + - Thank you to [@akdetrick](https://github.com/akdetrick) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/74) + + # v0.8.1 - 2018-3-21 - Log `undefined` variables (available in `result.warnings()`) From 5a269a8742518fb04fdb983edefa48735b10319f Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 26 Jun 2018 14:25:23 -0500 Subject: [PATCH 3/3] 0.9.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3229e56..076a8bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-css-variables", - "version": "0.8.1", + "version": "0.9.0", "description": "PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation", "keywords": [ "postcss",