| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 | 
							- 'use strict';
 
- var csstree = require('css-tree'),
 
-   List = csstree.List,
 
-   stable = require('stable'),
 
-   specificity = require('csso/lib/restructure/prepare/specificity');
 
- /**
 
-  * Flatten a CSS AST to a selectors list.
 
-  *
 
-  * @param {import('css-tree').CssNode} cssAst css-tree AST to flatten
 
-  * @return {Array} selectors
 
-  */
 
- function flattenToSelectors(cssAst) {
 
-   var selectors = [];
 
-   csstree.walk(cssAst, {
 
-     visit: 'Rule',
 
-     enter: function (node) {
 
-       if (node.type !== 'Rule') {
 
-         return;
 
-       }
 
-       var atrule = this.atrule;
 
-       var rule = node;
 
-       node.prelude.children.each(function (selectorNode, selectorItem) {
 
-         var selector = {
 
-           item: selectorItem,
 
-           atrule: atrule,
 
-           rule: rule,
 
-           pseudos: /** @type {{item: any; list: any[]}[]} */ ([]),
 
-         };
 
-         selectorNode.children.each(function (
 
-           selectorChildNode,
 
-           selectorChildItem,
 
-           selectorChildList
 
-         ) {
 
-           if (
 
-             selectorChildNode.type === 'PseudoClassSelector' ||
 
-             selectorChildNode.type === 'PseudoElementSelector'
 
-           ) {
 
-             selector.pseudos.push({
 
-               item: selectorChildItem,
 
-               list: selectorChildList,
 
-             });
 
-           }
 
-         });
 
-         selectors.push(selector);
 
-       });
 
-     },
 
-   });
 
-   return selectors;
 
- }
 
- /**
 
-  * Filter selectors by Media Query.
 
-  *
 
-  * @param {Array} selectors to filter
 
-  * @param {Array} useMqs Array with strings of media queries that should pass (<name> <expression>)
 
-  * @return {Array} Filtered selectors that match the passed media queries
 
-  */
 
- function filterByMqs(selectors, useMqs) {
 
-   return selectors.filter(function (selector) {
 
-     if (selector.atrule === null) {
 
-       return ~useMqs.indexOf('');
 
-     }
 
-     var mqName = selector.atrule.name;
 
-     var mqStr = mqName;
 
-     if (
 
-       selector.atrule.expression &&
 
-       selector.atrule.expression.children.first().type === 'MediaQueryList'
 
-     ) {
 
-       var mqExpr = csstree.generate(selector.atrule.expression);
 
-       mqStr = [mqName, mqExpr].join(' ');
 
-     }
 
-     return ~useMqs.indexOf(mqStr);
 
-   });
 
- }
 
- /**
 
-  * 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(function (selector) {
 
-     var pseudoSelectorsStr = csstree.generate({
 
-       type: 'Selector',
 
-       children: new List().fromArray(
 
-         selector.pseudos.map(function (pseudo) {
 
-           return pseudo.item.data;
 
-         })
 
-       ),
 
-     });
 
-     return ~usePseudos.indexOf(pseudoSelectorsStr);
 
-   });
 
- }
 
- /**
 
-  * Remove pseudo-elements and/or -classes from the selectors for proper matching.
 
-  *
 
-  * @param {Array} selectors to clean
 
-  * @return {void}
 
-  */
 
- function cleanPseudos(selectors) {
 
-   selectors.forEach(function (selector) {
 
-     selector.pseudos.forEach(function (pseudo) {
 
-       pseudo.list.remove(pseudo.item);
 
-     });
 
-   });
 
- }
 
- /**
 
-  * Compares two selector specificities.
 
-  * extracted from https://github.com/keeganstreet/specificity/blob/master/specificity.js#L211
 
-  *
 
-  * @param {Array} aSpecificity Specificity of selector A
 
-  * @param {Array} bSpecificity Specificity of selector B
 
-  * @return {number} Score of selector specificity A compared to selector specificity B
 
-  */
 
- function compareSpecificity(aSpecificity, bSpecificity) {
 
-   for (var i = 0; i < 4; i += 1) {
 
-     if (aSpecificity[i] < bSpecificity[i]) {
 
-       return -1;
 
-     } else if (aSpecificity[i] > bSpecificity[i]) {
 
-       return 1;
 
-     }
 
-   }
 
-   return 0;
 
- }
 
- /**
 
-  * Compare two simple selectors.
 
-  *
 
-  * @param {Object} aSimpleSelectorNode Simple selector A
 
-  * @param {Object} bSimpleSelectorNode Simple selector B
 
-  * @return {number} Score of selector A compared to selector B
 
-  */
 
- function compareSimpleSelectorNode(aSimpleSelectorNode, bSimpleSelectorNode) {
 
-   var aSpecificity = specificity(aSimpleSelectorNode),
 
-     bSpecificity = specificity(bSimpleSelectorNode);
 
-   return compareSpecificity(aSpecificity, bSpecificity);
 
- }
 
- function _bySelectorSpecificity(selectorA, selectorB) {
 
-   return compareSimpleSelectorNode(selectorA.item.data, selectorB.item.data);
 
- }
 
- /**
 
-  * Sort selectors stably by their specificity.
 
-  *
 
-  * @param {Array} selectors to be sorted
 
-  * @return {Array} Stable sorted selectors
 
-  */
 
- function sortSelectors(selectors) {
 
-   return stable(selectors, _bySelectorSpecificity);
 
- }
 
- /**
 
-  * Convert a css-tree AST style declaration to CSSStyleDeclaration property.
 
-  *
 
-  * @param {import('css-tree').CssNode} declaration css-tree style declaration
 
-  * @return {Object} CSSStyleDeclaration property
 
-  */
 
- function csstreeToStyleDeclaration(declaration) {
 
-   var propertyName = declaration.property,
 
-     propertyValue = csstree.generate(declaration.value),
 
-     propertyPriority = declaration.important ? 'important' : '';
 
-   return {
 
-     name: propertyName,
 
-     value: propertyValue,
 
-     priority: propertyPriority,
 
-   };
 
- }
 
- /**
 
-  * Gets the CSS string of a style element
 
-  *
 
-  * @param {Object} elem style element
 
-  * @return {string} CSS string or empty array if no styles are set
 
-  */
 
- function getCssStr(elem) {
 
-   if (
 
-     elem.children.length > 0 &&
 
-     (elem.children[0].type === 'text' || elem.children[0].type === 'cdata')
 
-   ) {
 
-     return elem.children[0].value;
 
-   }
 
-   return '';
 
- }
 
- /**
 
-  * Sets the CSS string of a style element
 
-  *
 
-  * @param {Object} elem style element
 
-  * @param {string} css string to be set
 
-  * @return {string} reference to field with CSS
 
-  */
 
- function setCssStr(elem, css) {
 
-   if (elem.children.length === 0) {
 
-     elem.children.push({
 
-       type: 'text',
 
-       value: '',
 
-     });
 
-   }
 
-   if (elem.children[0].type !== 'text' && elem.children[0].type !== 'cdata') {
 
-     return css;
 
-   }
 
-   elem.children[0].value = css;
 
-   return css;
 
- }
 
- module.exports.flattenToSelectors = flattenToSelectors;
 
- module.exports.filterByMqs = filterByMqs;
 
- module.exports.filterByPseudos = filterByPseudos;
 
- module.exports.cleanPseudos = cleanPseudos;
 
- module.exports.compareSpecificity = compareSpecificity;
 
- module.exports.compareSimpleSelectorNode = compareSimpleSelectorNode;
 
- module.exports.sortSelectors = sortSelectors;
 
- module.exports.csstreeToStyleDeclaration = csstreeToStyleDeclaration;
 
- module.exports.getCssStr = getCssStr;
 
- module.exports.setCssStr = setCssStr;
 
 
  |