{"version":3,"sources":["../../../src/engine/AreHTML.tokenizer.ts"],"names":[],"mappings":"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","file":"AreHTML.tokenizer.mjs","sourcesContent":["import { A_Caller, A_Feature, A_Inject } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreNodeFeatures, AreNode, AreTokenizer, AreAttribute_Init, AreContext } from \"@adaas/are\";\nimport { AreComponentNode } from \"@adaas/are-html/nodes/AreComponent\";\nimport { AreRootNode } from \"@adaas/are-html/nodes/AreRoot\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreEventAttribute } from \"@adaas/are-html/attributes/AreEvent.attribute\";\nimport { AreBindingAttribute } from \"@adaas/are-html/attributes/AreBinding.attribute\";\nimport { AreStaticAttribute } from \"@adaas/are-html/attributes/AreStatic.attribute\";\nimport { AreHTMLAttribute } from \"../lib/AreHTMLAttribute/AreHTML.attribute\";\nimport { AreHTMLNode } from \"../lib/AreHTMLNode/AreHTMLNode\";\nimport { isStaticMarkup } from \"./AreHTML.constants\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n@A_Frame.Define({\n    namespace: 'a-are-html',\n    description: 'HTML-specific tokenizer extending AreTokenizer. Parses raw HTML template strings into AreHTMLNode trees by scanning element tags and resolving directive ($), event (@), binding (:), and static attributes to their typed attribute classes, constructing AreComponentNode and AreRootNode instances where required.'\n})\nexport class AreHTMLTokenizer extends AreTokenizer {\n\n    ATTR_PATTERN = /([$:@]?[\\w.-]+(?::[\\w.-]+)?)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>/\"'=]+)))?/g\n\n\n    @A_Feature.Extend({\n        name: AreNodeFeatures.onTokenize,\n        scope: [AreComponentNode, AreRootNode]\n    })\n    tokenize(\n        @A_Inject(A_Caller) node: AreNode,\n        @A_Inject(AreContext) context: AreContext,\n        @A_Inject(A_Logger) logger?: A_Logger\n    ): void {\n\n        /**\n         * Static-island fast path.\n         *\n         * When a node's entire inner subtree is fully static — no `{{ }}`\n         * interpolations, no dynamic (`$`/`:`/`@`) attributes and only standard\n         * HTML tags — we skip exploding it into one child AreNode per element /\n         * text run and instead capture the inner markup verbatim. The interpreter\n         * later materialises it in a single pass (browser-parsed innerHTML /\n         * cached `<template>` clone), which:\n         *   - eliminates N node + scope + scene + instruction allocations,\n         *   - collapses N isolated DOM mutations into one, and\n         *   - decodes HTML entities (e.g. `&nbsp;`) for free.\n         *\n         * Routing outlets (AreRootNode) are intentionally excluded — they own\n         * their content dynamically. The node's OWN attributes are still\n         * extracted below, so a dynamic attribute on the island root itself\n         * (e.g. `<div :class=\"x\"> …static… </div>`) keeps working.\n         */\n        const isStaticIsland =\n            node instanceof AreComponentNode &&\n            !!node.content &&\n            isStaticMarkup(node.content);\n\n        if (isStaticIsland) {\n            (node as AreHTMLNode).markStatic(node.content);\n        } else {\n            super.tokenize(node, context, logger);\n        }\n\n        context.startPerformance('attributeExtraction');\n\n        const attributes = this.extractAttributes(node.markup);\n\n        for (const attr of attributes) {\n            node.scope.register(attr);\n        }\n\n        context.endPerformance('attributeExtraction');\n    }\n\n\n\n    extractAttributes(markup: string): AreHTMLAttribute[] {\n        // Strip the tag name, then remove the closing > that is NOT inside quotes\n        const withoutTag = markup.replace(/^<[a-zA-Z][a-zA-Z0-9-]*\\s*/, '')\n\n        // Walk the string to find the closing > that isn't inside a quoted value\n        let inSingle = false\n        let inDouble = false\n        let endIdx = withoutTag.length\n\n        for (let i = 0; i < withoutTag.length; i++) {\n            const ch = withoutTag[i]\n            if (ch === '\"' && !inSingle) inDouble = !inDouble\n            else if (ch === \"'\" && !inDouble) inSingle = !inSingle\n            else if (ch === '>' && !inSingle && !inDouble) {\n                endIdx = i\n                break\n            }\n        }\n\n        const attrString = withoutTag.slice(0, endIdx).replace(/\\s*\\/?\\s*$/, '').trim()\n\n        const results: AreHTMLAttribute[] = []\n\n        for (const match of attrString.matchAll(this.ATTR_PATTERN)) {\n            const raw = match[0]\n            const full = match[1]                           // e.g. ':class', '@click', '$for', 'id'\n\n            // skip zero-length or name-less regex matches\n            if (!full) continue\n\n            const value = match[2] ?? match[3] ?? match[4] ?? 'true'\n\n            const prefix = full[0]\n            const isSpecial = prefix === ':' || prefix === '@' || prefix === '$'\n            const name = isSpecial ? full.slice(1) : full\n\n            const meta: AreAttribute_Init = { name, content: value, raw, prefix: isSpecial ? prefix : '' }\n\n            if (prefix === ':') results.push(new AreBindingAttribute(meta))\n            else if (prefix === '@') results.push(new AreEventAttribute(meta))\n            else if (prefix === '$') results.push(new AreDirectiveAttribute(meta))\n            else results.push(new AreStaticAttribute(meta))\n        }\n\n        return results\n    }\n\n}"]}