packages/svg-mixer-utils/lib/postcss.js (43 lines of code) (raw):

const merge = require('merge-options'); const { createUrlsHelper } = require('postcss-helpers'); const BACKGROUND_DECL_NAME_REGEXP = /^background(-image)?$/i; const URL_FUNCTION_REGEXP = /url\([^)]*\)/ig; /** * @param {string} selector * @param {Function} transformer * @returns {string} * @example * transformSelector('.qwe, .qwe2', s => `${s}::after`) * // => '.qwe::after, .qwe2::after' */ module.exports.transformSelector = (selector, transformer) => selector.split(',').map(s => transformer(s)).join(','); /** * @param {Object} object * @return {Array<{prop: string, value: string}>} * @example * postcss * .rule({ selector: '.qwe' }) * .append(...objectToDeclProps({ * color: 'red', * 'background-image': '...' * })) */ module.exports.objectToDeclProps = object => Object.keys(object).map(key => ({ prop: key, value: object[key] })); /** * @param {postcss.Rule|postcss.Root} node * @param {Object} [options] * @param {boolean} [options.createHelper=true] * @param {boolean} [options.skipInvalid=true] * @return {Array<postcss.Declaration>|Array<{decl: postcss.Declaration, helper: UrlsHelper|null}>} */ module.exports.findBgDecls = (node, options = {}) => { const opts = merge({ createHelper: true, skipInvalid: true }, options); const decls = []; node.walkDecls(decl => { if ( BACKGROUND_DECL_NAME_REGEXP.test(decl.prop) && URL_FUNCTION_REGEXP.test(decl.value) ) { decls.push(decl); } BACKGROUND_DECL_NAME_REGEXP.lastIndex = 0; URL_FUNCTION_REGEXP.lastIndex = 0; }); let result = decls; if (opts.createHelper) { result = decls.map(decl => { // URL/URLs could be invalid, in this case set helper=null const helper = createUrlsHelper(decl.value); return { decl, helper: helper || null, valid: !!helper }; }); if (opts.skipInvalid) { result = result.filter(({ valid }) => valid); } } return result; };