(fileName, folder, sourceId = '', sizeBytes = null)
| 662 | export { observeModalResize }; |
| 663 | |
| 664 | export async function editFile(fileName, folder, sourceId = '', sizeBytes = null) { |
| 665 | // destroy any previous editor |
| 666 | let existingEditor = document.getElementById("editorContainer"); |
| 667 | if (existingEditor) existingEditor.remove(); |
| 668 | |
| 669 | const loadSeq = ++editorLoadSeq; |
| 670 | if (editorAbortController) { |
| 671 | try { editorAbortController.abort(); } catch (e) { /* ignore */ } |
| 672 | } |
| 673 | const controller = new AbortController(); |
| 674 | editorAbortController = controller; |
| 675 | const { signal } = controller; |
| 676 | showEditorLoading(fileName, loadSeq); |
| 677 | |
| 678 | const folderUsed = folder || window.currentFolder || "root"; |
| 679 | const sid = normalizeSourceId(sourceId); |
| 680 | window.currentEditorSourceId = sid; |
| 681 | const fileUrl = buildPreviewUrl(folderUsed, fileName, sid); |
| 682 | const sizeHint = Number(sizeBytes); |
| 683 | const sizeHintBytes = (Number.isFinite(sizeHint) && sizeHint >= 0) ? sizeHint : null; |
| 684 | const isRemote = isRemoteSourceId(sid); |
| 685 | |
| 686 | const wantOO = await shouldUseOnlyOffice(fileName); |
| 687 | if (wantOO) { |
| 688 | const enc = await isFolderEncrypted(folderUsed, sid); |
| 689 | if (!enc) { |
| 690 | hideEditorLoading(loadSeq); |
| 691 | await openOnlyOffice(fileName, folderUsed, sid); |
| 692 | return; |
| 693 | } |
| 694 | showToast(t('onlyoffice_disabled_encrypted')); |
| 695 | } |
| 696 | |
| 697 | // Probe size safely via API. Prefer HEAD; if missing Content-Length, fall back to a 1-byte Range GET. |
| 698 | async function probeSize(url, signal, allowRange = true) { |
| 699 | try { |
| 700 | const h = await fetch(url, { method: "HEAD", credentials: "include", signal }); |
| 701 | if (h.ok) { |
| 702 | const len = h.headers.get("content-length") ?? h.headers.get("Content-Length"); |
| 703 | if (len && !Number.isNaN(parseInt(len, 10))) return parseInt(len, 10); |
| 704 | } |
| 705 | } catch (e) { } |
| 706 | if (!allowRange) return null; |
| 707 | try { |
| 708 | const r = await fetch(url, { |
| 709 | method: "GET", |
| 710 | headers: { Range: "bytes=0-0" }, |
| 711 | credentials: "include", |
| 712 | signal |
| 713 | }); |
| 714 | // Content-Range: bytes 0-0/12345 |
| 715 | const cr = r.headers.get("content-range") ?? r.headers.get("Content-Range"); |
| 716 | const m = cr && cr.match(/\/(\d+)\s*$/); |
| 717 | if (m) return parseInt(m[1], 10); |
| 718 | } catch (e) { } |
| 719 | return null; |
| 720 | } |
| 721 |
no test coverage detected