packages/posthtml-transform/lib/rule.js (62 lines of code) (raw):

const valuesParser = require('postcss-values-parser'); const { strip: stripSlashes } = require('slashes'); const unquote = require('unquote'); const CSS_VALUE_TYPE_REGEXP = /^(word|func|number|string)$/; const NODE_TYPES = { WORD: 'word', FUNCTION: 'func', NUMBER: 'number', STRING: 'string', COMMA: 'comma' }; module.exports = class Rule { static parseValue(val) { const value = stripSlashes(val); const root = valuesParser(value).parse(); const values = []; let counter = 0; root.first.nodes.forEach(node => { switch (node.type) { case NODE_TYPES.WORD: case NODE_TYPES.FUNCTION: case NODE_TYPES.NUMBER: case NODE_TYPES.STRING: if (!values[counter]) { values[counter] = []; } const nodeValue = node.type === NODE_TYPES.FUNCTION ? node.toString().trim() : unquote(node.value).trim(); values[counter].push(nodeValue); break; case NODE_TYPES.COMMA: counter++; break; } }); return values; } constructor({ attr, value, selector, tag }) { this.attr = attr; this.tag = tag; const parsedVal = Rule.parseValue(value); const isSingleValue = parsedVal.length === 1; const isMultipleVal = !isSingleValue; if (isSingleValue) { this.value = parsedVal[0][0]; this.selector = unquote(selector) || parsedVal[0][1]; // Override selector from second value part } else { this.value = parsedVal; this.selector = unquote(selector); } this.isMultiple = isMultipleVal; } /** * @return {Rule[]} */ splitByMultipleValue() { return this.value.map(value => new Rule({ attr: this.attr, tag: this.tag, value: value[0], selector: value[1] || this.selector })); } };