From a73d08d328bba73e469f8949dc556fa24961e1e3 Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Thu, 22 Oct 2026 22:12:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=AA=97=E5=8F=A3=E6=A0=87=E7=AD=BE):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A4=9A=E6=A0=87=E7=AD=BE=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E4=B8=8E=E5=BC=82=E5=B8=B8=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/webui/ofdgo.css | 8 ++++++++ assets/webui/ofdgo.js | 35 +++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/assets/webui/ofdgo.css b/assets/webui/ofdgo.css index 20199ce..8b5b372 100644 --- a/assets/webui/ofdgo.css +++ b/assets/webui/ofdgo.css @@ -84,6 +84,10 @@ white-space: nowrap; } +.document-tab[data-error="true"] .document-tab-name { + color: #b42318; +} + .document-titlebar[data-active="false"] { background: var(--titlebar-inactive-background); color: var(--titlebar-inactive-foreground); @@ -881,6 +885,10 @@ button:not(:disabled):hover { justify-content: end; } +.confirm-dialog .form-actions button[hidden] { + display: none; +} + .convert-dialog { --convert-control-width: 64px; width: 720px; diff --git a/assets/webui/ofdgo.js b/assets/webui/ofdgo.js index 7116fb9..85ce45a 100644 --- a/assets/webui/ofdgo.js +++ b/assets/webui/ofdgo.js @@ -2477,8 +2477,9 @@ async function closeWorkspace() { if (workspace.tabs.some(tab => tab.state.saving)) { setStatus("文档正在保存,请稍后关闭"); return; } if (batch.running && !window.confirm("批量转换尚未完成,是否退出?")) return; if (workspace.tabs.some(tab => tab.opening || tab.state.exporting) && !window.confirm("文档正在处理,是否取消并退出?")) return; - const dirty = workspace.tabs.some(tab => tab.state.dirty) || canvasEditor.textChanged() || canvasEditor.cropChanged() || canvasEditor.nudgeChanged(); - if (dirty && (workspace.switching || workspace.tabs.some(tab => tab.closing) || document.body.hasAttribute("data-busy") || formDialogOpen())) { + const activeDirty = state.dirty || canvasEditor.textChanged() || canvasEditor.cropChanged() || canvasEditor.nudgeChanged(); + const dirty = activeDirty || workspace.tabs.some(tab => tab.state.dirty); + if (dirty && (workspace.switching || workspace.tabs.some(tab => tab.closing) || formDialogOpen() || (activeDirty && document.body.hasAttribute("data-busy")))) { setStatus("操作正在进行,请完成或取消后关闭"); return; } @@ -2545,6 +2546,8 @@ function renderDocumentTabs() { name.textContent = `${tab.state.dirty ? "● " : ""}${title}`; item.title = `${title}${tab.opening ? ` · ${STATUS.opening}` : tab.state.saving ? " · 正在保存" : tab.error ? ` · ${tab.error}` : ""}`; item.dataset.loading = String(Boolean(tab.opening)); + item.dataset.error = String(Boolean(tab.error)); + if (tab.error) name.textContent = `! ${name.textContent}`; const close = document.createElement("button"); close.type = "button"; close.className = "document-tab-close"; @@ -2846,17 +2849,19 @@ function setDirty(dirty) { updateWorkspaceDirty(); } -async function requestCloseAction(title, message, save) { - if (documentDialogs && !workspace.closing) return documentDialogs.request(el.closePanel, documentTab(), () => { +async function requestCloseAction(title, message, save, tab = documentTab()) { + const setup = () => { el.closeTitle.textContent = title; el.closeMessage.textContent = message; - el.closePanel.querySelector('[value="save"]').textContent = save; + const saveButton = el.closePanel.querySelector('[value="save"]'); + saveButton.hidden = !save; + if (save) saveButton.textContent = save; + el.closePanel.querySelector('[value="discard"]').textContent = save ? "放弃" : "停止并关闭"; el.closePanel.returnValue = "cancel"; - }); - el.closeTitle.textContent = title; - el.closeMessage.textContent = message; - el.closePanel.querySelector('[value="save"]').textContent = save; - el.closePanel.returnValue = "cancel"; + el.closePanel.inert = false; + }; + if (documentDialogs && !workspace.closing) return documentDialogs.request(el.closePanel, tab, setup); + setup(); const choice = new Promise(resolve => el.closePanel.addEventListener("close", () => resolve(el.closePanel.returnValue), { once: true })); if (documentDialogs) documentDialogs.showApplication(el.closePanel); else el.closePanel.showModal(); @@ -2865,6 +2870,9 @@ async function requestCloseAction(title, message, save) { } finally { el.closeTitle.textContent = "关闭文档"; el.closeMessage.textContent = "文档尚未保存"; + el.closePanel.querySelector('[value="save"]').hidden = false; + el.closePanel.querySelector('[value="discard"]').textContent = "放弃"; + el.closePanel.inert = document.body.hasAttribute("data-busy"); } } @@ -2899,7 +2907,10 @@ async function closeFile(tab = null) { try { if (tab.state.saving && tab.saveCompletion) await tab.saveCompletion; if (tab.closed) return; - if ((tab.opening || tab.state.exporting) && !window.confirm("文档正在处理,是否取消并关闭?")) return; + if (tab.opening || tab.state.exporting) { + const action = await requestCloseAction("关闭文档", "文档正在处理,是否取消并关闭?", null, tab); + if (action !== "discard" || tab.closed) return; + } if (tab.state.dirty || tab === workspace.active && (canvasEditor.input || canvasEditor.crop || canvasEditor.nudge)) { if (tab !== workspace.active && !await activateDocumentTab(tab)) return; if (!await confirmDocumentClose(tab) || tab.closed || workspace.closing) return; @@ -13756,7 +13767,7 @@ function setBusy(busy, text = "", percent = 0, status = "", tab = documentTab()) renderSecurity(); updateDisplayControls(); el.editButton.disabled = busy || Boolean(sealPreview || resourceManager.pick) || !state.doc || !state.ready || state.exporting; - el.closePanel.inert = busy; + el.closePanel.inert = busy && !el.closePanel.open; el.createForm.inert = busy && !state.imageImporting; updateCreateOptions(); el.insertForm.inert = busy;