UNPKG

unnestcss

Version:
91 lines 3.32 kB
import postcss from "postcss"; import { combineSelectors, combineAtRules } from "./combine.js"; import { isAtRule, isDecl, isRule } from "./help.js"; export class Parser { get css() { return this.toString(); } constructor(raw) { this.raw = raw; this.root = postcss.parse(raw); } unnest() { const originalNodes = [...this.root.nodes]; originalNodes.forEach((node) => { this.__processNode(node, node, undefined, undefined); }); } __processNode(currentNode, originalNode, parentSelectors, parentAtRules) { if (isRule(currentNode)) { this.__processRuleNode(currentNode, originalNode, parentSelectors, parentAtRules); } else if (isAtRule(currentNode)) { this.__processAtRuleNode(currentNode, originalNode, parentSelectors, parentAtRules); } } __processRuleNode(currentNode, originalNode, parentSelectors, parentAtRules) { const declNodes = currentNode.nodes.filter(isDecl); const ruleNodes = currentNode.nodes.filter(isRule); const atRuleNodes = currentNode.nodes.filter(isAtRule); const selectors = combineSelectors(currentNode.selectors, parentSelectors); ruleNodes.forEach((ruleNode) => { this.__processNode(ruleNode, originalNode, selectors, parentAtRules); }); atRuleNodes.forEach((atNode) => { this.__processNode(atNode, originalNode, selectors, parentAtRules); }); if (declNodes.length) { const { topNode, insertAtRuleNode } = this.__createParentAtRules(parentAtRules); const newRule = new postcss.Rule({ selectors, nodes: declNodes, }); if (insertAtRuleNode) { insertAtRuleNode.nodes.push(newRule); } this.root.insertBefore(originalNode, topNode || newRule); originalNode.remove(); } } __processAtRuleNode(currentNode, originalNode, parentSelectors, parentAtRules) { const { name, params } = currentNode; const currentAtRules = [ ...(parentAtRules || []), { name, params, }, ]; currentNode.nodes.forEach((node) => { if (isRule(node) || isAtRule(node)) { this.__processNode(node, originalNode, parentSelectors, currentAtRules); } }); } __createParentAtRules(parentAtRules) { let insertAtRuleNode; let topNode; if (parentAtRules) { const atRules = combineAtRules(...parentAtRules); atRules.forEach(({ name, params }, index) => { const newAtRule = new postcss.AtRule({ name, params, nodes: [], }); if (insertAtRuleNode) { insertAtRuleNode.nodes.push(newAtRule); } insertAtRuleNode = newAtRule; if (index === 0) { topNode = newAtRule; } }); } return { topNode, insertAtRuleNode }; } toString() { return this.root.toString(); } } //# sourceMappingURL=parser.js.map