{"version":3,"sources":["../../../src/engine/AreHTML.engine.ts"],"names":["content","match"],"mappings":"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","file":"AreHTML.engine.mjs","sourcesContent":["import { A_Feature, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\"\nimport { A_ServiceFeatures } from \"@adaas/a-utils/a-service\";\nimport { AreEngine, AreSyntaxTokenMatch, AreSyntax, AreSignalsContext } from \"@adaas/are\";\nimport { AreHTMLInterpreter } from \"@adaas/are-html/interpreter\";\nimport { AreHTMLEngineContext } from \"./AreHTML.context\";\nimport { AreInterpolation } from \"@adaas/are-html/nodes/AreInterpolation\";\nimport { AreText } from \"@adaas/are-html/nodes/AreText\";\nimport { AreComment } from \"@adaas/are-html/nodes/AreComment\";\nimport { AreComponentNode } from \"@adaas/are-html/nodes/AreComponent\";\nimport { AreHTMLTokenizer } from \"@adaas/are-html/tokenizer\";\nimport { AreRootNode } from \"@adaas/are-html/nodes/AreRoot\";\nimport { AreHTMLLifecycle } from \"@adaas/are-html/lifecycle\";\nimport { AreHTMLTransformer } from \"@adaas/are-html/transformer\";\nimport { AreHTMLCompiler } from \"./AreHTML.compiler\";\nimport { isVoidElement } from \"./AreHTML.constants\";\nimport { AreRootCache } from \"../lib/AreRoot/AreRootCache.context\";\n\n\n\n@A_Frame.Define({\n    namespace: 'a-are-html',\n    description: 'Concrete HTML rendering engine that assembles the full ARE pipeline for web environments. Bootstraps and wires AreHTMLTokenizer, AreHTMLTransformer, AreHTMLCompiler, AreHTMLInterpreter, and AreHTMLLifecycle; mounts root nodes from inline or fetched templates; and drives reactive re-renders via the AreSignals bus.'\n})\nexport class AreHTMLEngine extends AreEngine {\n\n\n\n    get DefaultSyntax() {\n        return new AreSyntax({\n            trimWhitespace: true,\n            strictMode: true,\n            rules: [\n                // HTML comments\n                {\n                    opening: '<!--',\n                    closing: '-->',\n                    component: AreComment,\n                    priority: 10,\n                    nested: false,\n                    extract: (raw) => ({ content: raw.slice(4, -3).trim() }),\n                },\n                // interpolations\n                {\n                    opening: '{{',\n                    closing: '}}',\n                    component: AreInterpolation,\n                    priority: 9,\n                    nested: false,\n                    extract: (_, match) => ({ key: match.content }),\n                },\n                // are-root — matched before generic elements, produces AreRootNode\n                {\n                    matcher: this.rootElementMatcher.bind(this),\n                    component: AreRootNode,\n                    priority: 5,\n                },\n                // generic HTML elements\n                {\n                    matcher: this.htmlElementMatcher.bind(this),\n                    component: AreComponentNode,\n                    priority: 4,\n                },\n                // plain text fallback\n                {\n                    component: AreText,\n                    priority: 0,\n                },\n            ],\n        })\n    }\n\n\n    /**\n     * Inject AreHTMLSyntax into the container scope before loading\n     * \n     * @param container \n     */\n    @A_Feature.Extend({\n        name: A_ServiceFeatures.onBeforeLoad,\n        before: /.*/\n    })\n    async init(\n        @A_Inject(A_Scope) scope: A_Scope,\n        @A_Inject(AreSignalsContext) signalContext?: AreSignalsContext,\n        @A_Inject(AreRootCache) rootCache?: AreRootCache\n    ) {\n        this.package(scope, {\n            context: new AreHTMLEngineContext({}),\n            syntax: this.DefaultSyntax,\n            compiler: AreHTMLCompiler,\n            interpreter: AreHTMLInterpreter,\n            tokenizer: AreHTMLTokenizer,\n            lifecycle: AreHTMLLifecycle,\n            transformer: AreHTMLTransformer,\n        });\n\n        if(!signalContext) {\n            signalContext = new AreSignalsContext();\n            scope.register(signalContext);\n        }\n\n        // Default per-root subtree cache used by AreRoot for fast route-back\n        // re-injection. Apps may register their own (e.g. with a custom limit)\n        // before load to override this.\n        if (!rootCache) {\n            rootCache = new AreRootCache();\n            scope.register(rootCache);\n        }\n    }\n\n\n    protected rootElementMatcher(\n        source: string,\n        from: number,\n        to: number,\n        build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch\n    ): AreSyntaxTokenMatch | null {\n\n        // const rootTag = this.config.rootTag\n        const rootTag = 'are-root';\n\n        const tagStart = source.indexOf('<', from)\n        if (tagStart === -1 || tagStart >= to) return null\n\n        // only match if the tag name is exactly the configured root tag\n        const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/)\n        if (!tagNameMatch || tagNameMatch[1].toLowerCase() !== rootTag) return null\n\n        // delegate the actual matching to the shared HTML element logic\n        return this.htmlElementMatcher(source, from, to, build)\n    }\n\n    protected htmlElementMatcher(\n        source: string,\n        from: number,\n        to: number,\n        build: (raw: string, content: string, position: number, closing: string) => AreSyntaxTokenMatch\n    ): AreSyntaxTokenMatch | null {\n        let index = from\n\n        while (index < to) {\n            const tagStart = source.indexOf('<', index)\n            if (tagStart === -1 || tagStart >= to) return null\n\n            // skip comments, closing tags, doctype, processing instructions\n            if (source.startsWith('<!--', tagStart)) { index = tagStart + 1; continue }\n            if (source[tagStart + 1] === '/') { index = tagStart + 1; continue }\n            if (source[tagStart + 1] === '!' || source[tagStart + 1] === '?') { index = tagStart + 1; continue }\n\n            const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/)\n            if (!tagNameMatch) { index = tagStart + 1; continue }\n\n            const tagName = tagNameMatch[1]\n            const openingTagEnd = AreHTMLEngine.findTagClose(source, tagStart)\n            if (openingTagEnd === -1) return null\n\n            // extract id attribute if present in the opening tag\n            const openingTagStr = source.slice(tagStart, openingTagEnd + 1)\n            const idMatch = openingTagStr.match(/\\bid=[\"']([^\"']*)[\"']/)\n            const id = idMatch ? idMatch[1] : undefined\n\n            // self-closing: <br/> or <input/>\n            if (source[openingTagEnd - 1] === '/') {\n                const raw = source.slice(tagStart, openingTagEnd + 1)\n                const content = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd - 1)\n                const match = build(raw, content, tagStart, '/>')\n                match.payload = { entity: tagName, selfClose: true, id }\n                return match\n            }\n\n            // HTML5 void elements: <input>, <br>, <img>, etc. — treat as self-closing\n            if (isVoidElement(tagName)) {\n                const raw = source.slice(tagStart, openingTagEnd + 1)\n                const content = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd)\n                const match = build(raw, content, tagStart, '>')\n                match.payload = { entity: tagName, selfClose: true, id }\n                return match\n            }\n\n            // find matching closing tag respecting nesting\n            const closingTag = `</${tagName}>`\n            let level = 0\n            let searchIndex = openingTagEnd + 1\n            let closingStart = -1\n\n            while (searchIndex < to) {\n                const nextOpen = source.indexOf(`<${tagName}`, searchIndex)\n                const nextClose = source.indexOf(closingTag, searchIndex)\n                if (nextClose === -1) break\n\n                if (nextOpen !== -1 && nextOpen < nextClose) {\n                    const charAfter = source[nextOpen + tagName.length + 1]\n                    if (charAfter === ' ' || charAfter === '>' || charAfter === '/') {\n                        // Skip self-closing nested occurrences, e.g. <div/> inside <div>...</div>.\n                        const innerEnd = AreHTMLEngine.findTagClose(source, nextOpen)\n                        const isSelfClose = innerEnd !== -1 && source[innerEnd - 1] === '/'\n\n                        if (!isSelfClose) {\n                            level++\n                        }\n                        searchIndex = (innerEnd === -1 ? nextOpen + tagName.length + 1 : innerEnd + 1)\n                        continue\n                    }\n                }\n\n                if (level === 0) { closingStart = nextClose; break }\n                level--\n                searchIndex = nextClose + closingTag.length\n            }\n\n            if (closingStart === -1) return null\n\n            const fullTag = source.slice(tagStart, closingStart + closingTag.length)\n            const content = source.slice(openingTagEnd + 1, closingStart)\n            const match = build(fullTag, content, tagStart, closingTag)\n            match.payload = { entity: tagName, selfClose: false, id }\n            return match\n        }\n        return null\n    }\n\n    /**\n     * Find the index of the closing `>` of an opening tag, skipping over\n     * `>` characters that appear inside quoted attribute values.\n     */\n    private static findTagClose(source: string, from: number): number {\n        let inSingle = false\n        let inDouble = false\n\n        for (let i = from; i < source.length; i++) {\n            const ch = source[i]\n            if (ch === '\"' && !inSingle) inDouble = !inDouble\n            else if (ch === \"'\" && !inDouble) inSingle = !inSingle\n            else if (ch === '>' && !inSingle && !inDouble) return i\n        }\n\n        return -1\n    }\n\n}"]}