// NOTICE: This file is generated by Rollup. To modify it, // please instead edit the ESM counterpart and rebuild with Rollup (npm run build). 'use strict'; /** @typedef {Record | undefined}>} AtRuleDefinitions */ /** @typedef {Record} PropertyDefinitions */ /** @typedef {Record} TypeDefinitions */ /** @typedef {Array} CSSWideKeywords */ /** @typedef {{atrules?: AtRuleDefinitions | undefined, properties?: PropertyDefinitions | undefined, types?: TypeDefinitions | undefined, cssWideKeywords?: CSSWideKeywords | undefined}} SyntaxDefinition */ /** * Merge multiple separate syntax definitions. * Individual definitions will override each other unless the second definition starts with a pipe symbol `|`. * * @param {...(SyntaxDefinition|undefined)} sources * @returns {SyntaxDefinition} */ function mergeSyntaxDefinitions(...sources) { /** @type {SyntaxDefinition|undefined} */ let target = sources[0] ?? {}; for (let i = 1; i < sources.length; i++) { const source = sources[i]; if (!source) continue; target = mergeTwoSyntaxDefinitions(target, source); } return target; } /** * Merge two separate syntax definitions. * Individual definitions will override each other unless the second definition starts with a pipe symbol `|`. * * @param {SyntaxDefinition} source1 * @param {SyntaxDefinition} source2 * @returns {SyntaxDefinition} */ function mergeTwoSyntaxDefinitions(source1, source2) { /** @type {SyntaxDefinition} */ const target = {}; target.atrules = mergeAtRuleDefinitions(source1.atrules, source2.atrules); target.properties = mergePropertyOrTypeDefinitions(source1.properties, source2.properties); target.types = mergePropertyOrTypeDefinitions(source1.types, source2.types); target.cssWideKeywords = mergeKeywords(source1.cssWideKeywords, source2.cssWideKeywords); return target; } /** * @param {AtRuleDefinitions | undefined} source1 * @param {AtRuleDefinitions | undefined} source2 * @returns {AtRuleDefinitions | undefined} */ function mergeAtRuleDefinitions(source1, source2) { if (typeof source1 === 'undefined' || typeof source2 === 'undefined') return source1 ?? source2 ?? {}; /** @type {AtRuleDefinitions} */ const target = structuredClone(source1); for (const [atRuleName, atRule] of Object.entries(source2)) { const targetAtRule = target[atRuleName] ?? {}; targetAtRule.prelude = mergePrelude(targetAtRule.prelude, atRule.prelude); targetAtRule.descriptors = mergePropertyOrTypeDefinitions( targetAtRule.descriptors, atRule.descriptors, ); target[atRuleName] = targetAtRule; } return target; } /** * @param {Record | undefined} source1 * @param {Record | undefined} source2 * @returns {Record | undefined} */ function mergePropertyOrTypeDefinitions(source1, source2) { if (typeof source1 === 'undefined' || typeof source2 === 'undefined') return source1 ?? source2 ?? {}; /** @type {Record} */ const target = { ...source1, }; for (const [name, syntax] of Object.entries(source2)) { target[name] = mergeSyntax(target[name], syntax); } return target; } /** * @param {Array | undefined} source1 * @param {Array | undefined} source2 * @returns {Array | undefined} */ function mergeKeywords(source1, source2) { if (typeof source1 === 'undefined' || typeof source2 === 'undefined') return source1 ?? source2 ?? []; return Array.from(new Set([...source1, ...source2])); } /** * @param {string | undefined} source1 * @param {string} source2 * @returns {string} */ function mergeSyntax(source1, source2) { if (typeof source1 === 'undefined') return source2; const trimmedSource2 = source2.trimStart(); if (!trimmedSource2.startsWith('|')) return source2; return `${source1} ${trimmedSource2}`; } /** * @param {string | undefined} source1 * @param {string | undefined} source2 * @returns {string | undefined} */ function mergePrelude(source1, source2) { if (typeof source1 === 'undefined' || typeof source2 === 'undefined') return source1 ?? source2; const trimmedSource2 = source2.trimStart(); if (!trimmedSource2.startsWith('|')) return source2; return `${source1} ${trimmedSource2}`; } module.exports = mergeSyntaxDefinitions;