From d0e455915f0670dfec70530f35e56e660cea4adc Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Wed, 20 Sep 2023 18:25:10 +0200 Subject: [PATCH 1/5] custom plugin to combine rules --- build/postcss-combine-selectors.cjs | 88 +++++++++++++++++++++++++++++ postcss.config.cjs | 4 +- 2 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 build/postcss-combine-selectors.cjs diff --git a/build/postcss-combine-selectors.cjs b/build/postcss-combine-selectors.cjs new file mode 100644 index 00000000..47218978 --- /dev/null +++ b/build/postcss-combine-selectors.cjs @@ -0,0 +1,88 @@ +const creator = () => { + return { + postcssPlugin: 'postcss-combine-selectors', + Once(root) { + const rulesToCombine = new Map(); + + root.walkRules(rule => { + if (isKeyframesRule(rule)) { + return; + } + + const key = ruleKey(rule); + const existing = rulesToCombine.get(key); + + // Existing group: + // - add rule to the group + if (existing) { + existing.rules.push(rule); + return; + } + + // New group: + // - first rule is the one we're going to combine into + // - create an empty slice for other rules to be added to + rulesToCombine.set(key, { + first: rule, + rules: [] + }); + }); + + // Iterate over all groups + for (const { first, rules } of rulesToCombine.values()) { + // If there was only one rule for a given group, there's nothing to combine + if (rules.length === 0) { + continue; + } + + // Append all contents of all subsequent rules to the first rule + for (const rule of rules) { + rule.each((child) => { + child.remove(); + first.append(child); + }) + + // Remove the now-empty rule + rule.remove(); + } + } + }, + }; +}; + +/** + * Construct a key that is specific to the AST ancestry of the rule. + * Only rules with the same key can be combined. + * + * @param {import('postcss').Rule} rule + * @returns {string} + */ +function ruleKey(rule) { + let key = `[rule ${rule.selector}]`; + + let ancestor = rule.parent; + while (ancestor) { + if (ancestor.type === 'atrule') { + key = `[${ancestor.name} ${ancestor.params}]${key}`; + } else if (ancestor.type === 'rule') { + key = `[rule ${ancestor.selector}]${key}`; + } else if (ancestor.type === 'root') { + break; + } + + ancestor = ancestor.parent; + } + + return key; +} + +function isKeyframesRule(rule) { + if (rule.parent?.type === 'atrule' && rule.parent.name === 'keyframes') { + return true; + } + + return false; +} + +module.exports = creator; +module.exports.postcss = true; diff --git a/postcss.config.cjs b/postcss.config.cjs index 7ac657c9..6db7ba91 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -1,7 +1,7 @@ const postcssPresetEnv = require('postcss-preset-env') const postcssImport = require('postcss-import') const cssnano = require('cssnano') -const combineSelectors = require('postcss-combine-duplicated-selectors') +const combineSelectors = require('./build/postcss-combine-selectors.cjs') const lib = process.env.npm_lifecycle_event @@ -11,6 +11,7 @@ const inlineMediaQueries = lib === 'lib:media' || lib === 'lib:supports' module.exports = { plugins: [ postcssImport(), + combineSelectors(), postcssPresetEnv({ stage: 0, autoprefixer: false, @@ -28,7 +29,6 @@ module.exports = { 'double-position-gradients': false, } }), - combineSelectors(), cssnano({ preset: 'default' }), From 43b2882739e7f9c6380c994393e1e7a295f1f997 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Wed, 20 Sep 2023 18:26:42 +0200 Subject: [PATCH 2/5] fmt --- build/postcss-combine-selectors.cjs | 158 ++++++++++++++-------------- postcss.config.cjs | 2 +- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/build/postcss-combine-selectors.cjs b/build/postcss-combine-selectors.cjs index 47218978..0fa3cbc0 100644 --- a/build/postcss-combine-selectors.cjs +++ b/build/postcss-combine-selectors.cjs @@ -1,88 +1,88 @@ const creator = () => { - return { - postcssPlugin: 'postcss-combine-selectors', - Once(root) { - const rulesToCombine = new Map(); - - root.walkRules(rule => { - if (isKeyframesRule(rule)) { - return; - } - - const key = ruleKey(rule); - const existing = rulesToCombine.get(key); - - // Existing group: - // - add rule to the group - if (existing) { - existing.rules.push(rule); - return; - } - - // New group: - // - first rule is the one we're going to combine into - // - create an empty slice for other rules to be added to - rulesToCombine.set(key, { - first: rule, - rules: [] - }); - }); - - // Iterate over all groups - for (const { first, rules } of rulesToCombine.values()) { - // If there was only one rule for a given group, there's nothing to combine - if (rules.length === 0) { - continue; - } - - // Append all contents of all subsequent rules to the first rule - for (const rule of rules) { - rule.each((child) => { - child.remove(); - first.append(child); - }) - - // Remove the now-empty rule - rule.remove(); - } - } - }, - }; -}; + return { + postcssPlugin: 'postcss-combine-selectors', + Once(root) { + const rulesToCombine = new Map() + + root.walkRules(rule => { + if (isKeyframesRule(rule)) { + return + } + + const key = ruleKey(rule) + const existing = rulesToCombine.get(key) + + // Existing group: + // - add rule to the group + if (existing) { + existing.rules.push(rule) + return + } + + // New group: + // - first rule is the one we're going to combine into + // - create an empty slice for other rules to be added to + rulesToCombine.set(key, { + first: rule, + rules: [] + }) + }) + + // Iterate over all groups + for (const { first, rules } of rulesToCombine.values()) { + // If there was only one rule for a given group, there's nothing to combine + if (rules.length === 0) { + continue + } + + // Append all contents of all subsequent rules to the first rule + for (const rule of rules) { + rule.each((child) => { + child.remove() + first.append(child) + }) + + // Remove the now-empty rule + rule.remove() + } + } + }, + } +} /** - * Construct a key that is specific to the AST ancestry of the rule. - * Only rules with the same key can be combined. - * - * @param {import('postcss').Rule} rule - * @returns {string} - */ +* Construct a key that is specific to the AST ancestry of the rule. +* Only rules with the same key can be combined. +* +* @param {import('postcss').Rule} rule +* @returns {string} +*/ function ruleKey(rule) { - let key = `[rule ${rule.selector}]`; - - let ancestor = rule.parent; - while (ancestor) { - if (ancestor.type === 'atrule') { - key = `[${ancestor.name} ${ancestor.params}]${key}`; - } else if (ancestor.type === 'rule') { - key = `[rule ${ancestor.selector}]${key}`; - } else if (ancestor.type === 'root') { - break; - } - - ancestor = ancestor.parent; - } - - return key; + let key = `[rule ${rule.selector}]` + + let ancestor = rule.parent + while (ancestor) { + if (ancestor.type === 'atrule') { + key = `[${ancestor.name} ${ancestor.params}]${key}` + } else if (ancestor.type === 'rule') { + key = `[rule ${ancestor.selector}]${key}` + } else if (ancestor.type === 'root') { + break + } + + ancestor = ancestor.parent + } + + return key } function isKeyframesRule(rule) { - if (rule.parent?.type === 'atrule' && rule.parent.name === 'keyframes') { - return true; - } - - return false; + if (rule.parent?.type === 'atrule' && rule.parent.name === 'keyframes') { + return true + } + + return false } -module.exports = creator; -module.exports.postcss = true; +module.exports = creator +module.exports.postcss = true diff --git a/postcss.config.cjs b/postcss.config.cjs index 6db7ba91..5d258721 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -1,7 +1,7 @@ const postcssPresetEnv = require('postcss-preset-env') const postcssImport = require('postcss-import') const cssnano = require('cssnano') -const combineSelectors = require('./build/postcss-combine-selectors.cjs') +const combineSelectors = require('./build/postcss-combine-selectors.cjs') const lib = process.env.npm_lifecycle_event From c23337126dcc97923acf1aa145bb60eb520e1a19 Mon Sep 17 00:00:00 2001 From: Romain Menke <11521496+romainmenke@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:51:29 +0200 Subject: [PATCH 3/5] Update postcss-combine-selectors.cjs --- build/postcss-combine-selectors.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/postcss-combine-selectors.cjs b/build/postcss-combine-selectors.cjs index 0fa3cbc0..497504db 100644 --- a/build/postcss-combine-selectors.cjs +++ b/build/postcss-combine-selectors.cjs @@ -1,7 +1,7 @@ const creator = () => { return { postcssPlugin: 'postcss-combine-selectors', - Once(root) { + OnceExit(root) { const rulesToCombine = new Map() root.walkRules(rule => { From 69b9ce895b4a90f63e6bbfea571073cfdb812d9c Mon Sep 17 00:00:00 2001 From: Romain Menke <11521496+romainmenke@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:57:08 +0200 Subject: [PATCH 4/5] Update postcss.config.cjs --- postcss.config.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postcss.config.cjs b/postcss.config.cjs index 5d258721..5a74ce6d 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -11,7 +11,6 @@ const inlineMediaQueries = lib === 'lib:media' || lib === 'lib:supports' module.exports = { plugins: [ postcssImport(), - combineSelectors(), postcssPresetEnv({ stage: 0, autoprefixer: false, @@ -29,6 +28,7 @@ module.exports = { 'double-position-gradients': false, } }), + combineSelectors(), cssnano({ preset: 'default' }), From 857581dcc20c4dc6bd92b94901664b30a1847c54 Mon Sep 17 00:00:00 2001 From: Adam Argyle Date: Wed, 20 Sep 2023 12:50:24 -0700 Subject: [PATCH 5/5] removes the postcss plugin from package.json --- package-lock.json | 72 ++--------------------------------------------- package.json | 1 - 2 files changed, 2 insertions(+), 71 deletions(-) diff --git a/package-lock.json b/package-lock.json index c985b577..4e0659ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-props", - "version": "1.5.10", + "version": "1.5.16", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "open-props", - "version": "1.5.10", + "version": "1.5.16", "license": "MIT", "devDependencies": { "ava": "^3.15.0", @@ -17,7 +17,6 @@ "open-color": "^1.9.1", "postcss": "^8.3.9", "postcss-cli": "^8.3.1", - "postcss-combine-duplicated-selectors": "^10.0.3", "postcss-import": "^14.0.2", "postcss-preset-env": "6.7.x", "typescript": "^4.9.4" @@ -3894,46 +3893,6 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-combine-duplicated-selectors": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-10.0.3.tgz", - "integrity": "sha512-IP0BmwFloCskv7DV7xqvzDXqMHpwdczJa6ZvIW8abgHdcIHs9mCJX2ltFhu3EwA51ozp13DByng30+Ke+eIExA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-combine-duplicated-selectors/node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-combine-duplicated-selectors/node_modules/postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-convert-values": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", @@ -9197,33 +9156,6 @@ "postcss-value-parser": "^4.2.0" } }, - "postcss-combine-duplicated-selectors": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-10.0.3.tgz", - "integrity": "sha512-IP0BmwFloCskv7DV7xqvzDXqMHpwdczJa6ZvIW8abgHdcIHs9mCJX2ltFhu3EwA51ozp13DByng30+Ke+eIExA==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - }, - "dependencies": { - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - } - } - }, "postcss-convert-values": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", diff --git a/package.json b/package.json index e969dd07..8e084174 100644 --- a/package.json +++ b/package.json @@ -317,7 +317,6 @@ "open-color": "^1.9.1", "postcss": "^8.3.9", "postcss-cli": "^8.3.1", - "postcss-combine-duplicated-selectors": "^10.0.3", "postcss-import": "^14.0.2", "postcss-preset-env": "6.7.x", "typescript": "^4.9.4"