diff --git a/frontend/app.js b/frontend/app.js index 9a5e919..59ad05d 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -5020,27 +5020,45 @@ }, highlightMatches() { + const matchesByNode = new Map(); + this.matches.forEach((match, idx) => { - const node = match.node; - const text = node.textContent; - const before = text.substring(0, match.index); - const matchText = text.substring(match.index, match.index + match.length); - const after = text.substring(match.index + match.length); + if (!matchesByNode.has(match.node)) { + matchesByNode.set(match.node, []); + } + matchesByNode.get(match.node).push({ match, idx }); + }); - const mark = document.createElement('mark'); - mark.className = idx === this.currentIndex ? 'find-highlight find-highlight-active' : 'find-highlight'; - mark.textContent = matchText; - mark.setAttribute('data-find-index', idx); + matchesByNode.forEach((entries, node) => { + if (!node || !node.parentNode) return; + const text = node.textContent || ''; + let cursor = 0; const fragment = document.createDocumentFragment(); - if (before) fragment.appendChild(document.createTextNode(before)); - fragment.appendChild(mark); - if (after) fragment.appendChild(document.createTextNode(after)); + + entries.sort((a, b) => a.match.index - b.match.index); + + entries.forEach(({ match, idx }) => { + if (match.index > cursor) { + fragment.appendChild(document.createTextNode(text.substring(cursor, match.index))); + } + + const matchText = text.substring(match.index, match.index + match.length); + const mark = document.createElement('mark'); + mark.className = idx === this.currentIndex ? 'find-highlight find-highlight-active' : 'find-highlight'; + mark.textContent = matchText; + mark.setAttribute('data-find-index', idx); + fragment.appendChild(mark); + + match.element = mark; + cursor = match.index + match.length; + }); + + if (cursor < text.length) { + fragment.appendChild(document.createTextNode(text.substring(cursor))); + } node.parentNode.replaceChild(fragment, node); - - // Update reference to the mark element - match.element = mark; }); }, @@ -5050,6 +5068,7 @@ const marks = contentArea.querySelectorAll('mark.find-highlight'); marks.forEach(mark => { + if (!mark.parentNode) return; const text = mark.textContent; const textNode = document.createTextNode(text); mark.parentNode.replaceChild(textNode, mark);