UNPKG

@zohodesk/client_build_tool

Version:

A CLI tool to build web applications and client libraries

139 lines (115 loc) 5.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.separateRtlAndLtr = separateRtlAndLtr; exports.separateSingleDir = separateSingleDir; var postcss = _interopRequireWildcard(require("postcss")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* eslint-disable no-param-reassign */ const oppositeDir = { ltr: 'rtl', rtl: 'ltr' }; function compareSelector(selector1, selector2) { // console.log({ selector1, selector2 }, selector1 === selector2); return selector1 === selector2; } const directionRegexs = { ltr: /\[dir=ltr\]/, rtl: /\[dir=rtl\]/ }; const getRegex = dir => directionRegexs[dir]; const getOppositeRegex = dir => getRegex(oppositeDir[dir]); function selectorMinifySameDir(selector, direction) { // NOTE: if this rule is same dir as current need // then we can just remove that [dir=ltr] or [dir=rtl] // it just for minimaze selector const regex = getRegex(direction); return selector.replace(regex, '').trim(); } /** * this funtion will remove given rule, * if given selector and it's previous sibiling rule selector are same * current rule properties will move to previous sibiling rule. * @param {Rule} rule current rule */ function mergeIfSameSelector(rule) { // NOTE: to merge dublicate selector rules const prev = rule.prev(); if (prev && compareSelector(prev.selector, rule.selector)) { rule.each(decl => { prev.append(decl); }); rule.remove(); } } /** * this funtion will remove given rule, * if given selector and it's previous sibiling rule selector are same * current rule properties will move to previous sibiling rule. * @param {Rule} rule current rule */ function removeIfOppsiteDirRule(rule, direction, rootOptions) { // console.log({ rule, type: rule.type }); const selectors = rule.selector.split(/\s*,\s*/); // NOTE: if we use opposite dir selector as custom override reason, // and compain normal selector with it, In this case // we just a have to remove that selector only not full rule const oppositeDirRegex = getOppositeRegex(direction); let remainingSelectors = selectors.filter(selector => !oppositeDirRegex.test(selector)); if (!rootOptions.disableMinifySelector) { remainingSelectors = remainingSelectors.map(selector => selectorMinifySameDir(selector, direction)); } if (remainingSelectors.length) { rule.selector = remainingSelectors.join(', '); } else { // NOTE: every selector is opposite dir then we have to remove the rule rule.remove(); } } function removeIfOppsiteDirKeyframe(rule, direction) { const name = rule.params; const keyFrameDirName = name.slice(name.lastIndexOf('-') + 1); if (keyFrameDirName === oppositeDir[direction]) { // console.log({ m: 'removed', keyFrameName: rule.params }); rule.remove(); } } function separateSingleDir(root, direction, rootOptions) { root.walkRules(rule => { removeIfOppsiteDirRule(rule, direction, rootOptions); mergeIfSameSelector(rule); }); root.walkAtRules(rule => { removeIfOppsiteDirKeyframe(rule, direction); }); return root; } function separateRtlAndLtr(css, rootOptions) { // let processor = postcss([]).process(css); const root = postcss.parse(css); // let { root } = processor; // console.log(processor, root); // NOTE: I did first rtl then ltr , Because for ltr I use original root ref const rtlRoot = separateSingleDir(root.clone(), 'rtl', rootOptions); // console.log('############################'); const ltrRoot = separateSingleDir(root, 'ltr', rootOptions); return { ltrRoot, rtlRoot, ltr: ltrRoot.toString(), rtl: rtlRoot.toString() }; } // NOTE: to test in https://astexplorer.net/ // you can test with sample input https://astexplorer.net/#/gist/a892a509eb585099355ef53ef094f836/1ca70d5f7af3b88ca4910296e12f118e9712c874 // export default postcss.plugin('postcss-rtl-remove', (options = {}) => // // Work with options here // root => { // const rtlRoot = separateSingleDir(root.clone(), 'rtl'); // const ltrRoot = separateSingleDir(root, 'ltr'); // // root.append(postcss.comment({ text: 'comment' })); // root.append(postcss.comment({ text: 'this is spliting part ' })); // root.append(rtlRoot); // //console.log({root, roots:root+""}, root+"") // // Transform CSS AST here // } // );