text-viewer.js (3026B)
1 let originalText = ''; 2 3 async function loadTextFile() { 4 const viewer = document.getElementById("text-viewer"); 5 const filename = viewer.dataset.filename; 6 const response = await fetch(`/uploads/${filename}`); 7 const text = await response.text(); 8 originalText = text; 9 viewer.textContent = text; 10 } 11 12 function toggleLineNumbers() { 13 const viewer = document.getElementById("text-viewer"); 14 if (viewer.classList.contains("with-lines")) { 15 viewer.classList.remove("with-lines"); 16 viewer.textContent = originalText; // Use stored original text 17 } else { 18 const lines = originalText.split("\n"); // Use stored original text 19 viewer.innerHTML = lines.map((line, i) => 20 `<span style="display:block;"><span style="color:#888; user-select:none; width:3em; display:inline-block;">${i+1}</span> ${escapeHtml(line)}</span>` 21 ).join(""); 22 viewer.classList.add("with-lines"); 23 } 24 } 25 26 function toggleFullscreen() { 27 const container = document.getElementById("text-viewer-container"); 28 if (!document.fullscreenElement) { 29 container.requestFullscreen(); 30 } else { 31 document.exitFullscreen(); 32 } 33 } 34 35 function parseLineNumber(str) { 36 // Match [l123] or [L123] 37 const match = str.match(/^[lL](\d+)$/); 38 return match ? Number(match[1]) : null; 39 } 40 41 function makeLineNumbersClickable(containerId, viewerId) { 42 const container = document.getElementById(containerId); 43 const viewer = document.getElementById(viewerId); 44 45 // Regex: [l123] or [L123] 46 const regex = /\[([lL]\d+)\]/g; 47 48 container.innerHTML = container.innerHTML.replace(regex, (match, lineRef) => { 49 const lineNum = parseLineNumber(lineRef); 50 return `<a href="#" class="line-link" data-line="${lineNum}">${match}</a>`; 51 }); 52 53 container.addEventListener("click", e => { 54 if (e.target.classList.contains("line-link")) { 55 e.preventDefault(); 56 const lineNum = Number(e.target.dataset.line); 57 scrollToLine(lineNum); 58 } 59 }); 60 } 61 62 function scrollToLine(lineNum) { 63 const viewer = document.getElementById("text-viewer"); 64 65 // If line numbers are visible, find the specific line span 66 if (viewer.classList.contains("with-lines")) { 67 const lines = viewer.querySelectorAll("span[style*='display:block']"); 68 if (lines[lineNum - 1]) { 69 lines[lineNum - 1].scrollIntoView({ behavior: "smooth", block: "center" }); 70 // Optional: highlight the line briefly 71 lines[lineNum - 1].style.background = "#ff06"; 72 setTimeout(() => lines[lineNum - 1].style.background = "", 2000); 73 } 74 } else { 75 // If no line numbers shown, calculate approximate position 76 const lines = originalText.split("\n"); 77 const totalLines = lines.length; 78 const percentage = (lineNum - 1) / totalLines; 79 viewer.scrollTop = viewer.scrollHeight * percentage; 80 } 81 } 82 83 // Run it after the page loads 84 document.addEventListener("DOMContentLoaded", () => { 85 // Replace "description-container" with the ID of your description element 86 makeLineNumbersClickable("current-description", "text-viewer"); 87 }); 88 89 loadTextFile();