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/csso/cjs/clean/Rule.cjs | |
| parent | 3fd9400d4dccc25aa29b5702216732e0b7542073 (diff) | |
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/csso/cjs/clean/Rule.cjs')
| -rw-r--r-- | node_modules/csso/cjs/clean/Rule.cjs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/node_modules/csso/cjs/clean/Rule.cjs b/node_modules/csso/cjs/clean/Rule.cjs new file mode 100644 index 00000000..064bc7d7 --- /dev/null +++ b/node_modules/csso/cjs/clean/Rule.cjs @@ -0,0 +1,104 @@ +'use strict'; + +const cssTree = require('css-tree'); +const utils = require('./utils.cjs'); + +const { hasOwnProperty } = Object.prototype; +const skipUsageFilteringAtrule = new Set(['keyframes']); + +function cleanUnused(selectorList, usageData) { + selectorList.children.forEach((selector, item, list) => { + let shouldRemove = false; + + cssTree.walk(selector, function(node) { + // ignore nodes in nested selectors + if (this.selector === null || this.selector === selectorList) { + switch (node.type) { + case 'SelectorList': + // TODO: remove toLowerCase when pseudo selectors will be normalized + // ignore selectors inside :not() + if (this.function === null || this.function.name.toLowerCase() !== 'not') { + if (cleanUnused(node, usageData)) { + shouldRemove = true; + } + } + break; + + case 'ClassSelector': + if (usageData.whitelist !== null && + usageData.whitelist.classes !== null && + !hasOwnProperty.call(usageData.whitelist.classes, node.name)) { + shouldRemove = true; + } + if (usageData.blacklist !== null && + usageData.blacklist.classes !== null && + hasOwnProperty.call(usageData.blacklist.classes, node.name)) { + shouldRemove = true; + } + break; + + case 'IdSelector': + if (usageData.whitelist !== null && + usageData.whitelist.ids !== null && + !hasOwnProperty.call(usageData.whitelist.ids, node.name)) { + shouldRemove = true; + } + if (usageData.blacklist !== null && + usageData.blacklist.ids !== null && + hasOwnProperty.call(usageData.blacklist.ids, node.name)) { + shouldRemove = true; + } + break; + + case 'TypeSelector': + // TODO: remove toLowerCase when type selectors will be normalized + // ignore universal selectors + if (node.name.charAt(node.name.length - 1) !== '*') { + if (usageData.whitelist !== null && + usageData.whitelist.tags !== null && + !hasOwnProperty.call(usageData.whitelist.tags, node.name.toLowerCase())) { + shouldRemove = true; + } + if (usageData.blacklist !== null && + usageData.blacklist.tags !== null && + hasOwnProperty.call(usageData.blacklist.tags, node.name.toLowerCase())) { + shouldRemove = true; + } + } + break; + } + } + }); + + if (shouldRemove) { + list.remove(item); + } + }); + + return selectorList.children.isEmpty; +} + +function cleanRule(node, item, list, options) { + if (utils.hasNoChildren(node.prelude) || utils.hasNoChildren(node.block)) { + list.remove(item); + return; + } + + // avoid usage filtering for some at-rules + if (this.atrule && skipUsageFilteringAtrule.has(cssTree.keyword(this.atrule.name).basename)) { + return; + } + + const { usage } = options; + + if (usage && (usage.whitelist !== null || usage.blacklist !== null)) { + cleanUnused(node.prelude, usage); + + if (utils.hasNoChildren(node.prelude)) { + list.remove(item); + return; + } + } +} + +module.exports = cleanRule; |
