[6a3a178] | 1 | "use strict";
|
---|
| 2 |
|
---|
| 3 | Object.defineProperty(exports, "__esModule", {
|
---|
| 4 | value: true
|
---|
| 5 | });
|
---|
| 6 | exports.default = void 0;
|
---|
| 7 |
|
---|
| 8 | var _alphanumSort = _interopRequireDefault(require("alphanum-sort"));
|
---|
| 9 |
|
---|
| 10 | var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
|
---|
| 11 |
|
---|
| 12 | var _canUnquote = _interopRequireDefault(require("./lib/canUnquote.js"));
|
---|
| 13 |
|
---|
| 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
---|
| 15 |
|
---|
| 16 | const pseudoElements = ['::before', '::after', '::first-letter', '::first-line'];
|
---|
| 17 |
|
---|
| 18 | function attribute(selector) {
|
---|
| 19 | if (selector.value) {
|
---|
| 20 | if (selector.raws.value) {
|
---|
| 21 | // Join selectors that are split over new lines
|
---|
| 22 | selector.raws.value = selector.raws.value.replace(/\\\n/g, '').trim();
|
---|
| 23 | }
|
---|
| 24 |
|
---|
| 25 | if ((0, _canUnquote.default)(selector.value)) {
|
---|
| 26 | selector.quoteMark = null;
|
---|
| 27 | }
|
---|
| 28 |
|
---|
| 29 | if (selector.operator) {
|
---|
| 30 | selector.operator = selector.operator.trim();
|
---|
| 31 | }
|
---|
| 32 | }
|
---|
| 33 |
|
---|
| 34 | selector.rawSpaceBefore = '';
|
---|
| 35 | selector.rawSpaceAfter = '';
|
---|
| 36 | selector.spaces.attribute = {
|
---|
| 37 | before: '',
|
---|
| 38 | after: ''
|
---|
| 39 | };
|
---|
| 40 | selector.spaces.operator = {
|
---|
| 41 | before: '',
|
---|
| 42 | after: ''
|
---|
| 43 | };
|
---|
| 44 | selector.spaces.value = {
|
---|
| 45 | before: '',
|
---|
| 46 | after: selector.insensitive ? ' ' : ''
|
---|
| 47 | };
|
---|
| 48 | selector.raws.spaces.attribute = {
|
---|
| 49 | before: '',
|
---|
| 50 | after: ''
|
---|
| 51 | };
|
---|
| 52 | selector.raws.spaces.operator = {
|
---|
| 53 | before: '',
|
---|
| 54 | after: ''
|
---|
| 55 | };
|
---|
| 56 | selector.raws.spaces.value = {
|
---|
| 57 | before: '',
|
---|
| 58 | after: selector.insensitive ? ' ' : ''
|
---|
| 59 | };
|
---|
| 60 |
|
---|
| 61 | if (selector.insensitive) {
|
---|
| 62 | selector.raws.spaces.insensitive = {
|
---|
| 63 | before: '',
|
---|
| 64 | after: ''
|
---|
| 65 | };
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | selector.attribute = selector.attribute.trim();
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | function combinator(selector) {
|
---|
| 72 | const value = selector.value.trim();
|
---|
| 73 | selector.spaces.before = '';
|
---|
| 74 | selector.spaces.after = '';
|
---|
| 75 | selector.rawSpaceBefore = '';
|
---|
| 76 | selector.rawsSpaceAfter = '';
|
---|
| 77 | selector.value = value.length ? value : ' ';
|
---|
| 78 | }
|
---|
| 79 |
|
---|
| 80 | const pseudoReplacements = {
|
---|
| 81 | ':nth-child': ':first-child',
|
---|
| 82 | ':nth-of-type': ':first-of-type',
|
---|
| 83 | ':nth-last-child': ':last-child',
|
---|
| 84 | ':nth-last-of-type': ':last-of-type'
|
---|
| 85 | };
|
---|
| 86 |
|
---|
| 87 | function pseudo(selector) {
|
---|
| 88 | const value = selector.value.toLowerCase();
|
---|
| 89 |
|
---|
| 90 | if (selector.nodes.length === 1 && pseudoReplacements[value]) {
|
---|
| 91 | const first = selector.at(0);
|
---|
| 92 | const one = first.at(0);
|
---|
| 93 |
|
---|
| 94 | if (first.length === 1) {
|
---|
| 95 | if (one.value === '1') {
|
---|
| 96 | selector.replaceWith(_postcssSelectorParser.default.pseudo({
|
---|
| 97 | value: pseudoReplacements[value]
|
---|
| 98 | }));
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | if (one.value.toLowerCase() === 'even') {
|
---|
| 102 | one.value = '2n';
|
---|
| 103 | }
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | if (first.length === 3) {
|
---|
| 107 | const two = first.at(1);
|
---|
| 108 | const three = first.at(2);
|
---|
| 109 |
|
---|
| 110 | if (one.value.toLowerCase() === '2n' && two.value === '+' && three.value === '1') {
|
---|
| 111 | one.value = 'odd';
|
---|
| 112 | two.remove();
|
---|
| 113 | three.remove();
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | return;
|
---|
| 118 | }
|
---|
| 119 |
|
---|
| 120 | const uniques = [];
|
---|
| 121 | selector.walk(child => {
|
---|
| 122 | if (child.type === 'selector') {
|
---|
| 123 | const childStr = String(child);
|
---|
| 124 |
|
---|
| 125 | if (!~uniques.indexOf(childStr)) {
|
---|
| 126 | uniques.push(childStr);
|
---|
| 127 | } else {
|
---|
| 128 | child.remove();
|
---|
| 129 | }
|
---|
| 130 | }
|
---|
| 131 | });
|
---|
| 132 |
|
---|
| 133 | if (~pseudoElements.indexOf(value)) {
|
---|
| 134 | selector.value = selector.value.slice(1);
|
---|
| 135 | }
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | const tagReplacements = {
|
---|
| 139 | from: '0%',
|
---|
| 140 | '100%': 'to'
|
---|
| 141 | };
|
---|
| 142 |
|
---|
| 143 | function tag(selector) {
|
---|
| 144 | const value = selector.value.toLowerCase();
|
---|
| 145 |
|
---|
| 146 | if (Object.prototype.hasOwnProperty.call(tagReplacements, value)) {
|
---|
| 147 | selector.value = tagReplacements[value];
|
---|
| 148 | }
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 | function universal(selector) {
|
---|
| 152 | const next = selector.next();
|
---|
| 153 |
|
---|
| 154 | if (next && next.type !== 'combinator') {
|
---|
| 155 | selector.remove();
|
---|
| 156 | }
|
---|
| 157 | }
|
---|
| 158 |
|
---|
| 159 | const reducers = {
|
---|
| 160 | attribute,
|
---|
| 161 | combinator,
|
---|
| 162 | pseudo,
|
---|
| 163 | tag,
|
---|
| 164 | universal
|
---|
| 165 | };
|
---|
| 166 |
|
---|
| 167 | function pluginCreator() {
|
---|
| 168 | return {
|
---|
| 169 | postcssPlugin: 'postcss-minify-selectors',
|
---|
| 170 |
|
---|
| 171 | OnceExit(css) {
|
---|
| 172 | const cache = {};
|
---|
| 173 | const processor = (0, _postcssSelectorParser.default)(selectors => {
|
---|
| 174 | selectors.nodes = (0, _alphanumSort.default)(selectors.nodes, {
|
---|
| 175 | insensitive: true
|
---|
| 176 | });
|
---|
| 177 | const uniqueSelectors = [];
|
---|
| 178 | selectors.walk(sel => {
|
---|
| 179 | const {
|
---|
| 180 | type
|
---|
| 181 | } = sel; // Trim whitespace around the value
|
---|
| 182 |
|
---|
| 183 | sel.spaces.before = sel.spaces.after = '';
|
---|
| 184 |
|
---|
| 185 | if (Object.prototype.hasOwnProperty.call(reducers, type)) {
|
---|
| 186 | reducers[type](sel);
|
---|
| 187 | return;
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 | const toString = String(sel);
|
---|
| 191 |
|
---|
| 192 | if (type === 'selector' && sel.parent.type !== 'pseudo') {
|
---|
| 193 | if (!~uniqueSelectors.indexOf(toString)) {
|
---|
| 194 | uniqueSelectors.push(toString);
|
---|
| 195 | } else {
|
---|
| 196 | sel.remove();
|
---|
| 197 | }
|
---|
| 198 | }
|
---|
| 199 | });
|
---|
| 200 | });
|
---|
| 201 | css.walkRules(rule => {
|
---|
| 202 | const selector = rule.raws.selector && rule.raws.selector.value === rule.selector ? rule.raws.selector.raw : rule.selector; // If the selector ends with a ':' it is likely a part of a custom mixin,
|
---|
| 203 | // so just pass through.
|
---|
| 204 |
|
---|
| 205 | if (selector[selector.length - 1] === ':') {
|
---|
| 206 | return;
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 | if (cache[selector]) {
|
---|
| 210 | rule.selector = cache[selector];
|
---|
| 211 | return;
|
---|
| 212 | }
|
---|
| 213 |
|
---|
| 214 | const optimizedSelector = processor.processSync(selector);
|
---|
| 215 | rule.selector = optimizedSelector;
|
---|
| 216 | cache[selector] = optimizedSelector;
|
---|
| 217 | });
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | };
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 | pluginCreator.postcss = true;
|
---|
| 224 | var _default = pluginCreator;
|
---|
| 225 | exports.default = _default;
|
---|
| 226 | module.exports = exports.default; |
---|