From c3e0a77b089043e548816f389176a7afe606ebe9 Mon Sep 17 00:00:00 2001 From: Charly Koch Date: Wed, 30 Jul 2025 21:36:23 +0200 Subject: [PATCH] feat: multi-line based highlight instead of line per line --- content_script.js | 76 ++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/content_script.js b/content_script.js index 8751466..0ec93f7 100644 --- a/content_script.js +++ b/content_script.js @@ -57,51 +57,65 @@ function processFileDiff(fileDiffElement) { } let fileNameElement = fileDiffElement.querySelector('.repos-change-summary-file-icon-container + .flex-column .text-ellipsis'); - const fileName = fileNameElement ? fileNameElement.textContent.trim() : null; const language = getLanguageFromFileName(fileName); - let originalLineElements = fileDiffElement.querySelectorAll('.monospaced-text > .repos-line-content'); + if (!language || !Prism.languages[language]) { + return; + } + + const originalLineElements = Array.from(fileDiffElement.querySelectorAll('.monospaced-text > .repos-line-content')); + const linesToHighlight = []; + const elementsToPreserveByLine = []; originalLineElements.forEach(originalLineElement => { - if (!originalLineElement.classList.contains('ado-syntax-highlighted')) { + const elementsToPreserve = []; + const nonCodeQuery = '.screen-reader-only, span[aria-hidden="true"]'; + originalLineElement.querySelectorAll(nonCodeQuery).forEach(el => { + elementsToPreserve.push(el.cloneNode(true)); + }); + elementsToPreserveByLine.push(elementsToPreserve); - const elementsToPreserve = []; - const nonCodeQuery = '.screen-reader-only, span[aria-hidden="true"]'; - originalLineElement.querySelectorAll(nonCodeQuery).forEach(el => { - elementsToPreserve.push(el.cloneNode(true)); - }); + const codeContainer = originalLineElement.cloneNode(true); + codeContainer.querySelectorAll(nonCodeQuery).forEach(el => el.remove()); - const codeContainer = originalLineElement.cloneNode(true); - codeContainer.querySelectorAll(nonCodeQuery).forEach(el => el.remove()); - const codeToHighlight = codeContainer.innerHTML; + linesToHighlight.push(codeContainer.innerHTML); + }); - const highlightedLine = originalLineElement.cloneNode(true); + if (linesToHighlight.length === 0) { + return; + } - const code = document.createElement('code'); // Temporary element - code.className = `language-${language}`; - code.innerHTML = codeToHighlight; - Prism.highlightElement(code, false, () => { - const contentDiv = document.createElement('div'); - contentDiv.innerHTML = code.innerHTML; - contentDiv.classList.add(getTheme(originalLineElement)); - highlightedLine.innerHTML = ''; + const code = document.createElement('code'); + code.className = `language-${language}`; + code.innerHTML = linesToHighlight.join('\n'); - elementsToPreserve.forEach(el => { - highlightedLine.appendChild(el); - }); + Prism.highlightElement(code, false, () => { + const highlightedLinesHTML = code.innerHTML.split('\n'); - highlightedLine.appendChild(contentDiv); - highlightedLine.classList.add('ado-syntax-highlighted'); + highlightedLinesHTML.forEach((highlightedLineHTML, index) => { + const originalLineElement = originalLineElements[index]; + if (!originalLineElement) return; - // Hide the original line. - // This is a hack to make the line comment button functional. Otherwise it breaks. - originalLineElement.style.display = 'none'; + const newLineElement = originalLineElement.cloneNode(false); + newLineElement.innerHTML = ''; + newLineElement.classList.add('ado-syntax-highlighted'); + newLineElement.classList.add(getTheme(originalLineElement)); - // Insert the highlighted version after the original - originalLineElement.parentNode.insertBefore(highlightedLine, originalLineElement.nextSibling) + elementsToPreserveByLine[index].forEach(el => { + newLineElement.appendChild(el); }); - } + + const codeWrapper = document.createElement('span'); + codeWrapper.innerHTML = highlightedLineHTML; + newLineElement.appendChild(codeWrapper); + + // Hide the original line + originalLineElement.style.display = 'none'; + originalLineElement.classList.add('ado-syntax-highlighted-original'); + + originalLineElement.parentNode.insertBefore(newLineElement, originalLineElement.nextSibling); + }); }); }