CasperSecurity
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = resolveDefaultsAtRules;
exports.elementSelectorParser = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
var _featureFlags = require("../featureFlags");
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
let getNode = {
id (node) {
return _postcssSelectorParser.default.attribute({
attribute: 'id',
operator: '=',
value: node.value,
quoteMark: '"'
});
}
};
function minimumImpactSelector(nodes) {
let rest = nodes.filter((node)=>{
// Keep non-pseudo nodes
if (node.type !== 'pseudo') return true;
// Keep pseudo nodes that have subnodes
// E.g.: `:not()` contains subnodes inside the parentheses
if (node.nodes.length > 0) return true;
// Keep pseudo `elements`
// This implicitly means that we ignore pseudo `classes`
return node.value.startsWith('::') || [
':before',
':after',
':first-line',
':first-letter'
].includes(node.value);
}).reverse();
let searchFor = new Set([
'tag',
'class',
'id',
'attribute'
]);
let splitPointIdx = rest.findIndex((n)=>searchFor.has(n.type)
);
if (splitPointIdx === -1) return rest.reverse().join('').trim();
let node1 = rest[splitPointIdx];
let bestNode = getNode[node1.type] ? getNode[node1.type](node1) : node1;
rest = rest.slice(0, splitPointIdx);
let combinatorIdx = rest.findIndex((n)=>n.type === 'combinator' && n.value === '>'
);
if (combinatorIdx !== -1) {
rest.splice(0, combinatorIdx);
rest.unshift(_postcssSelectorParser.default.universal());
}
return [
bestNode,
...rest.reverse()
].join('').trim();
}
let elementSelectorParser = (0, _postcssSelectorParser).default((selectors)=>{
return selectors.map((s)=>{
let nodes = s.split((n)=>n.type === 'combinator' && n.value === ' '
).pop();
return minimumImpactSelector(nodes);
});
});
exports.elementSelectorParser = elementSelectorParser;
let cache = new Map();
function extractElementSelector(selector) {
if (!cache.has(selector)) {
cache.set(selector, elementSelectorParser.transformSync(selector));
}
return cache.get(selector);
}
function resolveDefaultsAtRules({ tailwindConfig }) {
return (root)=>{
let variableNodeMap = new Map();
/** @type {Set<import('postcss').AtRule>} */ let universals = new Set();
root.walkAtRules('defaults', (rule)=>{
if (rule.nodes && rule.nodes.length > 0) {
universals.add(rule);
return;
}
let variable = rule.params;
if (!variableNodeMap.has(variable)) {
variableNodeMap.set(variable, new Set());
}
variableNodeMap.get(variable).add(rule.parent);
rule.remove();
});
for (let universal of universals){
/** @type {Map<string, Set<string>>} */ let selectorGroups = new Map();
var ref;
let rules = (ref = variableNodeMap.get(universal.params)) !== null && ref !== void 0 ? ref : [];
for (let rule of rules){
for (let selector of extractElementSelector(rule.selector)){
// If selector contains a vendor prefix after a pseudo element or class,
// we consider them separately because merging the declarations into
// a single rule will cause browsers that do not understand the
// vendor prefix to throw out the whole rule
let selectorGroupName = selector.includes(':-') || selector.includes('::-') ? selector : '__DEFAULT__';
var ref1;
let selectors = (ref1 = selectorGroups.get(selectorGroupName)) !== null && ref1 !== void 0 ? ref1 : new Set();
selectorGroups.set(selectorGroupName, selectors);
selectors.add(selector);
}
}
if ((0, _featureFlags).flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
if (selectorGroups.size === 0) {
universal.remove();
continue;
}
for (let [, selectors] of selectorGroups){
let universalRule = _postcss.default.rule();
universalRule.selectors = [
...selectors
];
universalRule.append(universal.nodes.map((node)=>node.clone()
));
universal.before(universalRule);
}
} else {
let universalRule = _postcss.default.rule();
universalRule.selectors = [
'*',
'::before',
'::after'
];
universalRule.append(universal.nodes);
universal.before(universalRule);
}
universal.remove();
}
};
}