UNPKG

1.6 kBJavaScriptView Raw
1'use strict';
2const selectorParser = require('postcss-selector-parser');
3
4/**
5 * @param {string} selectors
6 * @param {selectorParser.SyncProcessor<void>} callback
7 * @return {string}
8 */
9function parseSelectors(selectors, callback) {
10 return selectorParser(callback).processSync(selectors);
11}
12
13/**
14 * @param {import('postcss').Rule} rule
15 * @return {string}
16 */
17function unique(rule) {
18 const selector = [...new Set(rule.selectors)];
19 selector.sort();
20 return selector.join();
21}
22
23/**
24 * @type {import('postcss').PluginCreator<void>}
25 * @return {import('postcss').Plugin}
26 */
27function pluginCreator() {
28 return {
29 postcssPlugin: 'postcss-unique-selectors',
30 OnceExit(css) {
31 css.walkRules((nodes) => {
32 /** @type {string[]} */
33 let comments = [];
34 /** @type {selectorParser.SyncProcessor<void>} */
35 const removeAndSaveComments = (selNode) => {
36 selNode.walk((sel) => {
37 if (sel.type === 'comment') {
38 comments.push(sel.value);
39 sel.remove();
40 return;
41 } else {
42 return;
43 }
44 });
45 };
46 if (nodes.raws.selector && nodes.raws.selector.raw) {
47 parseSelectors(nodes.raws.selector.raw, removeAndSaveComments);
48 nodes.raws.selector.raw = unique(nodes);
49 }
50 nodes.selector = parseSelectors(nodes.selector, removeAndSaveComments);
51 nodes.selector = unique(nodes);
52 nodes.selectors = nodes.selectors.concat(comments);
53 });
54 },
55 };
56}
57
58pluginCreator.postcss = true;
59module.exports = pluginCreator;