| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.default = void 0; |
| |
| var _alphanumSort = _interopRequireDefault(require("alphanum-sort")); |
| |
| var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser")); |
| |
| var _canUnquote = _interopRequireDefault(require("./lib/canUnquote.js")); |
| |
| function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
| |
| const pseudoElements = ['::before', '::after', '::first-letter', '::first-line']; |
| |
| function attribute(selector) { |
| if (selector.value) { |
| if (selector.raws.value) { |
| // Join selectors that are split over new lines |
| selector.raws.value = selector.raws.value.replace(/\\\n/g, '').trim(); |
| } |
| |
| if ((0, _canUnquote.default)(selector.value)) { |
| selector.quoteMark = null; |
| } |
| |
| if (selector.operator) { |
| selector.operator = selector.operator.trim(); |
| } |
| } |
| |
| selector.rawSpaceBefore = ''; |
| selector.rawSpaceAfter = ''; |
| selector.spaces.attribute = { |
| before: '', |
| after: '' |
| }; |
| selector.spaces.operator = { |
| before: '', |
| after: '' |
| }; |
| selector.spaces.value = { |
| before: '', |
| after: selector.insensitive ? ' ' : '' |
| }; |
| selector.raws.spaces.attribute = { |
| before: '', |
| after: '' |
| }; |
| selector.raws.spaces.operator = { |
| before: '', |
| after: '' |
| }; |
| selector.raws.spaces.value = { |
| before: '', |
| after: selector.insensitive ? ' ' : '' |
| }; |
| |
| if (selector.insensitive) { |
| selector.raws.spaces.insensitive = { |
| before: '', |
| after: '' |
| }; |
| } |
| |
| selector.attribute = selector.attribute.trim(); |
| } |
| |
| function combinator(selector) { |
| const value = selector.value.trim(); |
| selector.spaces.before = ''; |
| selector.spaces.after = ''; |
| selector.rawSpaceBefore = ''; |
| selector.rawsSpaceAfter = ''; |
| selector.value = value.length ? value : ' '; |
| } |
| |
| const pseudoReplacements = { |
| ':nth-child': ':first-child', |
| ':nth-of-type': ':first-of-type', |
| ':nth-last-child': ':last-child', |
| ':nth-last-of-type': ':last-of-type' |
| }; |
| |
| function pseudo(selector) { |
| const value = selector.value.toLowerCase(); |
| |
| if (selector.nodes.length === 1 && pseudoReplacements[value]) { |
| const first = selector.at(0); |
| const one = first.at(0); |
| |
| if (first.length === 1) { |
| if (one.value === '1') { |
| selector.replaceWith(_postcssSelectorParser.default.pseudo({ |
| value: pseudoReplacements[value] |
| })); |
| } |
| |
| if (one.value.toLowerCase() === 'even') { |
| one.value = '2n'; |
| } |
| } |
| |
| if (first.length === 3) { |
| const two = first.at(1); |
| const three = first.at(2); |
| |
| if (one.value.toLowerCase() === '2n' && two.value === '+' && three.value === '1') { |
| one.value = 'odd'; |
| two.remove(); |
| three.remove(); |
| } |
| } |
| |
| return; |
| } |
| |
| const uniques = []; |
| selector.walk(child => { |
| if (child.type === 'selector') { |
| const childStr = String(child); |
| |
| if (!~uniques.indexOf(childStr)) { |
| uniques.push(childStr); |
| } else { |
| child.remove(); |
| } |
| } |
| }); |
| |
| if (~pseudoElements.indexOf(value)) { |
| selector.value = selector.value.slice(1); |
| } |
| } |
| |
| const tagReplacements = { |
| from: '0%', |
| '100%': 'to' |
| }; |
| |
| function tag(selector) { |
| const value = selector.value.toLowerCase(); |
| |
| if (Object.prototype.hasOwnProperty.call(tagReplacements, value)) { |
| selector.value = tagReplacements[value]; |
| } |
| } |
| |
| function universal(selector) { |
| const next = selector.next(); |
| |
| if (next && next.type !== 'combinator') { |
| selector.remove(); |
| } |
| } |
| |
| const reducers = { |
| attribute, |
| combinator, |
| pseudo, |
| tag, |
| universal |
| }; |
| |
| function pluginCreator() { |
| return { |
| postcssPlugin: 'postcss-minify-selectors', |
| |
| OnceExit(css) { |
| const cache = new Map(); |
| const processor = (0, _postcssSelectorParser.default)(selectors => { |
| selectors.nodes = (0, _alphanumSort.default)(selectors.nodes, { |
| insensitive: true |
| }); |
| const uniqueSelectors = []; |
| selectors.walk(sel => { |
| const { |
| type |
| } = sel; // Trim whitespace around the value |
| |
| sel.spaces.before = sel.spaces.after = ''; |
| |
| if (Object.prototype.hasOwnProperty.call(reducers, type)) { |
| reducers[type](sel); |
| return; |
| } |
| |
| const toString = String(sel); |
| |
| if (type === 'selector' && sel.parent.type !== 'pseudo') { |
| if (!~uniqueSelectors.indexOf(toString)) { |
| uniqueSelectors.push(toString); |
| } else { |
| sel.remove(); |
| } |
| } |
| }); |
| }); |
| css.walkRules(rule => { |
| 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, |
| // so just pass through. |
| |
| if (selector[selector.length - 1] === ':') { |
| return; |
| } |
| |
| if (cache.has(selector)) { |
| rule.selector = cache.get(selector); |
| return; |
| } |
| |
| const optimizedSelector = processor.processSync(selector); |
| rule.selector = optimizedSelector; |
| cache.set(selector, optimizedSelector); |
| }); |
| } |
| |
| }; |
| } |
| |
| pluginCreator.postcss = true; |
| var _default = pluginCreator; |
| exports.default = _default; |
| module.exports = exports.default; |