summaryrefslogtreecommitdiff
path: root/node_modules/csso/cjs/clean/Rule.cjs
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-10-14 15:05:55 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-10-14 15:05:55 +0800
commitc06f7ee0a40255214c477e13d9b956a7e07c2900 (patch)
treef5982a568ef8fab865d0142e71c7494fea3e4c1b /node_modules/csso/cjs/clean/Rule.cjs
parent3fd9400d4dccc25aa29b5702216732e0b7542073 (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.cjs104
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;