(file, snippetEl)
| 548 | } |
| 549 | |
| 550 | async function fillFileSnippet(file, snippetEl) { |
| 551 | if (!snippetEl) return; |
| 552 | snippetEl.textContent = ""; |
| 553 | snippetEl.style.display = "none"; |
| 554 | |
| 555 | const folder = file.folder || window.currentFolder || "root"; |
| 556 | const key = `${folder}::${file.name}`; |
| 557 | const ext = getFileExt(file.name || ""); |
| 558 | const bytes = Number.isFinite(file.sizeBytes) ? file.sizeBytes : null; |
| 559 | const isOffice = OFFICE_SNIPPET_EXTS.has(ext); |
| 560 | |
| 561 | // Reuse cache if we have it |
| 562 | if (_fileSnippetCache.has(key)) { |
| 563 | const cached = _fileSnippetCache.get(key); |
| 564 | if (cached) { |
| 565 | snippetEl.textContent = cached; |
| 566 | snippetEl.style.display = "block"; |
| 567 | } |
| 568 | return; |
| 569 | } |
| 570 | |
| 571 | // ============================ |
| 572 | // OFFICE DOCS (DOCX/XLSX/PPTX) |
| 573 | // ============================ |
| 574 | if (isOffice) { |
| 575 | // Size guard (avoid parsing massive Office files) |
| 576 | const MAX_OFFICE_BYTES = 20 * 1024 * 1024; // 20 MiB |
| 577 | if (bytes != null && bytes > MAX_OFFICE_BYTES) { |
| 578 | const msg = t("no_preview_available") || "No preview available"; |
| 579 | snippetEl.style.display = "block"; |
| 580 | snippetEl.textContent = msg; |
| 581 | _fileSnippetCache.set(key, msg); |
| 582 | return; |
| 583 | } |
| 584 | |
| 585 | snippetEl.style.display = "block"; |
| 586 | snippetEl.textContent = t("loading") || "Loading..."; |
| 587 | |
| 588 | try { |
| 589 | const url = withBase(`/api/file/snippet.php?folder=${encodeURIComponent(folder)}&file=${encodeURIComponent(file.name)}&t=${Date.now()}`); |
| 590 | const res = await fetch(url, { credentials: "include" }); |
| 591 | if (!res.ok) throw 0; |
| 592 | |
| 593 | const j = await res.json().catch(() => ({})); |
| 594 | let text = (j && typeof j.snippet === "string") ? j.snippet : ""; |
| 595 | text = text || ""; |
| 596 | |
| 597 | if (!text) { |
| 598 | snippetEl.textContent = ""; |
| 599 | snippetEl.style.display = "none"; |
| 600 | _fileSnippetCache.set(key, ""); |
| 601 | return; |
| 602 | } |
| 603 | |
| 604 | // Same visual rule as before: 6 lines, 600 chars, but let lines be a bit wider |
| 605 | const MAX_LINES = 6; |
| 606 | const MAX_CHARS_TOTAL = 600; |
| 607 | const MAX_LINE_CHARS = 60; |
no test coverage detected