css-flatten
Version:
Flattens a nested (S)CSS string, '&' placeholders are supported too.
41 lines (40 loc) • 1.3 kB
JavaScript
/* IMPORT */
import Parser from 'css-simple-parser';
import Resolve from './resolve.js';
/* MAIN */
const flatten = (css) => {
/* PARSING */
const AST = Parser.parse(css);
/* RESOLVING SELECTORS */
const selectorsCache = new Map();
Parser.traverse(AST, node => {
const { selector, parent } = node;
let selectors = selector.trim().split(/\s*,\s*/g); // Splitting and cleaning up
if ('selector' in parent) { // Regular node
selectors = Resolve.selectors(selectors, selectorsCache.get(parent) || []);
node.selector = selectors.join(',');
}
else { // Top-level node
if (selector.indexOf('&') >= 0)
throw new Error('Top-level ampersand placeholders are invalid');
}
selectorsCache.set(node, selectors);
});
/* FLATTENING */
const nodes = [];
Parser.traverse(AST, node => {
if (!/\S/.test(node.body))
return; // Ignoring empty blocks, nothing to output
nodes.push(node);
});
AST.children = nodes;
/* WIDOWING */
const empty = [];
for (let i = 0, l = nodes.length; i < l; i++) {
nodes[i].children = empty;
}
/* STRINGIFYING */
return Parser.stringify(AST);
};
/* EXPORT */
export default flatten;