UNPKG

postcss-merge-longhand

Version:

Merge longhand properties into shorthand with PostCSS.

96 lines (82 loc) 2.82 kB
import data from '../data/longhands.json' with { type: 'json' }; /** * The shorthand structure and keyword sets the transforms rely on, derived from * the specifications by `script/acquire.mjs`. The generated file is JSON, so * shorthands and initialValues deserialize as plain objects; wrap entries in * Map() to enable safe .get() lookup of property names from the stylesheet. */ const shorthands = new Map(Object.entries(data.shorthands)); const initialValues = new Map(Object.entries(data.initialValues)); /** * @param {string} name * @return {{longhands: string[], resets: string[]}} */ function shorthand(name) { const definition = shorthands.get(name); if (!definition) { throw new Error(`${name} is not a shorthand the generated data covers`); } return definition; } /** @type {Map<string, Set<string>>} */ const setsCache = new Map(); /** * All properties set when applying a shorthand: recursively follows each * shorthand through its named longhands and implicit resets. A property that * the generated data does not list as a shorthand sets only itself. * * Longhands often collide despite dissimilar names: `border-top` and * `border-color` both set `border-top-color` without any name overlap; * `border` and `border-image-source` collide despite sharing no segments. * Such collisions cannot be detected from property names alone. * * @param {string} name lower-cased * @return {Set<string>} */ function setsLonghands(name) { const cached = setsCache.get(name); if (cached) { return cached; } const definition = shorthands.get(name); if (!definition) { const own = new Set([name]); setsCache.set(name, own); return own; } /** @type {Set<string>} */ const reached = new Set(); for (const longhand of [...definition.longhands, ...definition.resets]) { for (const property of setsLonghands(longhand)) { reached.add(property); } } setsCache.set(name, reached); return reached; } export const sides = data.sides; export const borderComponents = data.borderComponents; const borderProperties = new Set(data.borderProperties); const flowRelativeBorderProperties = new Set(data.flowRelativeBorderProperties); export const cssWideKeywords = new Set(data.cssWideKeywords); export const lineStyles = new Set(data.lineStyles); export const lineWidthKeywords = new Set(data.lineWidthKeywords); export const namedColors = new Set(data.namedColors); export const colorFunctions = new Set(data.colorFunctions); export { setsLonghands }; export { shorthand }; export { initialValues }; export default { sides, setsLonghands, borderComponents, shorthand, initialValues, borderProperties, flowRelativeBorderProperties, cssWideKeywords, lineStyles, lineWidthKeywords, namedColors, colorFunctions, };