Advanced CSS value handling including base value abstraction and support for IE-specific CSS expression() values with full JavaScript parsing.
Abstract base class for CSS values providing common interface and error handling.
/**
* Abstract base class for CSS values
*/
class CSSValue {
constructor();
/**
* CSS text representation of the value
* Abstract implementation - throws errors by default
*/
cssText: string;
/**
* Internal helper for error messages
* @returns {string} Constructor name for error context
*/
_getConstructorName(): string;
}Important: Abstract Base Class
CSSValue is an abstract base class and should not be used directly. The cssText property is intentionally not implemented and will throw errors when accessed:
const { CSSValue } = require("cssom");
const value = new CSSValue();
try {
console.log(value.cssText);
} catch (error) {
console.log(error.message); // 'getter "cssText" of "CSSValue" is not implemented!'
}
try {
value.cssText = "some value";
} catch (error) {
console.log(error.message); // 'DOMException: property "cssText" of "CSSValue" is readonly and can not be replaced with "some value"!'
}Specialized class for handling IE-specific CSS expression() values with comprehensive JavaScript parsing capabilities.
/**
* CSS expression() value handler for IE-specific expressions
*/
class CSSValueExpression extends CSSValue {
/**
* Create a CSS expression parser
* @param {string} token - Expression token string
* @param {number} idx - Starting index in the token
*/
constructor(token, idx);
/** Expression token string */
_token: string;
/** Starting index in the token */
_idx: number;
/**
* Parse the CSS expression
* @returns {Object} Parse result with idx and expression, or error
*/
parse(): Object;
/**
* Parse JavaScript comments within expressions
* @param {string} token - Token string
* @param {number} idx - Current index
* @returns {number} Updated index after comment
*/
_parseJSComment(token, idx): number;
/**
* Parse JavaScript strings within expressions
* @param {string} token - Token string
* @param {number} idx - Current index
* @param {string} sep - String delimiter (single or double quote)
* @returns {number} Updated index after string
*/
_parseJSString(token, idx, sep): number;
/**
* Parse JavaScript regular expressions within expressions
* @param {string} token - Token string
* @param {number} idx - Current index
* @returns {number} Updated index after regex
*/
_parseJSRexExp(token, idx): number;
/**
* Find matching delimiter for paired characters
* @param {string} token - Token string
* @param {number} idx - Current index
* @param {string} sep - Delimiter to match
* @returns {number} Index of matching delimiter
*/
_findMatchedIdx(token, idx, sep): number;
}Usage Examples:
const { CSSValueExpression } = require("cssom");
// Example IE CSS expression parsing
const token = 'expression(document.body.clientWidth + "px")';
const parser = new CSSValueExpression(token, 11); // Start after 'expression('
const result = parser.parse();
if (result.error) {
console.log("Parse error:", result.error);
} else {
console.log("Parsed expression:", result.expression);
console.log("End index:", result.idx);
}The CSSValueExpression parser handles complex JavaScript constructs within CSS expressions:
const { CSSValueExpression } = require("cssom");
// Complex expression with various JavaScript features
const expressions = [
// Simple variable access
'document.body.scrollTop',
// String literals with escapes
'"Hello \\"world\\""',
// Regular expressions
'/pattern/gi',
// Comments
'/* comment */ value',
'// line comment\nvalue',
// Function calls with nested parentheses
'Math.max(window.innerWidth, document.body.clientWidth)',
// Complex nested structures
'obj.method("string", /regex/, /* comment */ 123)'
];
expressions.forEach((expr, i) => {
console.log(`\nExpression ${i + 1}: ${expr}`);
const fullToken = `expression(${expr})`;
const parser = new CSSValueExpression(fullToken, 11);
try {
const result = parser.parse();
if (result.error) {
console.log("Error:", result.error);
} else {
console.log("Success:", result.expression);
}
} catch (error) {
console.log("Exception:", error.message);
}
});Comprehensive error handling for malformed expressions:
const { CSSValueExpression } = require("cssom");
const malformedExpressions = [
'unterminated string "hello',
'unclosed comment /* comment',
'unmatched parentheses ((',
'invalid regex /[/'
];
malformedExpressions.forEach(expr => {
const token = `expression(${expr})`;
const parser = new CSSValueExpression(token, 11);
const result = parser.parse();
console.log(`Expression: ${expr}`);
console.log(`Result:`, result.error ? `Error: ${result.error}` : `Success`);
});How CSSValueExpression integrates with the main CSSOM parser:
const { parse } = require("cssom");
// CSS with IE expression (would be processed by CSSValueExpression internally)
const cssWithExpression = `
.dynamic {
width: expression(document.body.clientWidth + "px");
height: expression(Math.max(300, window.innerHeight * 0.5) + "px");
}
`;
// The parser automatically handles expressions during parsing
const sheet = parse(cssWithExpression);
const rule = sheet.cssRules[0];
// The expression is parsed and stored as the property value
console.log(rule.style.width); // Processed expression value
console.log(rule.style.height); // Processed expression valueComplex parsing scenarios handled by the expression parser:
const { CSSValueExpression } = require("cssom");
// Nested function calls with multiple argument types
const complexExpression = `
someFunction(
"string argument",
123,
/regex-pattern/gi,
/* inline comment */ anotherFunction(nested, "args"),
// line comment
finalArgument
)
`;
const token = `expression(${complexExpression})`;
const parser = new CSSValueExpression(token, 11);
const result = parser.parse();
console.log("Complex expression parsed:", !result.error);
console.log("Result:", result.error || result.expression);Important considerations for CSS expression usage:
// Modern alternatives to CSS expressions:
// Instead of: width: expression(document.body.clientWidth + "px")
// Use CSS: width: calc(100vw - 20px)
// Or JavaScript: element.style.width = document.body.clientWidth + "px"
// The CSSOM library supports parsing these legacy expressions for compatibility
// and migration purposes, but modern CSS features are recommended for new development