|
|
- "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"];
|