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-clamp/index.js | |
| parent | 3fd9400d4dccc25aa29b5702216732e0b7542073 (diff) | |
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/postcss-clamp/index.js')
| -rw-r--r-- | node_modules/postcss-clamp/index.js | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/node_modules/postcss-clamp/index.js b/node_modules/postcss-clamp/index.js new file mode 100644 index 00000000..474e8a62 --- /dev/null +++ b/node_modules/postcss-clamp/index.js @@ -0,0 +1,126 @@ +let valueParser = require('postcss-value-parser') + +function parseValue (value) { + let parsed = value.match(/([\d.-]+)(.*)/) + if (!parsed || !parsed[1] || !parsed[2] || isNaN(parsed[1])) { + return undefined + } + return [parseFloat(parsed[1]), parsed[2]] +} + +function compose (first, second, third) { + if (first && second && third) { + return `max(${first}, min(${second}, ${third}))` + } + if (first && second) { + return `max(${first}, ${second})` + } + + return first +} + +function updateValue (declaration, value, preserve) { + let newValue = value + let newValueAst = valueParser(value) + let valueAST = valueParser(declaration.value) + // Walk can't be interrupted, so we only care about first + let foundClamp = false + + valueAST.walk((node, index, nodes) => { + let isClamp = node.type === 'function' && node.value === 'clamp' + + if (!isClamp || foundClamp) { + return + } + + foundClamp = true + nodes[index] = newValueAst + }) + + if (foundClamp) { + newValue = valueAST.toString() + } + + if (preserve) { + declaration.cloneBefore({ value: newValue }) + } else { + declaration.value = newValue + } +} + +module.exports = opts => { + opts = opts || {} + let precalculate = opts.precalculate ? Boolean(opts.precalculate) : false + let preserve = opts.preserve ? Boolean(opts.preserve) : false + + return { + postcssPlugin: 'postcss-clamp', + Declaration (decl) { + if (!decl || !decl.value.includes('clamp')) { + return + } + valueParser(decl.value).walk(node => { + let nodes = node.nodes + if ( + node.type !== 'function' || + node.value !== 'clamp' || + nodes.length !== 5 + ) { + return + } + let first = nodes[0] + let second = nodes[2] + let third = nodes[4] + let naive = compose( + valueParser.stringify(first), + valueParser.stringify(second), + valueParser.stringify(third) + ) + if (!precalculate || second.type !== 'word' || third.type !== 'word') { + updateValue(decl, naive, preserve) + return + } + let parsedSecond = parseValue(second.value) + let parsedThird = parseValue(third.value) + if (parsedSecond === undefined || parsedThird === undefined) { + updateValue(decl, naive, preserve) + return + } + let [secondValue, secondUnit] = parsedSecond + let [thirdValue, thirdUnit] = parsedThird + if (secondUnit !== thirdUnit) { + updateValue(decl, naive, preserve) + return + } + let parsedFirst = parseValue(first.value) + if (parsedFirst === undefined) { + let secondThirdValue = `${secondValue + thirdValue}${secondUnit}` + updateValue( + decl, + compose(valueParser.stringify(first), secondThirdValue), + preserve + ) + return + } + let [firstValue, firstUnit] = parsedFirst + if (firstUnit !== secondUnit) { + let secondThirdValue = `${secondValue + thirdValue}${secondUnit}` + updateValue( + decl, + compose(valueParser.stringify(first), secondThirdValue), + preserve + ) + return + } + + updateValue( + decl, + compose(`${firstValue + secondValue + thirdValue}${secondUnit}`), + preserve + ) + }) + } + } +} + +module.exports.postcss = true |
