Files
OliveTin/frontend/node_modules/stylelint/lib/utils/normalizeSelector.mjs

85 lines
1.9 KiB
JavaScript

import parser from 'postcss-selector-parser';
/** @import { Container, Node, Root, Selector } from 'postcss-selector-parser' */
/**
* Normalize a selector so that it can be more easily compared to other selectors.
*
* @template {Root | Selector} T
* @param {T} node
* @returns {T}
*/
export default function normalizeSelector(node) {
normalizeSelectorNodeWhitespaceAndComments(node);
node.walk(normalizeSelectorNodeWhitespaceAndComments);
normalizeSelectorNodesOrder(node);
return node;
}
/**
* @param {Node} node
*/
function normalizeSelectorNodeWhitespaceAndComments(node) {
if (parser.isComment(node)) {
node.remove();
return;
}
node.rawSpaceBefore = '';
node.rawSpaceAfter = '';
node.spaces.before = '';
node.spaces.after = '';
if (parser.isAttribute(node)) {
delete node.spaces.insensitive;
delete node.spaces.operator;
delete node.spaces.attribute;
delete node.spaces.value;
delete node.raws.spaces;
}
}
/**
* @param {Node} node
*/
function normalizeSelectorNodesOrder(node) {
if (!parser.isContainer(node)) return;
// Need to sort inside out, not outside in.
// As the parents needs to sorted with their children already in the right order.
node.each(normalizeSelectorNodesOrder);
if (parser.isRoot(node) || parser.isPseudoClass(node) || parser.isPseudoElement(node)) {
const nodes = node.nodes.map((childNode) => {
// Make sure to only stringify the node once.
return { node: childNode, string: childNode.toString() };
});
nodes.sort((a, b) => a.string.localeCompare(b.string));
const uniqueNodes = new Set();
const nodesIndices = new Map();
nodes.forEach((x, i) => {
if (uniqueNodes.has(x.string)) return;
uniqueNodes.add(x.string);
nodesIndices.set(x.node, i);
});
node.nodes = node.nodes
.filter((childNode) => {
return nodesIndices.has(childNode);
})
.sort((a, b) => {
return nodesIndices.get(a) - nodesIndices.get(b);
});
}
}