All files postcss-selector-extract.ts

26.32% Statements 5/19
16.67% Branches 2/12
25% Functions 2/8
22.22% Lines 4/18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49  1x 1x 1x 2x                                                                                        
import * as postcss from 'postcss';
 
import filterSelector = require('./filter-selector');
 
import { ISelectorFilter } from '../interfaces/ISelectorFilter';
 
/**
 * Provide a PostCSS plugin for extracting and replacing CSS selectors.
 */
export = function postcssSelectorExtract(filters: ISelectorFilter[]|string[] = [], preserveLines = false) {
  return postcss.plugin(`postcss-extract-selectors`, () => (nodes) => {
    // We have to force `any` type, because postcss type
    // definitions seem to be outdated.
    nodes.walkRules((rule: any) => {
      const ruleSelectors = rule.selector
        .split(`,`)
        .map((ruleSelector: any) => ruleSelector.replace(/(\r\n|\n|\r)/gm, ``).trim())
        .map((ruleSelector: any) => filterSelector({
          ruleSelector,
          ruleParentSelectors: rule.parent.selector ? rule.parent.selector.split(`,`) : [],
          filters,
        }))
        .filter((ruleSelector: any) => ruleSelector.length);

      if (ruleSelectors.length) {
        rule.selector = ruleSelectors.join(`,`);
      } else {
        if (preserveLines) {
          const ruleLines = rule.toString().split(/\r\n|\r|\n/).length;

          rule.cloneBefore({
            type: `comment`,
            text: `START preserve lines${'\n'.repeat(ruleLines - 1)}preserve lines END`,
            raws: Object.assign(rule.raws, { left: ' ', right: ' ' }),
          });
        }
        rule.remove();
      }
    });
 
    // Remove empty @ rules.
    nodes.walkAtRules((rule) => {
      if (rule.nodes && !rule.nodes.length) {
        rule.remove();
      }
    });
  });
};