UNPKG

@wix/css-property-parser

Version:

A comprehensive TypeScript library for parsing and serializing CSS property values with full MDN specification compliance

135 lines (134 loc) 5.09 kB
// Line-height property parser // Handles parsing of CSS line-height property according to MDN specification // https://developer.mozilla.org/en-US/docs/Web/CSS/line-height import { parse as parseNumber } from './number.js'; import { parse as parseLength } from './length.js'; import { parse as parsePercentage } from './percentage.js'; import { parse as parseCSSVariable, toCSSValue as cssVariableToCSSValue } from './css-variable.js'; import { isCssVariable, isGlobalKeyword } from '../utils/shared-utils.js'; /** * Check if a value is a valid line-height keyword */ function isLineHeightKeyword(value) { const keyword = value.toLowerCase(); return keyword === 'normal'; } /** * Parses a CSS line-height property string into structured components * Follows MDN specification: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height */ export function parse(value) { if (!value || typeof value !== 'string') { return null; } const trimmed = value.trim(); if (trimmed === '') { return null; } // CSS variables can be parsed directly if (isCssVariable(trimmed)) { return parseCSSVariable(trimmed); } // Handle global keywords (inherit, initial, unset, revert, revert-layer) if (isGlobalKeyword(trimmed)) { return { type: 'keyword', keyword: trimmed.toLowerCase() }; } // Handle line-height keywords (normal) if (isLineHeightKeyword(trimmed)) { return { type: 'keyword', keyword: trimmed.toLowerCase() }; } // Try to parse as number first (unitless multiplier) - includes calc() expressions const numberResult = parseNumber(trimmed); if (numberResult) { // Handle CSS variables from number parser if ('CSSvariable' in numberResult) { return numberResult; } // Check for non-negative values if ('value' in numberResult && numberResult.value < 0) { return null; } // Return as LineHeightNumber or function expression if ('value' in numberResult) { return { type: 'number', value: numberResult.value }; } // Handle calc expressions (NumberCalcExpression) if ('expression' in numberResult) { return { expression: numberResult.expression, function: numberResult.function }; } } // Try to parse as percentage - includes calc() expressions const percentageResult = parsePercentage(trimmed); if (percentageResult) { // Handle CSS variables from percentage parser if ('CSSvariable' in percentageResult) { return percentageResult; } // Check for non-negative values if ('value' in percentageResult && percentageResult.value < 0) { return null; } // Return as LineHeightPercentage or function expression if ('value' in percentageResult) { return { type: 'percentage', value: percentageResult.value, unit: '%' }; } // Handle calc expressions (PercentageCalcExpression) if ('expression' in percentageResult) { return { expression: percentageResult.expression, function: percentageResult.function }; } } // Try to parse as length - includes calc() expressions const lengthResult = parseLength(trimmed); if (lengthResult) { // Handle CSS variables from length parser if ('CSSvariable' in lengthResult) { return lengthResult; } // Check for non-negative values if ('value' in lengthResult && lengthResult.value < 0) { return null; } // Return as LineHeightLength or function expression if ('value' in lengthResult) { return { type: 'length', value: lengthResult.value, unit: lengthResult.unit }; } // Handle calc expressions (LengthCalcExpression) if ('expression' in lengthResult) { return { expression: lengthResult.expression, function: lengthResult.function }; } } return null; } /** * Converts a parsed line-height back to a CSS value string */ export function toCSSValue(parsed) { if (!parsed) { return null; } // Handle CSS variables if ('CSSvariable' in parsed) { return cssVariableToCSSValue(parsed); } // Handle keyword values if ('keyword' in parsed) { return parsed.keyword; } // Handle function expressions if ('expression' in parsed && 'function' in parsed) { return `${parsed.function}(${parsed.expression})`; } // Handle numeric values (LineHeightNumber) if ('value' in parsed && !('unit' in parsed)) { return parsed.value.toString(); } // Handle length values (LineHeightLength) if ('value' in parsed && 'unit' in parsed && parsed.unit !== '%') { return `${parsed.value}${parsed.unit}`; } // Handle percentage values (LineHeightPercentage) if ('value' in parsed && 'unit' in parsed && parsed.unit === '%') { return `${parsed.value}%`; } return null; }