{"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["// Zero-Lag Highlighting Engine\n\nlet allSpansArray = [];\nlet prevSelected = [];\n\n/**\n * Recursively wraps text nodes of an element into individual span elements\n * with the class name 'custom-char'.\n * @param {HTMLElement} element - The target DOM element\n */\nexport function wrapTextNodes(element) {\n    if (!element) return;\n    const nodes = Array.from(element.childNodes);\n    nodes.forEach(node => {\n        if (node.nodeType === 3) { // Node.TEXT_NODE\n            const text = node.nodeValue;\n            if (text.trim() === '' && text.length === 1) return;\n            \n            const fragment = document.createDocumentFragment();\n            for (let i = 0; i < text.length; i++) {\n                const char = text[i];\n                const span = document.createElement('span');\n                span.className = 'custom-char';\n                span.textContent = char;\n                fragment.appendChild(span);\n            }\n            node.replaceWith(fragment);\n        } else if (node.nodeType === 1) { // Node.ELEMENT_NODE\n            if (!['SCRIPT', 'STYLE', 'IFRAME', 'I', 'svg', 'path'].includes(node.tagName)) {\n                wrapTextNodes(node);\n            }\n        }\n    });\n}\n\n/**\n * Injects the CSS highlighting styles into the document head,\n * exposing custom properties for theme configuration.\n */\nexport function injectStyles() {\n    if (typeof document === 'undefined') return;\n    const styleId = 'ink-highlight-styles';\n    if (document.getElementById(styleId)) return;\n\n    const style = document.createElement('style');\n    style.id = styleId;\n    style.textContent = `\n        .custom-char {\n            position: relative;\n            display: inline;\n        }\n        .custom-char.selected {\n            color: var(--ink-text-color, #fffcf2) !important;\n            background-color: transparent !important;\n        }\n        .custom-char.selected::before {\n            content: '';\n            position: absolute;\n            left: var(--ink-x-offset, 0);\n            right: var(--ink-x-offset, 0);\n            top: var(--ink-y-offset, 50%);\n            transform: translateY(-50%);\n            height: var(--ink-height, 0.8em);\n            background-color: var(--ink-color, #000000);\n            z-index: -1;\n        }\n    `;\n    document.head.appendChild(style);\n}\n\n/**\n * Initializes the zero-lag selection engine on target elements.\n * @param {string[]} targetSelectors - Array of query selectors to wrap and highlight\n */\nexport function initInk(targetSelectors = []) {\n    if (typeof window === 'undefined' || typeof document === 'undefined') return;\n\n    // Inject required styles\n    injectStyles();\n\n    // Wrap elements\n    targetSelectors.forEach(selector => {\n        document.querySelectorAll(selector).forEach(el => {\n            wrapTextNodes(el);\n        });\n    });\n\n    // Cache spans\n    allSpansArray = Array.from(document.querySelectorAll('.custom-char'));\n    allSpansArray.forEach((span, i) => {\n        span._highlightIdx = i;\n    });\n\n    // Zero-Lag Selection Event Listener\n    document.addEventListener('selectionchange', () => {\n        const selection = window.getSelection();\n\n        // FAST CLEAR\n        for (let i = 0; i < prevSelected.length; i++) {\n            prevSelected[i].classList.remove('selected');\n        }\n        prevSelected = [];\n\n        if (selection.isCollapsed || selection.rangeCount === 0) return;\n\n        const range = selection.getRangeAt(0);\n        let startNode = range.startContainer;\n        let endNode = range.endContainer;\n\n        function getSpanIndex(node, isStart) {\n            if (node.nodeType === 3 && node.parentNode.classList.contains('custom-char')) {\n                return node.parentNode._highlightIdx;\n            }\n            if (node.nodeType === 1 && node.classList.contains('custom-char')) {\n                return node._highlightIdx;\n            }\n            if (node.nodeType === 1) {\n                if (isStart) {\n                    const first = node.querySelector('.custom-char');\n                    if (first) return first._highlightIdx;\n                } else {\n                    const all = node.querySelectorAll('.custom-char');\n                    if (all.length > 0) return all[all.length - 1]._highlightIdx;\n                }\n            }\n            return null;\n        }\n\n        let startIdx = getSpanIndex(startNode, true);\n        let endIdx = getSpanIndex(endNode, false);\n\n        // Fallback\n        if (startIdx === null || endIdx === null) {\n            let ancestor = range.commonAncestorContainer;\n            if (ancestor.nodeType === 3) ancestor = ancestor.parentNode;\n            const spans = ancestor.querySelectorAll('.custom-char');\n            \n            let foundStart = false;\n            for (let i = 0; i < spans.length; i++) {\n                if (selection.containsNode(spans[i], true)) {\n                    foundStart = true;\n                    spans[i].classList.add('selected');\n                    prevSelected.push(spans[i]);\n                } else if (foundStart) {\n                    break;\n                }\n            }\n            return;\n        }\n\n        // Master O(1) Path\n        let min = Math.min(startIdx, endIdx);\n        let max = Math.max(startIdx, endIdx);\n\n        for (let i = min; i <= max; i++) {\n            if (allSpansArray[i]) {\n                allSpansArray[i].classList.add('selected');\n                prevSelected.push(allSpansArray[i]);\n            }\n        }\n    });\n}\n\n// Auto-initialize if loaded via standard script tag with configurations\nif (typeof document !== 'undefined') {\n    const script = document.currentScript || document.querySelector('script[src*=\"ink-highlight\"]');\n    if (script) {\n        const targets = script.getAttribute('data-targets');\n        if (targets) {\n            const color = script.getAttribute('data-ink-color') || '#000000';\n            const textColor = script.getAttribute('data-ink-text-color') || '#fffcf2';\n            const height = script.getAttribute('data-ink-height') || '0.8em';\n            const yOffset = script.getAttribute('data-ink-y-offset') || '50%';\n            const xOffset = script.getAttribute('data-ink-x-offset') || '0px';\n            const fontFamily = script.getAttribute('data-font-family');\n\n            // Pre-inject configured custom property styles\n            const styleId = 'ink-highlight-custom-vars';\n            if (!document.getElementById(styleId)) {\n                const style = document.createElement('style');\n                style.id = styleId;\n                \n                let styleContent = `\n                    :root {\n                        --ink-color: ${color};\n                        --ink-text-color: ${textColor};\n                        --ink-height: ${height};\n                        --ink-y-offset: ${yOffset};\n                        --ink-x-offset: ${xOffset};\n                    }\n                `;\n                \n                // If a specific font family is requested, apply it directly to targeted classes\n                if (fontFamily) {\n                    styleContent += `\n                        ${targets} {\n                            font-family: \"${fontFamily}\", serif !important;\n                        }\n                    `;\n                }\n\n                style.textContent = styleContent;\n                document.head.appendChild(style);\n            }\n\n            // Run initialization\n            if (document.readyState === 'loading') {\n                document.addEventListener('DOMContentLoaded', () => {\n                    initInk(targets.split(',').map(s => s.trim()));\n                });\n            } else {\n                initInk(targets.split(',').map(s => s.trim()));\n            }\n        }\n    }\n}\n"],"names":["allSpansArray","prevSelected","wrapTextNodes","element","nodes","Array","from","childNodes","forEach","node","nodeType","text","nodeValue","trim","length","fragment","document","createDocumentFragment","i","char","span","createElement","className","textContent","appendChild","replaceWith","includes","tagName","injectStyles","styleId","getElementById","style","id","head","initInk","targetSelectors","window","selector","querySelectorAll","el","_highlightIdx","addEventListener","selection","getSelection","classList","remove","isCollapsed","rangeCount","range","getRangeAt","startNode","startContainer","endNode","endContainer","getSpanIndex","isStart","parentNode","contains","first","querySelector","all","startIdx","endIdx","ancestor","commonAncestorContainer","spans","foundStart","containsNode","add","push","min","Math","max","script","currentScript","targets","getAttribute","color","textColor","height","yOffset","xOffset","fontFamily","styleContent","readyState","split","map","s"],"mappings":"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"}