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