summaryrefslogtreecommitdiff
path: root/node_modules/csso/lib/clean
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/lib/clean
parent3fd9400d4dccc25aa29b5702216732e0b7542073 (diff)
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/csso/lib/clean')
-rw-r--r--node_modules/csso/lib/clean/Atrule.js69
-rw-r--r--node_modules/csso/lib/clean/Comment.js3
-rw-r--r--node_modules/csso/lib/clean/Declaration.js14
-rw-r--r--node_modules/csso/lib/clean/Raw.js9
-rw-r--r--node_modules/csso/lib/clean/Rule.js100
-rw-r--r--node_modules/csso/lib/clean/TypeSelector.js19
-rw-r--r--node_modules/csso/lib/clean/WhiteSpace.js3
-rw-r--r--node_modules/csso/lib/clean/index.js28
-rw-r--r--node_modules/csso/lib/clean/utils.js7
9 files changed, 252 insertions, 0 deletions
diff --git a/node_modules/csso/lib/clean/Atrule.js b/node_modules/csso/lib/clean/Atrule.js
new file mode 100644
index 00000000..236d122d
--- /dev/null
+++ b/node_modules/csso/lib/clean/Atrule.js
@@ -0,0 +1,69 @@
+import { keyword as resolveKeyword } from 'css-tree';
+import { hasNoChildren } from './utils.js';
+
+export default function cleanAtrule(node, item, list) {
+ if (node.block) {
+ // otherwise removed at-rule don't prevent @import for removal
+ if (this.stylesheet !== null) {
+ this.stylesheet.firstAtrulesAllowed = false;
+ }
+
+ if (hasNoChildren(node.block)) {
+ list.remove(item);
+ return;
+ }
+ }
+
+ switch (node.name) {
+ case 'charset':
+ if (hasNoChildren(node.prelude)) {
+ list.remove(item);
+ return;
+ }
+
+ // if there is any rule before @charset -> remove it
+ if (item.prev) {
+ list.remove(item);
+ return;
+ }
+
+ break;
+
+ case 'import':
+ if (this.stylesheet === null || !this.stylesheet.firstAtrulesAllowed) {
+ list.remove(item);
+ return;
+ }
+
+ // if there are some rules that not an @import or @charset before @import
+ // remove it
+ list.prevUntil(item.prev, function(rule) {
+ if (rule.type === 'Atrule') {
+ if (rule.name === 'import' || rule.name === 'charset') {
+ return;
+ }
+ }
+
+ this.root.firstAtrulesAllowed = false;
+ list.remove(item);
+
+ return true;
+ }, this);
+
+ break;
+
+ default: {
+ const name = resolveKeyword(node.name).basename;
+
+ if (name === 'keyframes' ||
+ name === 'media' ||
+ name === 'supports') {
+
+ // drop at-rule with no prelude
+ if (hasNoChildren(node.prelude) || hasNoChildren(node.block)) {
+ list.remove(item);
+ }
+ }
+ }
+ }
+};
diff --git a/node_modules/csso/lib/clean/Comment.js b/node_modules/csso/lib/clean/Comment.js
new file mode 100644
index 00000000..7744c6ba
--- /dev/null
+++ b/node_modules/csso/lib/clean/Comment.js
@@ -0,0 +1,3 @@
+export default function cleanComment(data, item, list) {
+ list.remove(item);
+};
diff --git a/node_modules/csso/lib/clean/Declaration.js b/node_modules/csso/lib/clean/Declaration.js
new file mode 100644
index 00000000..36af5a85
--- /dev/null
+++ b/node_modules/csso/lib/clean/Declaration.js
@@ -0,0 +1,14 @@
+import { property } from 'css-tree';
+
+export default function cleanDeclartion(node, item, list) {
+ if (node.value.children && node.value.children.isEmpty) {
+ list.remove(item);
+ return;
+ }
+
+ if (property(node.property).custom) {
+ if (/\S/.test(node.value.value)) {
+ node.value.value = node.value.value.trim();
+ }
+ }
+};
diff --git a/node_modules/csso/lib/clean/Raw.js b/node_modules/csso/lib/clean/Raw.js
new file mode 100644
index 00000000..b9ec0ae9
--- /dev/null
+++ b/node_modules/csso/lib/clean/Raw.js
@@ -0,0 +1,9 @@
+import { isNodeChildrenList } from './utils.js';
+
+export default function cleanRaw(node, item, list) {
+ // raw in stylesheet or block children
+ if (isNodeChildrenList(this.stylesheet, list) ||
+ isNodeChildrenList(this.block, list)) {
+ list.remove(item);
+ }
+};
diff --git a/node_modules/csso/lib/clean/Rule.js b/node_modules/csso/lib/clean/Rule.js
new file mode 100644
index 00000000..c4b02d2f
--- /dev/null
+++ b/node_modules/csso/lib/clean/Rule.js
@@ -0,0 +1,100 @@
+import { walk, keyword } from 'css-tree';
+import { hasNoChildren } from './utils.js';
+
+const { hasOwnProperty } = Object.prototype;
+const skipUsageFilteringAtrule = new Set(['keyframes']);
+
+function cleanUnused(selectorList, usageData) {
+ selectorList.children.forEach((selector, item, list) => {
+ let shouldRemove = false;
+
+ 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;
+}
+
+export default function cleanRule(node, item, list, options) {
+ if (hasNoChildren(node.prelude) || hasNoChildren(node.block)) {
+ list.remove(item);
+ return;
+ }
+
+ // avoid usage filtering for some at-rules
+ if (this.atrule && skipUsageFilteringAtrule.has(keyword(this.atrule.name).basename)) {
+ return;
+ }
+
+ const { usage } = options;
+
+ if (usage && (usage.whitelist !== null || usage.blacklist !== null)) {
+ cleanUnused(node.prelude, usage);
+
+ if (hasNoChildren(node.prelude)) {
+ list.remove(item);
+ return;
+ }
+ }
+};
diff --git a/node_modules/csso/lib/clean/TypeSelector.js b/node_modules/csso/lib/clean/TypeSelector.js
new file mode 100644
index 00000000..416b495d
--- /dev/null
+++ b/node_modules/csso/lib/clean/TypeSelector.js
@@ -0,0 +1,19 @@
+// remove useless universal selector
+export default function cleanTypeSelector(node, item, list) {
+ const name = item.data.name;
+
+ // check it's a non-namespaced universal selector
+ if (name !== '*') {
+ return;
+ }
+
+ // remove when universal selector before other selectors
+ const nextType = item.next && item.next.data.type;
+ if (nextType === 'IdSelector' ||
+ nextType === 'ClassSelector' ||
+ nextType === 'AttributeSelector' ||
+ nextType === 'PseudoClassSelector' ||
+ nextType === 'PseudoElementSelector') {
+ list.remove(item);
+ }
+};
diff --git a/node_modules/csso/lib/clean/WhiteSpace.js b/node_modules/csso/lib/clean/WhiteSpace.js
new file mode 100644
index 00000000..870befb1
--- /dev/null
+++ b/node_modules/csso/lib/clean/WhiteSpace.js
@@ -0,0 +1,3 @@
+export default function cleanWhitespace(node, item, list) {
+ list.remove(item);
+};
diff --git a/node_modules/csso/lib/clean/index.js b/node_modules/csso/lib/clean/index.js
new file mode 100644
index 00000000..4faa73a6
--- /dev/null
+++ b/node_modules/csso/lib/clean/index.js
@@ -0,0 +1,28 @@
+import { walk } from 'css-tree';
+import Atrule from './Atrule.js';
+import Comment from './Comment.js';
+import Declaration from './Declaration.js';
+import Raw from './Raw.js';
+import Rule from './Rule.js';
+import TypeSelector from './TypeSelector.js';
+import WhiteSpace from './WhiteSpace.js';
+
+const handlers = {
+ Atrule,
+ Comment,
+ Declaration,
+ Raw,
+ Rule,
+ TypeSelector,
+ WhiteSpace
+};
+
+export default function(ast, options) {
+ walk(ast, {
+ leave(node, item, list) {
+ if (handlers.hasOwnProperty(node.type)) {
+ handlers[node.type].call(this, node, item, list, options);
+ }
+ }
+ });
+};
diff --git a/node_modules/csso/lib/clean/utils.js b/node_modules/csso/lib/clean/utils.js
new file mode 100644
index 00000000..ca1d57c8
--- /dev/null
+++ b/node_modules/csso/lib/clean/utils.js
@@ -0,0 +1,7 @@
+export function hasNoChildren(node) {
+ return !node || !node.children || node.children.isEmpty;
+}
+
+export function isNodeChildrenList(node, list) {
+ return node !== null && node.children === list;
+}