123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- 'use strict';
- exports.__esModule = 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 }; }
- var pseudoElements = ['::before', '::after', '::first-letter', '::first-line'];
- function getParsed(selectors, callback) {
- return (0, _postcssSelectorParser2.default)(callback).process(selectors).result;
- }
- 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.insensitive) {
- selector.raws.insensitive = '';
- }
- selector.attribute = selector.attribute.trim();
- }
- function combinator(selector) {
- var value = selector.value.trim();
- selector.value = value.length ? value : ' ';
- }
- var 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) {
- if (selector.nodes.length === 1 && pseudoReplacements[selector.value]) {
- var first = selector.at(0);
- var one = first.at(0);
- if (first.length === 1) {
- if (one.value === '1') {
- selector.replaceWith(_postcssSelectorParser2.default.pseudo({
- value: pseudoReplacements[selector.value]
- }));
- }
- if (one.value === 'even') {
- one.value = '2n';
- }
- }
- if (first.length === 3) {
- var two = first.at(1);
- var three = first.at(2);
- if (one.value === '2n' && two.value === '+' && three.value === '1') {
- one.value = 'odd';
- two.remove();
- three.remove();
- }
- }
- return;
- }
- var uniques = [];
- selector.walk(function (child) {
- if (child.type === 'selector') {
- var childStr = String(child);
- if (!~uniques.indexOf(childStr)) {
- uniques.push(childStr);
- } else {
- child.remove();
- }
- }
- });
- if (~pseudoElements.indexOf(selector.value)) {
- selector.value = selector.value.slice(1);
- }
- }
- var tagReplacements = {
- from: '0%',
- '100%': 'to'
- };
- function tag(selector) {
- var value = selector.value;
- if ((0, _has2.default)(tagReplacements, value)) {
- selector.value = tagReplacements[value];
- }
- }
- function universal(selector) {
- var next = selector.next();
- if (next && next.type !== 'combinator') {
- selector.remove();
- }
- }
- var reducers = {
- attribute: attribute,
- combinator: combinator,
- pseudo: pseudo,
- tag: tag,
- universal: universal
- };
- function optimise(rule) {
- var 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;
- }
- rule.selector = getParsed(selector, function (selectors) {
- selectors.nodes = (0, _alphanumSort2.default)(selectors.nodes, { insensitive: true });
- var uniqueSelectors = [];
- selectors.walk(function (sel) {
- var type = sel.type;
- // Trim whitespace around the value
- sel.spaces.before = sel.spaces.after = '';
- if ((0, _has2.default)(reducers, type)) {
- reducers[type](sel);
- return;
- }
- var toString = String(sel);
- if (type === 'selector' && sel.parent.type !== 'pseudo') {
- if (!~uniqueSelectors.indexOf(toString)) {
- uniqueSelectors.push(toString);
- } else {
- sel.remove();
- }
- }
- });
- });
- }
- exports.default = (0, _postcss.plugin)('postcss-minify-selectors', function () {
- return function (css) {
- return css.walkRules(optimise);
- };
- });
- module.exports = exports['default'];
|