taggart

Simple golang tagging filesystem webapp
Log | Files | Refs

description.js (3107B)


      1 function toggleDescriptionEdit() {
      2     const displayDiv = document.getElementById('description-display');
      3     const editDiv = document.getElementById('description-edit');
      4 
      5     displayDiv.style.display = 'none';
      6     editDiv.style.display = 'block';
      7 
      8     // Focus the textarea and update character count
      9     const textarea = document.getElementById('description-textarea');
     10     textarea.focus();
     11 
     12     // Move cursor to end of text if there's existing content
     13     if (textarea.value) {
     14         textarea.setSelectionRange(textarea.value.length, textarea.value.length);
     15     }
     16 }
     17 
     18 function cancelDescriptionEdit() {
     19     const displayDiv = document.getElementById('description-display');
     20     const editDiv = document.getElementById('description-edit');
     21     const textarea = document.getElementById('description-textarea');
     22 
     23     // Reset textarea to original value
     24     const original = displayDiv.dataset.originalDescription || '';
     25     textarea.value = original;
     26 
     27     displayDiv.style.display = 'block';
     28     editDiv.style.display = 'none';
     29 
     30     // Re-run conversion so any [file/123] becomes clickable again
     31     convertFileRefs();
     32 }
     33 
     34 // Auto-resize textarea as content changes
     35 document.addEventListener('DOMContentLoaded', function() {
     36     const textarea = document.getElementById('description-textarea');
     37     if (textarea) {
     38         textarea.addEventListener('input', function() {
     39             // Reset height to auto to get the correct scrollHeight
     40             this.style.height = 'auto';
     41             // Set the height to match the content, with a minimum of 6 rows
     42             const minHeight = parseInt(getComputedStyle(this).lineHeight) * 6;
     43             this.style.height = Math.max(minHeight, this.scrollHeight) + 'px';
     44         });
     45     }
     46 });
     47 
     48 // Allow [file/123] and [/file/123] links to become clickable
     49 function convertFileRefs() {
     50   const el = document.getElementById("current-description");
     51   if (!el) return;
     52 
     53   const pattern = /\[\/?file\/(\d+)\]/g;
     54 
     55   // Walk through text nodes only, preserving existing HTML elements
     56   function processTextNodes(node) {
     57     if (node.nodeType === Node.TEXT_NODE) {
     58       let text = node.textContent;
     59 
     60       // Check if this text node contains file references
     61       if (pattern.test(text)) {
     62         // Reset regex lastIndex
     63         pattern.lastIndex = 0;
     64 
     65         // Replace file references
     66         text = text.replace(pattern, (_, id) => {
     67           return `<a href="/file/${id}" class="file-link">file/${id}</a>`;
     68         });
     69 
     70         // Create a temporary container and replace the text node
     71         const temp = document.createElement('span');
     72         temp.innerHTML = text;
     73         const parent = node.parentNode;
     74         while (temp.firstChild) {
     75           parent.insertBefore(temp.firstChild, node);
     76         }
     77         parent.removeChild(node);
     78       }
     79     } else if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== 'A') {
     80       // Don't process inside existing anchor tags
     81       Array.from(node.childNodes).forEach(processTextNodes);
     82     }
     83   }
     84 
     85   processTextNodes(el);
     86 }
     87 
     88 document.addEventListener("DOMContentLoaded", function() {
     89   convertFileRefs();
     90 });