UNPKG

babel-plugin-styled-components-px2vw

Version:
85 lines (79 loc) 3.04 kB
import postcss from 'postcss'; import memoize from 'memoizerific'; import px2vw from 'postcss-px-to-viewport'; //TODO: upgrade to 8 version wait postcss-px-to-viewport support import { IPx2VwOptions } from '../types/options'; import configuration from './configuration'; const FAKE_OPENING_WRAPPER = `styled-fake-wrapper/* start of styled-fake-wrapper */{ `; const FAKE_CLOSING_WRAPPER = ` }/* end of styled-fake-wrapper */`; const FAKE_RULE = '/* start of styled-fake-rule */padding:/* end of styled-fake-rule */'; const PAIR_REG = /[\s\w-]+:([\s\w.-])+/; // const PAIR_REG = /[\s\w-]+:([\s-\d]+px)+/; const PX_UNIT_REG = new RegExp(`([\\s-\\d]+${configuration.config.unitToConvert})+`); //; const SPLIT_SEPARATORS = [';', '\n', '{', '}']; const errorTokenMap = new Map(); // a map data prevent infinite loop function process(css: string): string { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { tags, ...others } = configuration.config; const options: IPx2VwOptions = { ...others, }; return postcss([px2vw(options)]).process(css, { // syntax: scss, }).css; } function replaceWithRecord(cssText: string): string { const { unitToConvert } = configuration.config; try { if (PAIR_REG.test(cssText)) { const replaced = process(`${FAKE_OPENING_WRAPPER}${cssText}${FAKE_CLOSING_WRAPPER}`); /* istanbul ignore next */ if (errorTokenMap.has(cssText)) { errorTokenMap.delete(cssText); } return replaced.replace(FAKE_OPENING_WRAPPER, '').replace(FAKE_CLOSING_WRAPPER, ''); } else if (PX_UNIT_REG.test(cssText)) { const replaced = process(`${FAKE_RULE}${cssText}`); /* istanbul ignore next */ if (errorTokenMap.has(cssText)) { errorTokenMap.delete(cssText); } return replaced.replace(FAKE_RULE, ''); } else { /* istanbul ignore next */ if (errorTokenMap.has(cssText)) { errorTokenMap.delete(cssText); } return cssText; } } catch (ignored) { let tempResults: string[] = []; let cssStr = cssText; SPLIT_SEPARATORS.forEach((separator) => { const tokens = cssStr.split(separator); for (const token of tokens) { const tokenRemoveComments = token.replace(/\s*(?<!(\/\*.*|[::]))\/\/.*$/gm, ''); // remove single-line comments // TODO:consider into propList option if ( PAIR_REG.test(tokenRemoveComments) && tokenRemoveComments.includes(unitToConvert) && !errorTokenMap.get(tokenRemoveComments) && !!token.trim() ) { errorTokenMap.set(tokenRemoveComments, true); tempResults.push(replace(tokenRemoveComments)); } else { tempResults.push(token); } } cssStr = tempResults.join(separator); tempResults = []; }); return cssStr; } } export const replace = memoize(10)(function (cssText: string): string { // eslint-disable-next-line @typescript-eslint/no-unused-vars return replaceWithRecord(cssText); });