CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-entities

High-performance library for encoding and decoding HTML and XML entities with configurable options

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

escaping.mddocs/

Entity Escaping

Fast, targeted character escaping functions for specific HTML/XML contexts and UTF-8 optimized output. These functions provide direct escaping without the configuration overhead of the main encode function.

Capabilities

UTF-8 Optimized Escaping

Minimal escaping function optimized for UTF-8 environments where only essential XML characters need encoding.

/**
 * Encodes only XML-critical characters for UTF-8 output
 * Fastest escaping option - only escapes: " & ' < >
 * @param data - String to escape
 * @returns String with only essential XML characters escaped
 */
function escapeUTF8(data: string): string;

Usage Examples:

import { escapeUTF8 } from "entities/escape";

// Minimal escaping for UTF-8 content
escapeUTF8('Hello & "world" <tag>');
// Result: 'Hello &amp; &quot;world&quot; &lt;tag&gt;'

// Unicode characters preserved
escapeUTF8("Café & 世界 <hello>");
// Result: "Café &amp; 世界 &lt;hello&gt;"

HTML Context-Specific Escaping

WHATWG HTML specification compliant escaping functions for different HTML contexts.

/**
 * Escapes characters for HTML attribute values
 * Follows WHATWG HTML spec for attribute context
 * Escapes: " & \u00A0 (quote, ampersand, non-breaking space)
 * @param data - String to escape
 * @returns String safe for HTML attribute values
 */
function escapeAttribute(data: string): string;

/**
 * Escapes characters for HTML text content  
 * Follows WHATWG HTML spec for text context
 * Escapes: & < > \u00A0 (ampersand, less-than, greater-than, nbsp)
 * @param data - String to escape
 * @returns String safe for HTML text content
 */
function escapeText(data: string): string;

Usage Examples:

import { escapeAttribute, escapeText } from "entities/escape";

// HTML attribute escaping
escapeAttribute('Say "Hello" & goodbye');
// Result: 'Say &quot;Hello&quot; &amp; goodbye'

// HTML text escaping
escapeText("2 < 3 & 4 > 1");  
// Result: "2 &lt; 3 &amp; 4 &gt; 1"

// Non-breaking space handling
escapeText("Word\u00A0word");
// Result: "Word&nbsp;word"

XML Entity Encoding

Comprehensive XML encoding functions for full XML compatibility.

/**
 * Encodes all non-ASCII characters and XML-invalid characters using XML entities
 * If a character has no equivalent entity, uses numeric hexadecimal reference
 * @param input - String to encode
 * @returns Fully encoded XML-safe string
 */
function encodeXML(input: string): string;

/**
 * Alias for encodeXML function for backward compatibility
 * @param input - String to encode  
 * @returns Fully encoded XML-safe string
 */
function escape(input: string): string;

Usage Examples:

import { encodeXML, escape } from "entities/escape";

// Full XML encoding
encodeXML("Café & <script>alert('XSS')</script>");
// Result: "Caf&#xe9; &amp; &lt;script&gt;alert(&apos;XSS&apos;)&lt;/script&gt;"

// Using the alias
escape('<hello>world & "quotes"</hello>');
// Result: "&lt;hello&gt;world &amp; &quot;quotes&quot;&lt;/hello&gt;"

// Non-ASCII characters become numeric entities
encodeXML("世界");
// Result: "&#x4e16;&#x754c;"

Utility Constants and Functions

Character Matching Patterns

/**
 * Regular expression for matching XML characters needing replacement
 * Matches: " $ & ' < > and all characters from U+0080 to U+FFFF
 */
const xmlReplacer: RegExp;

/**
 * Gets Unicode code point at specified index (polyfill for older environments)
 * @param c - Input string
 * @param index - Character index
 * @returns Unicode code point
 */
function getCodePoint(c: string, index: number): number;

Performance Comparison

These functions are optimized for different use cases:

FunctionSpeedUse Case
escapeUTF8FastestModern UTF-8 environments
escapeAttributeFastHTML attribute values
escapeTextFastHTML text content
encodeXMLModerateFull XML compatibility

Advanced Usage Patterns

Template Building

import { escapeAttribute, escapeText } from "entities/escape";

function buildHTMLElement(tag: string, attributes: Record<string, string>, content: string) {
  const attrs = Object.entries(attributes)
    .map(([key, value]) => `${key}="${escapeAttribute(value)}"`)
    .join(' ');
    
  return `<${tag} ${attrs}>${escapeText(content)}</${tag}>`;
}

// Usage
const html = buildHTMLElement('div', 
  { 
    class: 'user-input',
    title: 'Contains "quotes" & symbols' 
  },
  'User said: <script>alert("XSS")</script>'
);
// Result: <div class="user-input" title="Contains &quot;quotes&quot; &amp; symbols">User said: &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;</div>

Stream Processing

import { escapeUTF8 } from "entities/escape";

function processTextStream(chunks: string[]): string[] {
  return chunks.map(chunk => escapeUTF8(chunk));
}

// Safe for concatenation
const safeChunks = processTextStream(['Hello & ', 'world <tag>']);
const result = safeChunks.join('');
// Result: "Hello &amp; world &lt;tag&gt;"

Context-Aware Escaping

import { escapeAttribute, escapeText, escapeUTF8 } from "entities/escape";

type HTMLContext = 'text' | 'attribute' | 'xml';

function contextualEscape(input: string, context: HTMLContext): string {
  switch (context) {
    case 'text':
      return escapeText(input);
    case 'attribute':
      return escapeAttribute(input);  
    case 'xml':
      return escapeUTF8(input);
    default:
      throw new Error(`Unknown context: ${context}`);
  }
}

Batch Escaping

import { escapeText } from "entities/escape";

function escapeUserInputs(inputs: string[]): string[] {
  return inputs.map(input => escapeText(input));
}

// Safe processing of multiple user inputs
const userComments = [
  "Great post! <3",
  "Check out this link: http://example.com?a=1&b=2", 
  "Quote: \"Be yourself\" - Someone"
];

const safeComments = escapeUserInputs(userComments);
// All comments are now HTML-safe

Security Considerations

XSS Prevention

import { escapeText, escapeAttribute } from "entities/escape";

// GOOD: Escape user input before HTML insertion
function safeHTMLInsertion(userInput: string) {
  return `<div>${escapeText(userInput)}</div>`;
}

// GOOD: Escape attribute values
function safeAttributeInsertion(userValue: string) {
  return `<input value="${escapeAttribute(userValue)}">`;
}

// BAD: Never insert unescaped user input
function unsafeInsertion(userInput: string) {
  return `<div>${userInput}</div>`; // VULNERABLE TO XSS
}

Context Matching

Always match the escaping function to the HTML context:

// Correct context usage
`<div title="${escapeAttribute(userTitle)}">${escapeText(userContent)}</div>`

// Incorrect - using wrong context
`<div title="${escapeText(userTitle)}">${escapeAttribute(userContent)}</div>`

Integration with Main API

These escaping functions are also available through the main encode function:

import { encode, EncodingMode } from "entities";
import { escapeUTF8, escapeAttribute, escapeText } from "entities/escape";

// These are equivalent:
escapeUTF8(input) === encode(input, { mode: EncodingMode.UTF8 })
escapeAttribute(input) === encode(input, { mode: EncodingMode.Attribute })  
escapeText(input) === encode(input, { mode: EncodingMode.Text })

Use the direct escaping functions when you need maximum performance and know the exact context. Use the main encode function when you need flexibility and configuration options.

Install with Tessl CLI

npx tessl i tessl/npm-entities

docs

advanced-decoding.md

decoding.md

encoding.md

escaping.md

index.md

tile.json