index.cjs 4.1 KB

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