CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cssom

CSS Object Model implementation and CSS parser for programmatic CSS manipulation and analysis

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

css-values.mddocs/

CSS Values

Advanced CSS value handling including base value abstraction and support for IE-specific CSS expression() values with full JavaScript parsing.

Capabilities

CSSValue Base Class

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"!'
}

CSSValueExpression Class

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);
}

Expression Parsing Features

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);
  }
});

Error Handling

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`);
});

Integration with Parser

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 value

Advanced Parsing Scenarios

Complex 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);

Browser Compatibility Notes

Important considerations for CSS expression usage:

  • IE-Specific: CSS expressions are a legacy Internet Explorer feature
  • Security: Expressions execute JavaScript and should be used with caution
  • Performance: Expressions are re-evaluated frequently and can impact performance
  • Modern Alternative: Use CSS calc() or JavaScript for dynamic values in modern browsers
// 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

Install with Tessl CLI

npx tessl i tessl/npm-cssom

docs

css-rules.md

css-values.md

index.md

lists-collections.md

parsing.md

style-declarations.md

stylesheet-management.md

tile.json