UNPKG

postcss-logical-properties-polyfill

Version:

PostCSS plugin that polyfill W3C's CSS proposal to support logical properties and values

86 lines (85 loc) 3.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const transformers_1 = require("./transformers"); const defaultBuildSelector = (selector, writingMode, direction) => { let prefix = `html[dir="${direction}"]`; if (writingMode !== 'horizontal-tb') { prefix += ` .writing-mode-${writingMode}`; } return `${prefix} ${selector}`; }; function normalizeOptions(options) { // @ts-ignore return options.map((mode) => { if (Array.isArray(mode)) { return mode; } return ['horizontal-tb', mode]; }); } function generatePolyfills(decls, writingMode, direction) { const newDecls = []; decls.forEach((decl) => { const newDecl = transformers_1.transformToNonLogical(decl, writingMode, direction); if (!newDecl) { return; } if (Array.isArray(newDecl)) { newDecls.push(...newDecl); } else { newDecls.push(newDecl); } }); return newDecls; } const plugin = ({ buildSelector = defaultBuildSelector, modes = [ ['horizontal-tb', 'rtl'], ['horizontal-tb', 'ltr'], ], preserve = true, } = {}) => ({ // Force type since by an unknown reason it doesn't inherited from the function's generic postcssPlugin: 'postcss-logical-properties-polyfill', Root(root) { modes = normalizeOptions(modes); const rulesToProcess = new Map(); root.walkDecls((decl) => { if (!transformers_1.isSupportedProp(decl.prop)) { return; } const parent = decl.parent; if (!parent || parent.type !== 'rule') { return; } // Skip LESS namespaces and mixins, since they must have different behavior if (parent.selector.match(/\((\s*|\s*[@].*)\)/)) { return; } if (rulesToProcess.has(parent)) { rulesToProcess.get(parent).push(decl); } else { rulesToProcess.set(parent, [decl]); } }); for (const [rule, decls] of rulesToProcess) { for (const [writingMode, direction] of modes) { const declsForDirection = generatePolyfills(decls, writingMode, direction); if (declsForDirection.length === 0) { continue; } const newRule = rule.clone().removeAll(); newRule.selectors = rule.selectors.map((selector) => buildSelector(selector, writingMode, direction)); newRule.append(declsForDirection); if (!newRule.raws.before.startsWith('\n\n')) { newRule.raws.before = '\n\n' + newRule.raws.before; } rule.after(newRule); } if (!preserve) { decls.forEach((decl) => decl.remove()); } } }, }); plugin.postcss = true; exports.default = plugin;