{"version":3,"file":"Interpolation.cjs","sources":["../../src/core/Interpolation.js"],"sourcesContent":["import PathManager from './PathManager.js';\nimport syncNode from '../utils/syncNode.js';\nimport findComment from '../utils/findComment.js';\n\n/**\n * Interpolation reference for managing dynamic content between comment markers.\n * Handles the lifecycle of content that can change between renders, including\n * component recycling and DOM synchronization.\n * @param {Object} options The options object.\n * @param {Function} options.getStart Function that returns the start comment marker text.\n * @param {Function} options.getEnd Function that returns the end comment marker text.\n * @param {any} options.expression The expression to be evaluated for the interpolation.\n * @param {Function} options.isComponent Function that checks if an element is a component root element.\n * @param {Function} options.containsComponent Function that checks if an element contains a component.\n * @private\n */\nclass Interpolation {\n    constructor(options) {\n        this.getStart = options.getStart;\n        this.getEnd = options.getEnd;\n        this.expression = options.expression;\n        this.shouldSkipFind = options.shouldSkipFind;\n        this.shouldSkipSync = options.shouldSkipSync;\n        this.tracker = new PathManager();\n    }\n\n    /**\n     * Attach the interpolation reference to comment markers in the DOM.\n     * Searches for start and end comment markers, skipping component subtrees.\n     * @param {Node} parent The parent node to search in.\n     */\n    hydrate(parent) {\n        const startMark = findComment(parent, this.getStart(), this.shouldSkipFind);\n        const endMark = findComment(parent, this.getEnd(), this.shouldSkipFind, startMark);\n\n        this.ref = [\n            startMark,\n            endMark\n        ];\n    }\n\n    /**\n     * Update the interpolation content with a new fragment.\n     * Optimizes updates by syncing single non-component elements or replacing content entirely.\n     * @param {DocumentFragment} fragment The new content fragment to insert.\n     * @param {Element} targetElement The target element to replace with the new fragment.\n     */\n    update(fragment, handleComponents) {\n        let divider;\n        // Reference to marker elements.\n        const [startMark, endMark] = this.ref;\n\n        const currentFirstElement = startMark.nextSibling;\n        // Check if the interpolation is empty.\n        const currentEmpty = currentFirstElement === endMark;\n        // Check if the interpolation has a single child element.\n        const currentSingleChildElement = !currentEmpty && currentFirstElement.nextSibling === endMark;\n\n        if (currentEmpty) {\n            // The interpolation is empty. Insert the fragment.\n            endMark.parentNode.insertBefore(fragment, endMark);\n        } else if (\n            currentSingleChildElement &&\n            fragment.children.length === 1 &&\n            !this.shouldSkipSync(currentFirstElement) &&\n            !this.shouldSkipSync(fragment.firstChild)\n        ) {\n            // The interpolation has a single child element and the new fragment has a single child element.\n            // The elements doesn't contain a component. Sync node attributes and content.\n            syncNode(currentFirstElement, fragment.firstChild);\n        } else {\n            // The interpolation has multiple child elements or the new fragment has multiple child elements.\n            // Insert a divider comment before the end marker and insert the new fragment after the divider.\n            divider = document.createComment('');\n            endMark.parentNode.insertBefore(divider, endMark);\n            endMark.parentNode.insertBefore(fragment, endMark);\n        }\n        // Handle the components in the fragment. Execute the handler function.\n        handleComponents();\n\n        if (divider) {\n            // Remove old content and divider.\n            const startMark = this.ref[0];\n            if (startMark.nextSibling === divider) {\n                divider.parentNode.removeChild(divider);\n            } else {\n                const range = document.createRange();\n                range.setStartAfter(this.ref[0]);\n                range.setEndAfter(divider);\n                range.deleteContents();\n            }\n        }\n    }\n\n    /**\n     * Update the interpolation content with a new fragment. This is used for container components.\n     * @param {Element} element The element to replace with the new fragment.\n     * @param {DocumentFragment} fragment The new content fragment to insert.\n     * @param {Function} handleComponents Function to handle the components in the fragment before removing the old content.\n     */\n    updateElement(element, fragment, handleComponents) {\n        const divider = document.createComment('');\n        element.parentNode.insertBefore(divider, element.nextSibling);\n        divider.parentNode.insertBefore(fragment.firstChild, divider.nextSibling);\n        handleComponents();\n        if (element.nextSibling === divider) element.parentNode.removeChild(element);\n        divider.parentNode.removeChild(divider);\n    }\n}\n\nexport default Interpolation;\n"],"names":["PathManager","findComment","syncNode"],"mappings":"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"}