diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2023-10-14 15:05:55 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2023-10-14 15:05:55 +0800 |
| commit | c06f7ee0a40255214c477e13d9b956a7e07c2900 (patch) | |
| tree | f5982a568ef8fab865d0142e71c7494fea3e4c1b /node_modules/postcss-minify-params/src/index.js | |
| parent | 3fd9400d4dccc25aa29b5702216732e0b7542073 (diff) | |
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/postcss-minify-params/src/index.js')
| -rw-r--r-- | node_modules/postcss-minify-params/src/index.js | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/node_modules/postcss-minify-params/src/index.js b/node_modules/postcss-minify-params/src/index.js new file mode 100644 index 00000000..c2cbe320 --- /dev/null +++ b/node_modules/postcss-minify-params/src/index.js @@ -0,0 +1,158 @@ +'use strict'; +const browserslist = require('browserslist'); +const valueParser = require('postcss-value-parser'); +const { getArguments } = require('cssnano-utils'); + +/** + * Return the greatest common divisor + * of two numbers. + * + * @param {number} a + * @param {number} b + * @return {number} + */ +function gcd(a, b) { + return b ? gcd(b, a % b) : a; +} + +/** + * @param {number} a + * @param {number} b + * @return {[number, number]} + */ +function aspectRatio(a, b) { + const divisor = gcd(a, b); + + return [a / divisor, b / divisor]; +} + +/** + * @param {valueParser.Node[]} args + * @return {string} + */ +function split(args) { + return args.map((arg) => valueParser.stringify(arg)).join(''); +} + +/** + * @param {valueParser.Node} node + * @return {void} + */ +function removeNode(node) { + node.value = ''; + node.type = 'word'; +} + +/** + * @param {unknown[]} items + * @return {string} + */ +function sortAndDedupe(items) { + const a = [...new Set(items)]; + a.sort(); + return a.join(); +} + +/** + * @param {boolean} legacy + * @param {import('postcss').AtRule} rule + * @return {void} + */ +function transform(legacy, rule) { + const ruleName = rule.name.toLowerCase(); + + // We should re-arrange parameters only for `@media` and `@supports` at-rules + if (!rule.params || !['media', 'supports'].includes(ruleName)) { + return; + } + + const params = valueParser(rule.params); + + params.walk((node, index) => { + if (node.type === 'div') { + node.before = node.after = ''; + } else if (node.type === 'function') { + node.before = ''; + if ( + node.nodes[0] && + node.nodes[0].type === 'word' && + node.nodes[0].value.startsWith('--') && + node.nodes[2] === undefined + ) { + node.after = ' '; + } else { + node.after = ''; + } + if ( + node.nodes[4] && + node.nodes[0].value.toLowerCase().indexOf('-aspect-ratio') === 3 + ) { + const [a, b] = aspectRatio( + Number(node.nodes[2].value), + Number(node.nodes[4].value) + ); + + node.nodes[2].value = a.toString(); + node.nodes[4].value = b.toString(); + } + } else if (node.type === 'space') { + node.value = ' '; + } else { + const prevWord = params.nodes[index - 2]; + + if ( + node.value.toLowerCase() === 'all' && + rule.name.toLowerCase() === 'media' && + !prevWord + ) { + const nextWord = params.nodes[index + 2]; + + if (!legacy || nextWord) { + removeNode(node); + } + + if (nextWord && nextWord.value.toLowerCase() === 'and') { + const nextSpace = params.nodes[index + 1]; + const secondSpace = params.nodes[index + 3]; + + removeNode(nextWord); + removeNode(nextSpace); + removeNode(secondSpace); + } + } + } + }, true); + + rule.params = sortAndDedupe(getArguments(params).map(split)); + + if (!rule.params.length) { + rule.raws.afterName = ''; + } +} + +const allBugBrowers = new Set(['ie 10', 'ie 11']); + +/** + * @type {import('postcss').PluginCreator<browserslist.Options>} + * @param {browserslist.Options} options + * @return {import('postcss').Plugin} + */ +function pluginCreator(options = {}) { + const browsers = browserslist(null, { + stats: options.stats, + path: __dirname, + env: options.env, + }); + + const hasAllBug = browsers.some((browser) => allBugBrowers.has(browser)); + return { + postcssPlugin: 'postcss-minify-params', + + OnceExit(css) { + css.walkAtRules((rule) => transform(hasAllBug, rule)); + }, + }; +} + +pluginCreator.postcss = true; +module.exports = pluginCreator; |
