@zohodesk/client_build_tool
Version:
A CLI tool to build web applications and client libraries
139 lines (115 loc) • 5.43 kB
JavaScript
;
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
// }
// );