mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
1 parent
0d2e1ccdf2
commit
c2751ae186
3 files changed
+129
-3
No files matched your search
@@ -19,6 +19,7 @@
|
||||
<input id="fontDirectoryInput" class="file-input" type="file" webkitdirectory multiple>
|
||||
<div class="tool-group">
|
||||
<button id="ofdButton" class="icon-button" type="button" title="打开"><span class="open-icon"></span></button>
|
||||
<button id="closeButton" class="icon-button" type="button" title="关闭" disabled><span class="close-icon"></span></button>
|
||||
<button id="newButton" class="icon-button" type="button" title="新建"><span class="new-icon"></span></button>
|
||||
<button id="saveButton" class="icon-button" type="button" title="保存" disabled><span class="save-icon"></span></button>
|
||||
<button id="editButton" class="icon-button" type="button" title="编辑" data-pressed="false" disabled><span class="edit-icon"></span></button>
|
||||
@@ -185,6 +186,13 @@
|
||||
<button id="batchPagesButton" class="editor-group-action" type="button">页面</button>
|
||||
</div>
|
||||
</div>
|
||||
<dialog id="closePanel" class="form-dialog">
|
||||
<form method="dialog">
|
||||
<h2 class="form-title">关闭文档</h2>
|
||||
<div class="form-row">文档尚未保存</div>
|
||||
<div class="form-actions"><button class="button" value="cancel" autofocus>取消</button><button class="button" value="discard">放弃</button><button class="button" value="save">保存</button></div>
|
||||
</form>
|
||||
</dialog>
|
||||
<dialog id="convertPanel" class="form-dialog convert-dialog">
|
||||
<form id="convertForm">
|
||||
<h2 id="convertTitle" class="form-title">批量转换<span id="convertCount"></span></h2>
|
||||
|
||||
@@ -583,6 +583,7 @@ button:not(:disabled):hover {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.close-icon,
|
||||
.new-icon {
|
||||
position: relative;
|
||||
width: 15px;
|
||||
@@ -590,6 +591,8 @@ button:not(:disabled):hover {
|
||||
border: 1px solid currentColor;
|
||||
}
|
||||
|
||||
.close-icon::before,
|
||||
.close-icon::after,
|
||||
.new-icon::before,
|
||||
.new-icon::after {
|
||||
position: absolute;
|
||||
@@ -606,6 +609,19 @@ button:not(:disabled):hover {
|
||||
transform: translate(-50%, -50%) rotate(90deg);
|
||||
}
|
||||
|
||||
.close-icon::before,
|
||||
.close-icon::after {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.close-icon::before {
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.close-icon::after {
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
.save-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
+105
-3
@@ -226,6 +226,8 @@ const el = {
|
||||
encryptionConfirm: document.querySelector("#encryptionConfirm"),
|
||||
ofdInput: document.querySelector("#ofdInput"),
|
||||
ofdButton: document.querySelector("#ofdButton"),
|
||||
closeButton: document.querySelector("#closeButton"),
|
||||
closePanel: document.querySelector("#closePanel"),
|
||||
newButton: document.querySelector("#newButton"),
|
||||
editButton: document.querySelector("#editButton"),
|
||||
editNotice: document.querySelector("#editNotice"),
|
||||
@@ -606,7 +608,7 @@ el.editorTools.addEventListener("scroll", () => fontPicker.position());
|
||||
|
||||
const canvasEditor = new CanvasEditor(el.viewerPanel, {
|
||||
textControls: [el.textFont, el.textFontToggle, el.textFontAdd, el.textFontList, el.textSize, el.textColor, textBackground, ...textFormatButtons, el.undoButton, el.redoButton, el.saveButton, el.fontInput, document.querySelector("#textReflow")],
|
||||
keepTextFocus: () => fontPicker.open || canvasEditor.input?.fontDialog,
|
||||
keepTextFocus: () => fontPicker.open || el.closePanel.open || canvasEditor.input?.fontDialog,
|
||||
textClipboardScope: () => `${state.wasmSeq}:${state.fileName}:${state.doc?.documents?.[state.doc.documentIndex || 0]?.root}:${state.doc?.documentIndex || 0}:${state.doc?.documentVersion || ""}`,
|
||||
busy: () => document.body.hasAttribute("data-busy"),
|
||||
rotation: () => state.rotation,
|
||||
@@ -1378,6 +1380,8 @@ el.pageForm.addEventListener("submit", async (event) => {
|
||||
}
|
||||
});
|
||||
el.ofdButton.addEventListener("click", openOFDFile);
|
||||
el.closeButton.addEventListener("pointerdown", event => event.preventDefault());
|
||||
el.closeButton.addEventListener("click", () => closeFile().catch(error => showError(error, false)));
|
||||
batchElements.Button.addEventListener("click", () => { updateBatchControls(); batchElements.Panel.showModal(); });
|
||||
batchElements.Add.addEventListener("click", () => batchElements.Input.click());
|
||||
batchElements.Input.addEventListener("change", () => { addBatchFiles(batchElements.Input.files); batchElements.Input.value = ""; });
|
||||
@@ -2297,6 +2301,102 @@ function discardChanges() {
|
||||
return !state.dirty || window.confirm("文档尚未保存,放弃更改?");
|
||||
}
|
||||
|
||||
async function closeFile() {
|
||||
if (!state.doc || state.exporting || batch.unlocking || document.body.hasAttribute("data-busy")) return;
|
||||
let openSeq = state.openSeq;
|
||||
if (state.dirty || canvasEditor.input || canvasEditor.nudge || canvasEditor.nudgeCommit || canvasEditor.crop) {
|
||||
el.closePanel.returnValue = "cancel";
|
||||
const choice = new Promise(resolve => el.closePanel.addEventListener("close", () => resolve(el.closePanel.returnValue), { once: true }));
|
||||
el.closePanel.showModal();
|
||||
const action = await choice;
|
||||
if (openSeq !== state.openSeq || action === "cancel") return;
|
||||
if (action === "save") {
|
||||
if (!await exportFile(true, null, "ofd")) return;
|
||||
openSeq = state.openSeq;
|
||||
}
|
||||
}
|
||||
if (openSeq !== state.openSeq || batch.unlocking) return;
|
||||
clearSecurityForms();
|
||||
const source = state.ofdBytes;
|
||||
state.openSeq++;
|
||||
state.pageSeq++;
|
||||
state.ofdBytes = null;
|
||||
state.doc = null;
|
||||
state.fileName = "ofdgo.ofd";
|
||||
state.editing = false;
|
||||
state.editorInfo = null;
|
||||
state.savedRevision = null;
|
||||
state.packageDirty = false;
|
||||
state.encryptionDirty = false;
|
||||
state.composite = null;
|
||||
state.annotationEdit = null;
|
||||
state.annotationCreate = null;
|
||||
state.annotationSummary = null;
|
||||
state.openActionTask = null;
|
||||
state.openActionEnabled = false;
|
||||
state.insertObject = null;
|
||||
state.objectClipboard = null;
|
||||
state.styleClipboard = null;
|
||||
state.styleOriginal = null;
|
||||
state.conversionWarnings = [];
|
||||
state.editorViews.clear();
|
||||
state.pageSelection.clear();
|
||||
state.pageSelectionAnchor = null;
|
||||
state.pageMultiSelect = false;
|
||||
state.navigationScroll.clear();
|
||||
state.documentManagement = null;
|
||||
state.versionManagement = null;
|
||||
state.infoDocumentIndex = null;
|
||||
state.pageIndex = 0;
|
||||
state.scale = 1;
|
||||
state.rotation = 0;
|
||||
state.fontRenderPending = false;
|
||||
canvasEditor.richClipboard = null;
|
||||
canvasEditor.cancelNudge();
|
||||
canvasEditor.clear();
|
||||
setDirty(false);
|
||||
resetSearch();
|
||||
resetPageFlow();
|
||||
state.pageWindow = null;
|
||||
el.svgHost.replaceChildren();
|
||||
el.viewerPanel.classList.remove("single-page-fits-height");
|
||||
el.annotationsList.replaceChildren();
|
||||
el.annotationsStatus.textContent = "";
|
||||
el.ofdInput.value = "";
|
||||
releaseResourcePreview();
|
||||
resourceManager.sequence++;
|
||||
resourceManager.items = [];
|
||||
resourceManager.selected = null;
|
||||
resourceManager.references = [];
|
||||
resourceManager.targets = [];
|
||||
settings.sequence++;
|
||||
settings.data = null;
|
||||
settings.drafts.clear();
|
||||
settings.actions = [];
|
||||
settings.baseline = {};
|
||||
settingsElements.Content.replaceChildren();
|
||||
settingsElements.Actions.replaceChildren();
|
||||
resourceElements.List.replaceChildren();
|
||||
resourceElements.Reference.replaceChildren();
|
||||
invoicePanel.entries = [];
|
||||
invoicePanel.drafts.clear();
|
||||
invoicePanel.result = null;
|
||||
fontBinding.font = null;
|
||||
fontBinding.choices = [];
|
||||
fontManager.localFonts = [];
|
||||
markWASMExited();
|
||||
renderPageList();
|
||||
renderOutlines();
|
||||
renderMeta();
|
||||
renderFontList();
|
||||
updateFontSummary();
|
||||
updateControls();
|
||||
el.zoomLabel.textContent = "100%";
|
||||
setEmpty(STATUS.ready);
|
||||
setStatus(STATUS.ready);
|
||||
if (nativeHost) await nativeHost.release(source);
|
||||
}
|
||||
|
||||
function setEditorInfo(doc) {
|
||||
state.editorInfo = { revision: doc.revision, canUndo: doc.canUndo, canRedo: doc.canRedo,
|
||||
pageCapabilities: doc.pageCapabilities, editWarnings: doc.editWarnings || [] };
|
||||
@@ -9938,7 +10038,7 @@ function renderOutlines(reset = true) {
|
||||
state.outlineExpanded.clear();
|
||||
state.outlineSelection = null;
|
||||
}
|
||||
const outlines = state.doc.outlines || [];
|
||||
const outlines = state.doc?.outlines || [];
|
||||
el.pageListTitle.hidden = true;
|
||||
el.navigationTabs.hidden = false;
|
||||
el.outlinesTab.hidden = outlines.length === 0 && !state.editing;
|
||||
@@ -10813,7 +10913,7 @@ function renderMeta(keepDetails = false) {
|
||||
el.documentSelect.value = String(doc.documentIndex || 0);
|
||||
el.metaPanel.setAttribute("data-busy", String(!!doc.detailsPending));
|
||||
document.title = `${nativeHost ? "OFDGo" : "OFDGo WebUI"} - ${state.doc ? state.fileName : "OFD编辑器"}`;
|
||||
el.metaFile.textContent = state.fileName;
|
||||
el.metaFile.textContent = state.doc ? state.fileName : "-";
|
||||
el.metaTitle.textContent = doc.title || "-";
|
||||
el.metaAuthor.textContent = doc.author || "-";
|
||||
for (const [field, value] of [
|
||||
@@ -11912,6 +12012,7 @@ function updateControls() {
|
||||
renderSecurity();
|
||||
updateStructureControls();
|
||||
const hasDoc = Boolean(state.doc);
|
||||
el.closeButton.disabled = !hasDoc || state.exporting || document.body.hasAttribute("data-busy");
|
||||
updateDocumentControls();
|
||||
updateDisplayControls();
|
||||
updateEditorTools();
|
||||
@@ -12130,6 +12231,7 @@ function showError(err, empty = !state.doc) {
|
||||
|
||||
function setBusy(busy, text = "", percent = 0, status = "") {
|
||||
document.body.toggleAttribute("data-busy", busy);
|
||||
el.closeButton.disabled = busy || !state.doc || state.exporting;
|
||||
el.refreshAppButton.disabled = busy;
|
||||
updateStructureControls();
|
||||
updateDocumentControls();
|
||||
|
||||
Reference in new issue
Block a user