taggart

Simple golang tagging filesystem webapp
Log | Files | Refs

text-viewer.js (3152B)


      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 escapeHtml(text) {
     27   const div = document.createElement('div');
     28   div.textContent = text;
     29   return div.innerHTML;
     30 }
     31 
     32 function toggleFullscreen() {
     33   const container = document.getElementById("text-viewer-container");
     34   if (!document.fullscreenElement) {
     35     container.requestFullscreen();
     36   } else {
     37     document.exitFullscreen();
     38   }
     39 }
     40 
     41 function parseLineNumber(str) {
     42   // Match [l123] or [L123]
     43   const match = str.match(/^[lL](\d+)$/);
     44   return match ? Number(match[1]) : null;
     45 }
     46 
     47 function makeLineNumbersClickable(containerId, viewerId) {
     48   const container = document.getElementById(containerId);
     49   const viewer = document.getElementById(viewerId);
     50 
     51   // Regex: [l123] or [L123]
     52   const regex = /\[([lL]\d+)\]/g;
     53 
     54   container.innerHTML = container.innerHTML.replace(regex, (match, lineRef) => {
     55     const lineNum = parseLineNumber(lineRef);
     56     return `<a href="#" class="line-link" data-line="${lineNum}">${match}</a>`;
     57   });
     58 
     59   container.addEventListener("click", e => {
     60     if (e.target.classList.contains("line-link")) {
     61       e.preventDefault();
     62       const lineNum = Number(e.target.dataset.line);
     63       scrollToLine(lineNum);
     64     }
     65   });
     66 }
     67 
     68 function scrollToLine(lineNum) {
     69   const viewer = document.getElementById("text-viewer");
     70 
     71   // If line numbers are visible, find the specific line span
     72   if (viewer.classList.contains("with-lines")) {
     73     const lines = viewer.querySelectorAll("span[style*='display:block']");
     74     if (lines[lineNum - 1]) {
     75       lines[lineNum - 1].scrollIntoView({ behavior: "smooth", block: "center" });
     76       // Optional: highlight the line briefly
     77       lines[lineNum - 1].style.background = "#ff06";
     78       setTimeout(() => lines[lineNum - 1].style.background = "", 2000);
     79     }
     80   } else {
     81     // If no line numbers shown, calculate approximate position
     82     const lines = originalText.split("\n");
     83     const totalLines = lines.length;
     84     const percentage = (lineNum - 1) / totalLines;
     85     viewer.scrollTop = viewer.scrollHeight * percentage;
     86   }
     87 }
     88 
     89 // Run it after the page loads
     90 document.addEventListener("DOMContentLoaded", () => {
     91   // Replace "description-container" with the ID of your description element
     92   makeLineNumbersClickable("current-description", "text-viewer");
     93 });
     94 
     95     loadTextFile();