All files / src/lib postcss-node-extract.ts

100% Statements 21/21
100% Branches 7/7
100% Functions 5/5
100% Lines 20/20
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 482x 2x   2x 2x   2x                 2x         15x 15x   15x 13x 867x 867x 939x 939x 939x   867x 681x 27x   27x             681x          
import { camelCase } from 'change-case';
import * as postcss from 'postcss';
 
import extractNodeRecursively = require('./extract-node-recursively');
import filterDefinitions = require('./filter-definitions');
 
import { PRESERVE_LINES_END, PRESERVE_LINES_START } from '../const';
 
import { ICustomFilter } from '../interfaces/ICustomFilter';
import { IFilter } from '../interfaces/IFilter';
import { IFilterGroup } from '../interfaces/IFilterGroup';
 
/**
 * A PostCSS plugin for extracting nodes from CSS code.
 */
export = function postcssNodeExtract(
  filterNames: string|string[],
  customFilters?: ICustomFilter,
  preserveLines = false,
) {
  const filterNamesArray = Array.isArray(filterNames) ? filterNames : [filterNames];
  Object.assign(filterDefinitions, customFilters);
 
  return postcss.plugin(`postcss-node-extract`, () => (nodes) => {
    nodes.walk((rule) => {
      let filterRule = false;
      filterNamesArray.some((filterName) => {
        const filterNameCamelCase = camelCase(filterName);
        filterRule = extractNodeRecursively(rule, filterDefinitions[filterNameCamelCase]);
        return filterRule;
      });
      if (!filterRule) {
        if (preserveLines) {
          const ruleLines = rule.toString().split(/\r\n|\r|\n/).length;
 
          rule.cloneBefore({
            type: `comment`,
            text: `${PRESERVE_LINES_START}${'\n'.repeat(ruleLines - 1)}${PRESERVE_LINES_END}`,
            raws: Object.assign(rule.raws, { left: ' ', right: ' ' }),
          });
        }
 
        rule.remove();
      }
    });
  });
};