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/lib/clean | |
| parent | 3fd9400d4dccc25aa29b5702216732e0b7542073 (diff) | |
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/csso/lib/clean')
| -rw-r--r-- | node_modules/csso/lib/clean/Atrule.js | 69 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/Comment.js | 3 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/Declaration.js | 14 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/Raw.js | 9 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/Rule.js | 100 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/TypeSelector.js | 19 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/WhiteSpace.js | 3 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/index.js | 28 | ||||
| -rw-r--r-- | node_modules/csso/lib/clean/utils.js | 7 |
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; +} |
