{"version":3,"sources":["../../../src/engine/AreHTML.constants.ts"],"names":[],"mappings":"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","file":"AreHTML.constants.mjs","sourcesContent":["// ─────────────────────────────────────────────────────────────────────────────\n// ── SVG ──────────────────────────────────────────────────────────────────────\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** XML namespace URI for SVG elements. */\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Maps namespace prefixes used in SVG/XML attributes to their canonical URIs.\n * Used by the interpreter when calling setAttributeNS / removeAttributeNS.\n */\nexport const SVG_ATTRIBUTE_NS: Record<string, string> = {\n    xlink: 'http://www.w3.org/1999/xlink',\n    xml: 'http://www.w3.org/XML/1998/namespace',\n    xmlns: 'http://www.w3.org/2000/xmlns/',\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ── HTML void elements ────────────────────────────────────────────────────────\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Void HTML elements that cannot have children and must not have a closing tag.\n * Per the HTML5 spec these are treated as self-closing even when written as\n * `<input>` (without the trailing slash `/>`).\n *\n * Reference: https://html.spec.whatwg.org/multipage/syntax.html#void-elements\n */\nexport const VOID_ELEMENTS = new Set<string>([\n    'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n    'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\nexport function isVoidElement(tagName: string): boolean {\n    return VOID_ELEMENTS.has(tagName.toLowerCase());\n}\n\n/**\n * Boolean HTML attributes whose presence (regardless of value) implies \"true\",\n * and whose absence implies \"false\". Setting these via `setAttribute(name, value)`\n * always renders the attribute, which is wrong for reactive bindings.\n *\n * Reference: https://html.spec.whatwg.org/multipage/indices.html#attributes-3\n */\nexport const BOOLEAN_ATTRIBUTES = new Set<string>([\n    'allowfullscreen',\n    'async',\n    'autofocus',\n    'autoplay',\n    'checked',\n    'controls',\n    'default',\n    'defer',\n    'disabled',\n    'formnovalidate',\n    'hidden',\n    'inert',\n    'ismap',\n    'itemscope',\n    'loop',\n    'multiple',\n    'muted',\n    'nomodule',\n    'novalidate',\n    'open',\n    'playsinline',\n    'readonly',\n    'required',\n    'reversed',\n    'selected',\n]);\n\nexport function isBooleanAttribute(name: string): boolean {\n    return BOOLEAN_ATTRIBUTES.has(name.toLowerCase());\n}\n\n/**\n * Form-control IDL properties that must be set as a JS property\n * (not just an attribute) so live user input is reflected.\n *\n * `<input value=\"foo\">` only sets the *default* value;\n * `input.value = \"foo\"` updates the live state.\n */\nexport const IDL_FORM_PROPERTIES: Record<string, Set<string>> = {\n    INPUT: new Set(['value', 'checked', 'indeterminate']),\n    TEXTAREA: new Set(['value']),\n    SELECT: new Set(['value']),\n    OPTION: new Set(['selected']),\n};\n\nexport function isIDLFormProperty(tagName: string, attrName: string): boolean {\n    const set = IDL_FORM_PROPERTIES[tagName.toUpperCase()];\n    return !!set && set.has(attrName);\n}\n\n/**\n * Normalize a `:class` binding value into a single space-separated string.\n * Supports the common shapes:\n *   - string                                       → \"a b\"\n *   - array<string | object | falsy>               → [\"a\", { b: true, c: cond }, null]\n *   - object<string, boolean>                      → { a: true, b: false }\n */\nexport function normalizeClassValue(value: any): string {\n    if (value === null || value === undefined || value === false) return '';\n    if (typeof value === 'string') return value;\n    if (typeof value === 'number') return String(value);\n\n    if (Array.isArray(value)) {\n        return value.map(normalizeClassValue).filter(Boolean).join(' ');\n    }\n    if (typeof value === 'object') {\n        const parts: string[] = [];\n        for (const key of Object.keys(value)) {\n            if (value[key]) parts.push(key);\n        }\n        return parts.join(' ');\n    }\n    return '';\n}\n\n/**\n * Normalize a `:style` binding value into an inline-style string.\n * Supports:\n *   - string                                       → \"color: red; font-size: 12px\"\n *   - object<string, string|number>                → { color: 'red', fontSize: '12px' }\n *   - array<string | object>                       → ['color: red', { fontSize: '12px' }]\n */\nexport function normalizeStyleValue(value: any): string {\n    if (value === null || value === undefined || value === false) return '';\n    if (typeof value === 'string') return value;\n    if (typeof value === 'number') return String(value);\n\n    if (Array.isArray(value)) {\n        return value.map(normalizeStyleValue).filter(Boolean).join('; ');\n    }\n    if (typeof value === 'object') {\n        const parts: string[] = [];\n        for (const key of Object.keys(value)) {\n            const v = value[key];\n            if (v === null || v === undefined || v === false) continue;\n            const kebab = key.replace(/[A-Z]/g, m => '-' + m.toLowerCase());\n            parts.push(`${kebab}: ${v}`);\n        }\n        return parts.join('; ');\n    }\n    return '';\n}\n\n/**\n * Parse a DOM event name with modifiers, e.g. \"click.stop.prevent\" or \"keydown.enter\".\n * Returns the bare event name plus the modifier set.\n */\nexport interface ParsedEventName {\n    event: string;\n    modifiers: Set<string>;\n}\n\nexport function parseEventName(raw: string): ParsedEventName {\n    const [event, ...modifiers] = raw.split('.');\n    return { event, modifiers: new Set(modifiers) };\n}\n\n/**\n * Known event-listener modifiers that map directly to addEventListener options.\n */\nexport const LISTENER_OPTION_MODIFIERS = new Set(['capture', 'once', 'passive']);\n\n/**\n * Coerce a value into a string for DOM consumption.\n * Avoids \"undefined\"/\"null\"/\"[object Object]\" leaks into the DOM.\n */\nexport function toDOMString(value: any): string {\n    if (value === null || value === undefined) return '';\n    if (typeof value === 'string') return value;\n    if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n    try {\n        return JSON.stringify(value);\n    } catch {\n        return '';\n    }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ── Static-island detection ──────────────────────────────────────────────────\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Standard HTML element names that are safe to materialise wholesale via\n * `innerHTML` / a cached `<template>` clone.\n *\n * The set is intentionally an allow-list of plain HTML flow/phrasing/table/list\n * /form-display tags. Anything NOT in this set — custom elements, registered\n * ARE components (resolved by PascalCase tag), and SVG/MathML elements — is\n * excluded so those subtrees keep flowing through the normal per-node pipeline\n * (SVG needs createElementNS; components need their own lifecycle).\n */\nexport const STANDARD_HTML_TAGS = new Set<string>([\n    // root / sections\n    'html', 'body', 'header', 'footer', 'main', 'nav', 'section', 'article',\n    'aside', 'address', 'hgroup',\n    // headings\n    'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n    // grouping\n    'div', 'p', 'span', 'pre', 'blockquote', 'figure', 'figcaption',\n    'hr', 'br', 'wbr',\n    // lists\n    'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'menu',\n    // text-level / phrasing\n    'a', 'b', 'i', 'u', 's', 'em', 'strong', 'small', 'mark', 'abbr', 'cite',\n    'q', 'code', 'kbd', 'samp', 'var', 'sub', 'sup', 'time', 'data', 'dfn',\n    'bdi', 'bdo', 'ruby', 'rt', 'rp', 'del', 'ins',\n    // media / embedded (no special namespace handling needed)\n    'img', 'picture', 'source', 'figure', 'audio', 'video', 'track',\n    // tables\n    'table', 'caption', 'colgroup', 'col', 'thead', 'tbody', 'tfoot',\n    'tr', 'th', 'td',\n    // forms (display only — these still render fine from innerHTML)\n    'label', 'fieldset', 'legend', 'datalist', 'option', 'optgroup', 'output',\n    'progress', 'meter',\n    // interactive\n    'details', 'summary', 'dialog',\n]);\n\n/**\n * Detects whether an inner-markup string is a fully *static island* — i.e. it\n * contains no ARE-reactive constructs and therefore can be rendered in one shot\n * (browser-parsed `innerHTML` / cached `<template>` clone) instead of being\n * exploded into one AreNode per element/text/interpolation.\n *\n * A subtree is static iff it contains:\n *   1. no `{{ }}` interpolations, and\n *   2. no dynamic attributes (`$`-directive / `:`-binding / `@`-event), and\n *   3. only standard HTML tags (no custom elements, ARE components or SVG).\n *\n * The scanner is quote-aware so a `:` / `@` / `$` inside an attribute *value*\n * (e.g. `href=\"http://…\"`, `style=\"color:red\"`) is never mistaken for a\n * dynamic-attribute prefix. The detector is deliberately conservative: any\n * ambiguity resolves to `false` (skip the optimisation, keep the safe path).\n *\n * NOTE: pure-text content (no tags at all) is also considered static — this is\n * what lets `&nbsp;`, `&amp;`, `&#160;` and friends decode correctly, since the\n * browser HTML parser handles entities that hand-built text nodes do not.\n */\nexport function isStaticMarkup(inner: string): boolean {\n    if (!inner) return false;\n    // 1. interpolations make the subtree dynamic\n    if (inner.indexOf('{{') !== -1) return false;\n\n    const n = inner.length;\n    let i = 0;\n\n    while (i < n) {\n        const lt = inner.indexOf('<', i);\n        if (lt === -1) break; // remaining content is plain text — safe\n\n        // HTML comment — inert, skip over it\n        if (inner.startsWith('<!--', lt)) {\n            const end = inner.indexOf('-->', lt + 4);\n            if (end === -1) return false; // malformed\n            i = end + 3;\n            continue;\n        }\n\n        // closing tag, doctype or processing instruction — skip to its '>'\n        if (inner[lt + 1] === '/' || inner[lt + 1] === '!' || inner[lt + 1] === '?') {\n            const gt = inner.indexOf('>', lt);\n            if (gt === -1) return false;\n            i = gt + 1;\n            continue;\n        }\n\n        // opening tag — extract the tag name\n        const nameMatch = /^<([a-zA-Z][a-zA-Z0-9-]*)/.exec(inner.slice(lt));\n        if (!nameMatch) { i = lt + 1; continue; }\n\n        const tag = nameMatch[1].toLowerCase();\n        // custom element / ARE component / non-standard (incl. SVG) → not static\n        if (tag.indexOf('-') !== -1 || !STANDARD_HTML_TAGS.has(tag)) return false;\n\n        // walk the opening tag (quote-aware) to find its closing '>' and inspect\n        // attribute-name boundaries for dynamic prefixes\n        let j = lt + nameMatch[0].length;\n        let inSingle = false;\n        let inDouble = false;\n        let atNameBoundary = true; // true right after whitespace / '/' inside a tag\n        let tagEnd = -1;\n\n        while (j < n) {\n            const ch = inner[j];\n\n            if (inDouble) {\n                if (ch === '\"') inDouble = false;\n            } else if (inSingle) {\n                if (ch === \"'\") inSingle = false;\n            } else if (ch === '\"') {\n                inDouble = true;\n                atNameBoundary = false;\n            } else if (ch === \"'\") {\n                inSingle = true;\n                atNameBoundary = false;\n            } else if (ch === '>') {\n                tagEnd = j;\n                break;\n            } else if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r' || ch === '/') {\n                atNameBoundary = true;\n            } else {\n                // a dynamic-attribute prefix only counts when it STARTS an\n                // attribute name (i.e. sits at a name boundary, outside quotes)\n                if (atNameBoundary && (ch === '$' || ch === ':' || ch === '@')) {\n                    return false;\n                }\n                atNameBoundary = false;\n            }\n            j++;\n        }\n\n        if (tagEnd === -1) return false; // unterminated tag — bail to safe path\n        i = tagEnd + 1;\n    }\n\n    return true;\n}\n\n\n"]}