@wix/css-property-parser
Version:
A comprehensive TypeScript library for parsing and serializing CSS property values with full MDN specification compliance
159 lines (158 loc) • 5.16 kB
JavaScript
"use strict";
// Shared individual border property parser
// Handles parsing of individual border shorthand properties (border-top, border-right, border-bottom, border-left)
// https://developer.mozilla.org/en-US/docs/Web/CSS/border-top
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseBorderIndividualProperty = parseBorderIndividualProperty;
exports.borderIndividualToCSSValue = borderIndividualToCSSValue;
const length_1 = require('./length.cjs');
const color_1 = require('./color.cjs');
const css_variable_1 = require('./css-variable.cjs');
const shared_utils_1 = require('../utils/shared-utils.cjs');
const types_1 = require('../types.cjs');
/**
* Parse border width value (length or keyword)
*/
function parseBorderWidth(value) {
if ((0, shared_utils_1.isGlobalKeyword)(value)) {
return { type: 'keyword', keyword: value.toLowerCase() };
}
if (types_1.BORDER_WIDTH_KEYWORDS.includes(value.toLowerCase())) {
return { type: 'keyword', keyword: value.toLowerCase() };
}
return (0, length_1.parse)(value);
}
/**
* Parse border style value
*/
function parseBorderStyle(value) {
if ((0, shared_utils_1.isGlobalKeyword)(value)) {
return { type: 'keyword', keyword: value.toLowerCase() };
}
if (types_1.BORDER_STYLE_KEYWORDS.includes(value.toLowerCase())) {
return { type: 'keyword', keyword: value.toLowerCase() };
}
return null;
}
/**
* Parse border color value
*/
function parseBorderColor(value) {
if ((0, shared_utils_1.isGlobalKeyword)(value)) {
return { type: 'keyword', keyword: value.toLowerCase() };
}
if (value.toLowerCase() === 'currentcolor') {
return { type: 'keyword', keyword: 'currentcolor' };
}
const colorResult = (0, color_1.parse)(value);
// Filter out CSS variables since they should be handled at the top level
if (colorResult && colorResult.type !== 'variable') {
return colorResult;
}
return null;
}
/**
* Parse individual border shorthand property value
*/
function parseBorderIndividualProperty(value) {
if (!value || typeof value !== 'string')
return null;
const trimmed = value.trim();
if (trimmed === '')
return null;
// Handle CSS variables
if ((0, shared_utils_1.isCssVariable)(trimmed)) {
return (0, css_variable_1.parse)(trimmed);
}
// Handle global keywords
if ((0, shared_utils_1.isGlobalKeyword)(trimmed)) {
return { type: 'keyword', keyword: trimmed.toLowerCase() };
}
// Tokenize the value to handle multiple parts
const tokens = (0, shared_utils_1.tokenize)(trimmed);
let width = null;
let style = null;
let color = null;
// Parse each token and assign to appropriate property
for (const token of tokens) {
// Try width first
if (!width) {
const widthResult = parseBorderWidth(token);
if (widthResult) {
width = widthResult;
continue;
}
}
// Try style
if (!style) {
const styleResult = parseBorderStyle(token);
if (styleResult) {
style = styleResult;
continue;
}
}
// Try color
if (!color) {
const colorResult = parseBorderColor(token);
if (colorResult) {
color = colorResult;
continue;
}
}
// If we get here, we have an unrecognized token
return null;
}
// Must have at least one valid component
if (!width && !style && !color) {
return null;
}
return {
type: 'border-individual',
width: width || undefined,
style: style || undefined,
color: color || undefined
};
}
/**
* Convert individual border value to CSS string
*/
function borderIndividualToCSSValue(parsed) {
if (!parsed)
return null;
if (parsed.type === 'keyword') {
return parsed.keyword;
}
if (parsed.type === 'variable') {
return (0, css_variable_1.toCSSValue)(parsed);
}
if (parsed.type === 'border-individual') {
const parts = [];
if (parsed.width) {
if (parsed.width.type === 'length') {
const widthValue = (0, length_1.toCSSValue)(parsed.width);
if (widthValue)
parts.push(widthValue);
}
else if (parsed.width.type === 'keyword') {
parts.push(parsed.width.keyword);
}
}
if (parsed.style) {
if (parsed.style.type === 'keyword') {
parts.push(parsed.style.keyword);
}
}
if (parsed.color) {
if (parsed.color.type === 'keyword') {
parts.push(parsed.color.keyword);
}
else {
const colorValue = (0, color_1.toCSSValue)(parsed.color);
if (colorValue)
parts.push(colorValue);
}
}
return parts.length > 0 ? parts.join(' ') : null;
}
return null;
}