import { walk } from 'css-tree'; import { unsafeToSkipNode, isEqualSelectors, isEqualDeclarations, addSelectors, hasSimilarSelectors } from './utils.js'; function processRule(node, item, list) { const selectors = node.prelude.children; const declarations = node.block.children; list.prevUntil(item.prev, function(prev) { // skip non-ruleset node if safe if (prev.type !== 'Rule') { return unsafeToSkipNode.call(selectors, prev); } const prevSelectors = prev.prelude.children; const prevDeclarations = prev.block.children; // try to join rulesets with equal pseudo signature if (node.pseudoSignature === prev.pseudoSignature) { // try to join by selectors if (isEqualSelectors(prevSelectors, selectors)) { prevDeclarations.appendList(declarations); list.remove(item); return true; } // try to join by declarations if (isEqualDeclarations(declarations, prevDeclarations)) { addSelectors(prevSelectors, selectors); list.remove(item); return true; } } // go to prev ruleset if has no selector similarities return hasSimilarSelectors(selectors, prevSelectors); }); } // NOTE: direction should be left to right, since rulesets merge to left // ruleset. When direction right to left unmerged rulesets may prevent lookup // TODO: remove initial merge export default function initialMergeRule(ast) { walk(ast, { visit: 'Rule', enter: processRule }); };