Urara-Blog/node_modules/.pnpm-store/v3/files/79/2aab390d648d837b4f6b01c4b04bc161debeab6a3a090f0458952e95f4dc42bbff84c8a3e4aee9e8d1bf0ae07245aa40079a95e799f94e18c5f071edb932dc
2022-08-14 01:14:53 +08:00

72 lines
2.1 KiB
Text

'use strict';
const hasAllProps = require('./hasAllProps.js');
const getDecls = require('./getDecls.js');
const getRules = require('./getRules.js');
/**
* @param {import('postcss').Declaration} propA
* @param {import('postcss').Declaration} propB
* @return {boolean}
*/
function isConflictingProp(propA, propB) {
if (!propB.prop || propB.important !== propA.important ||
propA.prop === propB.prop) {
return false;
}
const partsA = propA.prop.split('-');
const partsB = propB.prop.split('-');
/* Be safe: check that the first part matches. So we don't try to
* combine e.g. border-color and color.
*/
if (partsA[0] !== partsB[0]) {
return false;
}
const partsASet = new Set(partsA);
return partsB.every((partB) => partsASet.has(partB));
}
/**
* @param {import('postcss').Declaration[]} match
* @param {import('postcss').Declaration[]} nodes
* @return {boolean}
*/
function hasConflicts(match, nodes) {
const firstNode = Math.min(...match.map((n) => nodes.indexOf(n)));
const lastNode = Math.max(...match.map((n) => nodes.indexOf(n)));
const between = nodes.slice(firstNode + 1, lastNode);
return match.some((a) => between.some((b) => isConflictingProp(a, b)));
}
/**
* @param {import('postcss').Rule} rule
* @param {string[]} properties
* @param {(rules: import('postcss').Declaration[], last: import('postcss').Declaration, props: import('postcss').Declaration[]) => boolean} callback
* @return {void}
*/
module.exports = function mergeRules(rule, properties, callback) {
let decls = getDecls(rule, properties);
while (decls.length) {
const last = decls[decls.length - 1];
const props = decls.filter((node) => node.important === last.important);
const rules = getRules(props, properties);
if (
hasAllProps(rules, ...properties) &&
!hasConflicts(
rules,
/** @type import('postcss').Declaration[]*/ (rule.nodes)
)
) {
if (callback(rules, last, props)) {
decls = decls.filter((node) => !rules.includes(node));
}
}
decls = decls.filter((node) => node !== last);
}
};