|
|
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _postcss = require("postcss");
var _alphanumSort = require("alphanum-sort");
var _alphanumSort2 = _interopRequireDefault(_alphanumSort);
var _has = require("has");
var _has2 = _interopRequireDefault(_has);
var _postcssSelectorParser = require("postcss-selector-parser");
var _postcssSelectorParser2 = _interopRequireDefault(_postcssSelectorParser);
var _unquote = require("./lib/unquote");
var _unquote2 = _interopRequireDefault(_unquote);
var _canUnquote = require("./lib/canUnquote");
var _canUnquote2 = _interopRequireDefault(_canUnquote);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pseudoElements = ["::before", "::after", "::first-letter", "::first-line"];
function getParsed(selectors, callback) { return (0, _postcssSelectorParser2.default)(callback).processSync(selectors); }
function attribute(selector) { if (selector.value) { // Join selectors that are split over new lines
selector.value = selector.value.replace(/\\\n/g, "").trim();
if ((0, _canUnquote2.default)(selector.value)) { selector.value = (0, _unquote2.default)(selector.value); }
selector.operator = selector.operator.trim(); }
if (!selector.raws) { selector.raws = {}; }
if (!selector.raws.spaces) { selector.raws.spaces = {}; }
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.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(_postcssSelectorParser2.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 ((0, _has2.default)(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 };
exports.default = (0, _postcss.plugin)("postcss-minify-selectors", () => { return css => { const cache = {};
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[selector]) { rule.selector = cache[selector];
return; }
const optimizedSelector = getParsed(selector, selectors => { selectors.nodes = (0, _alphanumSort2.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 ((0, _has2.default)(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(); } } }); });
rule.selector = optimizedSelector; cache[selector] = optimizedSelector; }); }; }); module.exports = exports["default"];
|