From 3fdf621f5673ffdb644afe3e7d62e0eb5b3f4eb1 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Sun, 20 Oct 2019 21:37:12 +0300 Subject: [PATCH] refactor: simplify style element inlining --- src/css.js | 108 ++++++++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/src/css.js b/src/css.js index aeb98602..f1291f9f 100644 --- a/src/css.js +++ b/src/css.js @@ -118,7 +118,8 @@ function specificity(selector) { case 'TypeSelector': // ignore universal selector - if (node.name.charAt(node.name.length - 1) !== '*') { + const { name } = node; + if (name.charAt(name.length - 1) !== '*') { C++; } break; @@ -171,26 +172,19 @@ function flattenToSelectors(cssAst, selectors) { * Filter selectors by Media Query. * * @param {Array} selectors to filter - * @param {Array} useMqs Array with strings of media queries that should pass ( ) * @return {Array} Filtered selectors that match the passed media queries */ -function filterByMqs(selectors, useMqs) { - return selectors.filter(selector => { - if (selector.atrule === null) { +function filterByMqs(selectors) { + return selectors.filter(({ atrule }) => { + if (atrule === null) { return ~useMqs.indexOf(''); } - - const mqName = selector.atrule.name; - let mqStr = mqName; - if ( - selector.atrule.expression && - selector.atrule.expression.children.first().type === 'MediaQueryList' - ) { - const mqExpr = csstree.generate(selector.atrule.expression); - mqStr = [mqName, mqExpr].join(' '); - } - - return ~useMqs.indexOf(mqStr); + const { name, expression } = atrule; + return ~useMqs.indexOf( + expression && expression.children.first().type === 'MediaQueryList' + ? [name, csstree.generate(expression)].join(' ') + : name, + ); }); } @@ -198,21 +192,20 @@ function filterByMqs(selectors, useMqs) { * Filter selectors by the pseudo-elements and/or -classes they contain. * * @param {Array} selectors to filter - * @param {Array} usePseudos Array with strings of single or sequence of pseudo-elements and/or -classes that should pass * @return {Array} Filtered selectors that match the passed pseudo-elements and/or -classes */ -function filterByPseudos(selectors, usePseudos) { - return selectors.filter(selector => { - const pseudoSelectorsStr = csstree.generate({ - type: 'Selector', - children: new List().fromArray( - selector.pseudos.map(pseudo => { - return pseudo.item.data; +function filterByPseudos(selectors) { + return selectors.filter( + ({ pseudos }) => + ~usePseudos.indexOf( + csstree.generate({ + type: 'Selector', + children: new List().fromArray( + pseudos.map(pseudo => pseudo.item.data), + ), }), ), - }); - return ~usePseudos.indexOf(pseudoSelectorsStr); - }); + ); } /** @@ -222,11 +215,9 @@ function filterByPseudos(selectors, usePseudos) { * @return {Array} Selectors without pseudo-elements and/or -classes */ function cleanPseudos(selectors) { - selectors.forEach(selector => { - selector.pseudos.forEach(pseudo => { - pseudo.list.remove(pseudo.item); - }); - }); + selectors.forEach(({ pseudos }) => + pseudos.forEach(pseudo => pseudo.list.remove(pseudo.item)), + ); } /** @@ -245,7 +236,6 @@ function compareSpecificity(aSpecificity, bSpecificity) { return 1; } } - return 0; } @@ -272,6 +262,10 @@ function sortSelectors(selectors) { return stable(selectors, bySelectorSpecificity); } +const declarationParseProps = { + context: 'declarationList', + parseValue: false, +}; function CSSStyleDeclaration(node) { const style = { style: node.props.style, @@ -281,13 +275,9 @@ function CSSStyleDeclaration(node) { if (!styles || styles.length === 0) { return style; } - try { csstree - .parse(styles, { - context: 'declarationList', - parseValue: false, - }) + .parse(styles, declarationParseProps) .children.each(({ property, value, important }) => { try { setProperty(style, property, csstree.generate(value), important); @@ -306,7 +296,6 @@ function CSSStyleDeclaration(node) { parseError, ); } - return style; } @@ -341,9 +330,7 @@ function setProperty({ properties, style }, name, value, important) { */ function closestElem(node, elemName) { let elem = node; - while ((elem = elem.parent) && elem.tag !== elemName) {} - return elem; } @@ -356,6 +343,17 @@ function initStyle(selectedEl) { } } +// useMqs Array with strings of media queries that should pass ( ) +const useMqs = ['', 'screen']; + +// usePseudos Array with strings of single or sequence of pseudo-elements and/or -classes that should pass +const usePseudos = ['']; + +const parseProps = { + parseValue: false, + parseCustomProperty: false, +}; + /** * Moves + merges styles from style elements to element styles * @@ -369,14 +367,10 @@ function initStyle(selectedEl) { * empty string element for all non-pseudo-classes and/or -elements * * @param {Object} document document element - * @param {Object} opts plugin params * * @author strarsis + * @author modified by: msand */ -const opts = { - useMqs: ['', 'screen'], - usePseudos: [''], -}; export function inlineStyles(document) { // collect