/** * Live file-input preview. * For every found on the page, * renders a list of selected files with thumbnails (images) or file-type icons * (PDFs, videos, archivesโ€ฆ) and the filename + size. */ (() => { const ICON = { pdf: '๐Ÿ“„', video: '๐ŸŽฌ', zip: '๐Ÿ—œ๏ธ', vtt: '๐Ÿ’ฌ', image: '๐Ÿ–ผ๏ธ', other: '๐Ÿ“Ž', }; function iconFor(file) { const t = file.type; if (t.startsWith('image/')) return ICON.image; if (t === 'application/pdf') return ICON.pdf; if (t.startsWith('video/')) return ICON.video; if (t === 'application/zip' || t === 'application/x-zip-compressed') return ICON.zip; if (file.name.endsWith('.vtt')) return ICON.vtt; return ICON.other; } function humanSize(bytes) { if (bytes >= 1073741824) return `${(bytes / 1073741824).toFixed(2)} GB`; if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(2)} MB`; if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${bytes} B`; } function renderPreview(input, container) { container.innerHTML = ''; const files = Array.from(input.files); if (!files.length) return; files.forEach((file) => { const item = document.createElement('div'); item.className = 'fp-item'; if (file.type.startsWith('image/')) { const img = document.createElement('img'); img.className = 'fp-thumb'; img.alt = file.name; const reader = new FileReader(); reader.onload = (e) => { img.src = e.target.result; }; reader.readAsDataURL(file); item.appendChild(img); } else { const icon = document.createElement('span'); icon.className = 'fp-icon'; icon.textContent = iconFor(file); item.appendChild(icon); } const meta = document.createElement('span'); meta.className = 'fp-meta'; meta.innerHTML = '' + escHtml(file.name) + '' + '' + humanSize(file.size) + ''; item.appendChild(meta); container.appendChild(item); }); } function escHtml(str) { return str .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function init() { document.querySelectorAll('input[type="file"][data-preview]').forEach((input) => { const containerId = input.getAttribute('data-preview'); const container = document.getElementById(containerId); if (!container) return; input.addEventListener('change', () => { renderPreview(input, container); }); }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();