index.cjs.js 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  2. var browserslist = _interopDefault(require('browserslist'));
  3. var postcss = _interopDefault(require('postcss'));
  4. var index = postcss.plugin('postcss-browser-comments', opts => root => {
  5. // client browserslist
  6. const clientBrowserList = browserslist(Object(opts).browsers || null, {
  7. path: root.source && root.source.input && root.source.input.file
  8. }); // root children references
  9. const references = root.nodes.slice(0); // for each child node of the root children references
  10. for (let node of references) {
  11. // if the node is a comment browser comment node
  12. if (isBrowserCommentNode(node)) {
  13. // rule following the browser comment
  14. const rule = node.next(); // browser data
  15. const browserdata = getBrowserData(node.text);
  16. if (browserdata.isNumbered) {
  17. rule.nodes.filter(isBrowserReferenceCommentNode).map(comment => {
  18. const browserdataIndex = parseFloat(comment.text) - 1;
  19. const browserslistPart = browserdata.browserslist[browserdataIndex]; // whether to remove the rule if the comment browserslist does not match the client browserslist
  20. const removeRule = !clientBrowserList.some(clientBrowser => browserslist(browserslistPart).some(commentBrowser => commentBrowser === clientBrowser)); // conditionally remove the declaration and reference comment
  21. if (removeRule) {
  22. comment.prev().remove();
  23. comment.remove();
  24. }
  25. }); // conditionally remove the empty rule and comment
  26. if (!rule.nodes.length) {
  27. rule.remove();
  28. node.remove();
  29. }
  30. } else {
  31. // whether to remove the rule if the comment browserslist does not match the client browserslist
  32. const removeRule = !clientBrowserList.some(clientBrowser => browserslist(browserdata.browserslist).some(commentBrowser => commentBrowser === clientBrowser)); // conditionally remove the rule and comment
  33. if (removeRule) {
  34. rule.remove();
  35. node.remove();
  36. }
  37. }
  38. }
  39. }
  40. }); // returns whether a node is a browser comment
  41. const isBrowserCommentNode = node => node.type === 'comment' && isBrowserCommentNodeRegExp.test(node.text) && node.next().type === 'rule';
  42. const isBrowserCommentNodeRegExp = /^\*\n * /; // returns whether a node is a browser reference comment
  43. const isBrowserReferenceCommentNode = node => node.type === 'comment' && isBrowserReferenceCommentNodeRegExp.test(node.text);
  44. const isBrowserReferenceCommentNodeRegExp = /^\d+$/; // returns browser data from comment text
  45. const getBrowserData = text => {
  46. const browserDataNumbered = text.match(browserDataMutliRegExp);
  47. const isNumbered = Boolean(browserDataNumbered);
  48. return {
  49. browserslist: isNumbered ? browserDataNumbered.map(browserslistPart => getBrowsersList(browserslistPart.replace(browserDataNumberedNewlineRegExp, '$1'))) : getBrowsersList(text.replace(browserDataNewlineRegExp, '')),
  50. isNumbered
  51. };
  52. };
  53. const browserDataMutliRegExp = /(\n \* \d+\. (?:[^\n]+|\n \* {4,})+)/g;
  54. const browserDataNewlineRegExp = /^\*\n \* ?|\n \*/g;
  55. const browserDataNumberedNewlineRegExp = /\n \* (?:( )\s*)?/g; // returns a browserlist from comment text
  56. const getBrowsersList = text => text.split(getBrowsersListInSplitRegExp).slice(1).map(part => part.split(getBrowsersListAndSplitRegExp).filter(part2 => part2)).reduce((acc, val) => acc.concat(val), []).map(part => part.replace(getBrowsersListQueryRegExp, ($0, browser, query) => browser === 'all' ? '> 0%' : `${browser}${query ? /^((?:\d*\.)?\d+)-$/.test(query) ? ` <= ${query.slice(0, -1)}` : ` ${query}` : ' > 0'}`).toLowerCase());
  57. const getBrowsersListInSplitRegExp = /\s+in\s+/;
  58. const getBrowsersListAndSplitRegExp = /(?: and|, and|,)/;
  59. const getBrowsersListQueryRegExp = /^\s*(\w+)(?: ((?:(?:\d*\.)?\d+-)?(?:\d*\.)?\d+[+-]?))?.*$/;
  60. module.exports = index;