mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 17:27:08 +08:00
1 parent
5bc92dddd1
commit
89bbbba46e
4 files changed
+240
-4
No files matched your search
+21
-1
@@ -348,6 +348,23 @@
|
|||||||
<div id="documentStatus" class="form-status" role="status"></div>
|
<div id="documentStatus" class="form-status" role="status"></div>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
<dialog id="versionPanel" class="form-dialog document-dialog" aria-labelledby="versionTitle">
|
||||||
|
<form id="versionForm">
|
||||||
|
<h2 id="versionTitle" class="form-title">版本管理</h2>
|
||||||
|
<div id="versionNotice" class="font-permission-hint" role="status" hidden></div>
|
||||||
|
<div id="versionList" class="document-list" role="listbox" aria-label="版本列表"></div>
|
||||||
|
<label class="form-row"><span>名称</span><input id="versionName" type="text" autocomplete="off" aria-label="版本名称"></label>
|
||||||
|
<div class="document-actions" role="group" aria-label="版本操作">
|
||||||
|
<button id="versionAdd" class="button" type="button" title="新增版本" aria-label="新增版本">新增</button>
|
||||||
|
<button id="versionRename" class="button" type="button" title="修改名称" aria-label="修改名称">改名</button>
|
||||||
|
<button id="versionDefault" class="button" type="button" title="默认版本" aria-label="默认版本">默认</button>
|
||||||
|
<button id="versionDelete" class="button" type="button" title="删除版本" aria-label="删除版本">删除</button>
|
||||||
|
<button id="versionSelect" class="button" type="button" title="切换版本" aria-label="切换版本">切换</button>
|
||||||
|
<button id="versionClose" class="button" type="button">关闭</button>
|
||||||
|
</div>
|
||||||
|
<div id="versionStatus" class="form-status" role="status"></div>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
<dialog id="infoPanel" class="form-dialog" aria-label="文档信息">
|
<dialog id="infoPanel" class="form-dialog" aria-label="文档信息">
|
||||||
<form id="infoForm">
|
<form id="infoForm">
|
||||||
<label class="form-row"><span>标题</span><input id="infoTitle" type="text" autofocus></label>
|
<label class="form-row"><span>标题</span><input id="infoTitle" type="text" autofocus></label>
|
||||||
@@ -620,7 +637,10 @@
|
|||||||
</section>
|
</section>
|
||||||
<div class="panel-row">
|
<div class="panel-row">
|
||||||
<div class="panel-title compact">文档</div>
|
<div class="panel-title compact">文档</div>
|
||||||
<button id="documentManageButton" class="small-button" type="button" title="文档管理" aria-label="文档管理" aria-haspopup="dialog" aria-controls="documentPanel" hidden>管理</button>
|
<div class="panel-actions">
|
||||||
|
<button id="versionManageButton" class="small-button" type="button" title="版本管理" aria-label="版本管理" aria-haspopup="dialog" aria-controls="versionPanel" hidden>版本</button>
|
||||||
|
<button id="documentManageButton" class="small-button" type="button" title="文档管理" aria-label="文档管理" aria-haspopup="dialog" aria-controls="documentPanel" hidden>管理</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="editNotice" class="font-permission-hint" role="status" hidden></div>
|
<div id="editNotice" class="font-permission-hint" role="status" hidden></div>
|
||||||
<div id="documentRow" class="document-row" hidden>
|
<div id="documentRow" class="document-row" hidden>
|
||||||
|
|||||||
+150
-2
@@ -64,6 +64,7 @@ const state = {
|
|||||||
createPackage: false,
|
createPackage: false,
|
||||||
createDocumentAt: null,
|
createDocumentAt: null,
|
||||||
documentManagement: null,
|
documentManagement: null,
|
||||||
|
versionManagement: null,
|
||||||
infoDocumentIndex: null,
|
infoDocumentIndex: null,
|
||||||
pageSelection: new Set(),
|
pageSelection: new Set(),
|
||||||
pageSelectionAnchor: null,
|
pageSelectionAnchor: null,
|
||||||
@@ -257,6 +258,19 @@ const el = {
|
|||||||
documentDeleteButton: document.querySelector("#documentDeleteButton"),
|
documentDeleteButton: document.querySelector("#documentDeleteButton"),
|
||||||
documentUpButton: document.querySelector("#documentUpButton"),
|
documentUpButton: document.querySelector("#documentUpButton"),
|
||||||
documentDownButton: document.querySelector("#documentDownButton"),
|
documentDownButton: document.querySelector("#documentDownButton"),
|
||||||
|
versionManageButton: document.querySelector("#versionManageButton"),
|
||||||
|
versionPanel: document.querySelector("#versionPanel"),
|
||||||
|
versionForm: document.querySelector("#versionForm"),
|
||||||
|
versionNotice: document.querySelector("#versionNotice"),
|
||||||
|
versionList: document.querySelector("#versionList"),
|
||||||
|
versionName: document.querySelector("#versionName"),
|
||||||
|
versionStatus: document.querySelector("#versionStatus"),
|
||||||
|
versionAdd: document.querySelector("#versionAdd"),
|
||||||
|
versionRename: document.querySelector("#versionRename"),
|
||||||
|
versionDefault: document.querySelector("#versionDefault"),
|
||||||
|
versionDelete: document.querySelector("#versionDelete"),
|
||||||
|
versionSelect: document.querySelector("#versionSelect"),
|
||||||
|
versionClose: document.querySelector("#versionClose"),
|
||||||
infoPanel: document.querySelector("#infoPanel"),
|
infoPanel: document.querySelector("#infoPanel"),
|
||||||
infoForm: document.querySelector("#infoForm"),
|
infoForm: document.querySelector("#infoForm"),
|
||||||
infoTitle: document.querySelector("#infoTitle"),
|
infoTitle: document.querySelector("#infoTitle"),
|
||||||
@@ -696,6 +710,33 @@ editorClick(el.paragraphButton, () => {
|
|||||||
el.paragraphCancel.addEventListener("click", () => el.paragraphPanel.close());
|
el.paragraphCancel.addEventListener("click", () => el.paragraphPanel.close());
|
||||||
editorClick(el.documentAddButton, () => openCreatePanel(false, true));
|
editorClick(el.documentAddButton, () => openCreatePanel(false, true));
|
||||||
editorClick(el.documentManageButton, openDocumentManagement);
|
editorClick(el.documentManageButton, openDocumentManagement);
|
||||||
|
editorClick(el.versionManageButton, openVersionManagement);
|
||||||
|
el.versionClose.addEventListener("click", () => el.versionPanel.close());
|
||||||
|
el.versionPanel.addEventListener("cancel", event => { if (el.versionForm.inert) event.preventDefault(); });
|
||||||
|
el.versionPanel.addEventListener("close", () => {
|
||||||
|
if (!el.versionPanel.open) {
|
||||||
|
state.versionManagement = null;
|
||||||
|
el.versionList.replaceChildren();
|
||||||
|
el.versionName.value = el.versionStatus.textContent = "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
el.versionForm.addEventListener("submit", event => event.preventDefault());
|
||||||
|
el.versionName.addEventListener("input", updateVersionControls);
|
||||||
|
for (const [button, action] of [[el.versionAdd, "add"], [el.versionRename, "rename"], [el.versionDefault, "default"], [el.versionDelete, "delete"], [el.versionSelect, "select"]]) {
|
||||||
|
button.addEventListener("click", () => changeVersion(action));
|
||||||
|
}
|
||||||
|
el.versionList.addEventListener("keydown", event => {
|
||||||
|
const manager = state.versionManagement;
|
||||||
|
if (!manager?.entries || manager.loading || document.body.hasAttribute("aria-busy")) return;
|
||||||
|
let index = manager.entries.findIndex(entry => entry.id === manager.id);
|
||||||
|
if (event.key === "ArrowUp") index--;
|
||||||
|
else if (event.key === "ArrowDown") index++;
|
||||||
|
else if (event.key === "Home") index = 0;
|
||||||
|
else if (event.key === "End") index = manager.entries.length - 1;
|
||||||
|
else return;
|
||||||
|
event.preventDefault();
|
||||||
|
selectManagedVersion(manager.entries[Math.max(0, Math.min(index, manager.entries.length - 1))].id, true);
|
||||||
|
});
|
||||||
el.documentClose.addEventListener("click", () => el.documentPanel.close());
|
el.documentClose.addEventListener("click", () => el.documentPanel.close());
|
||||||
el.documentPanel.addEventListener("cancel", event => { if (el.documentForm.inert) event.preventDefault(); });
|
el.documentPanel.addEventListener("cancel", event => { if (el.documentForm.inert) event.preventDefault(); });
|
||||||
el.documentPanel.addEventListener("close", () => {
|
el.documentPanel.addEventListener("close", () => {
|
||||||
@@ -1610,7 +1651,7 @@ function handleKeyDown(event) {
|
|||||||
|
|
||||||
function formDialogOpen() {
|
function formDialogOpen() {
|
||||||
return Boolean(sealPreview) || fontBindingElements.Panel.open || el.signPanel.open || el.verifyPanel.open || el.credentialsPanel.open || el.encryptionPanel.open || batchElements.Panel.open || el.exportPanel.open || el.createPanel.open || el.insertPanel.open || el.pagePanel.open || el.paragraphPanel.open || el.importPanel.open || el.infoPanel.open || el.documentPanel.open
|
return Boolean(sealPreview) || fontBindingElements.Panel.open || el.signPanel.open || el.verifyPanel.open || el.credentialsPanel.open || el.encryptionPanel.open || batchElements.Panel.open || el.exportPanel.open || el.createPanel.open || el.insertPanel.open || el.pagePanel.open || el.paragraphPanel.open || el.importPanel.open || el.infoPanel.open || el.documentPanel.open
|
||||||
|| el.batchPagesPanel.open || el.objectStylePanel.open || el.sourceTextPanel.open || el.outlinePanel.open || el.objectBoundsPanel.open || el.annotationNote.open || el.annotationCreate.open || el.objectPicker.open;
|
|| el.versionPanel.open || el.batchPagesPanel.open || el.objectStylePanel.open || el.sourceTextPanel.open || el.outlinePanel.open || el.objectBoundsPanel.open || el.annotationNote.open || el.annotationCreate.open || el.objectPicker.open;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setObjectDimension(input, value) {
|
function setObjectDimension(input, value) {
|
||||||
@@ -2036,6 +2077,106 @@ function setEditorInfo(doc) {
|
|||||||
setDirty(state.packageDirty || state.encryptionDirty || doc.revision !== state.savedRevision);
|
setDirty(state.packageDirty || state.encryptionDirty || doc.revision !== state.savedRevision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function openVersionManagement() {
|
||||||
|
if (!state.editing || !state.ready || state.exporting || document.body.hasAttribute("aria-busy")) return;
|
||||||
|
state.versionManagement = { id: state.doc.documentVersion || "", entries: null, loading: false, failed: false };
|
||||||
|
el.versionList.replaceChildren();
|
||||||
|
el.versionName.value = "";
|
||||||
|
el.versionPanel.showModal();
|
||||||
|
await refreshVersionManagement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshVersionManagement(focus = false) {
|
||||||
|
const manager = state.versionManagement, openSeq = state.openSeq;
|
||||||
|
if (!manager || !el.versionPanel.open) return;
|
||||||
|
manager.loading = true;
|
||||||
|
manager.failed = false;
|
||||||
|
el.versionStatus.textContent = "正在读取版本";
|
||||||
|
updateVersionControls();
|
||||||
|
try {
|
||||||
|
const entries = await callWASM("ofdgoDocumentVersions");
|
||||||
|
if (state.versionManagement !== manager || !el.versionPanel.open) return;
|
||||||
|
if (openSeq !== state.openSeq) return refreshVersionManagement(focus);
|
||||||
|
manager.entries = entries;
|
||||||
|
if (!entries.some(entry => entry.id === manager.id)) manager.id = state.doc.documentVersion || "";
|
||||||
|
el.versionList.replaceChildren(...entries.map(entry => {
|
||||||
|
const button = document.createElement("button");
|
||||||
|
button.type = "button";
|
||||||
|
button.className = "document-entry";
|
||||||
|
button.setAttribute("role", "option");
|
||||||
|
button.setAttribute("aria-current", String(entry.id === (state.doc.documentVersion || "")));
|
||||||
|
const name = document.createElement("span"), marker = document.createElement("span");
|
||||||
|
name.className = "document-name";
|
||||||
|
name.textContent = entry.id ? entry.name || `版本 ${entry.index}` : "主文档";
|
||||||
|
marker.className = "document-pages";
|
||||||
|
marker.textContent = entry.default ? "默认" : "";
|
||||||
|
button.title = name.textContent;
|
||||||
|
button.append(name, marker);
|
||||||
|
button.addEventListener("click", () => selectManagedVersion(entry.id));
|
||||||
|
return button;
|
||||||
|
}));
|
||||||
|
manager.loading = false;
|
||||||
|
el.versionStatus.textContent = "";
|
||||||
|
selectManagedVersion(manager.id, focus);
|
||||||
|
} catch (err) {
|
||||||
|
if (state.versionManagement !== manager || !el.versionPanel.open) return;
|
||||||
|
if (openSeq !== state.openSeq) return refreshVersionManagement(focus);
|
||||||
|
manager.failed = true;
|
||||||
|
el.versionStatus.textContent = err.message;
|
||||||
|
} finally {
|
||||||
|
if (state.versionManagement === manager && openSeq === state.openSeq) {
|
||||||
|
manager.loading = false;
|
||||||
|
updateVersionControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectManagedVersion(id, focus = false) {
|
||||||
|
const manager = state.versionManagement;
|
||||||
|
if (!manager || manager.loading || document.body.hasAttribute("aria-busy")) return;
|
||||||
|
const index = manager.entries?.findIndex(entry => entry.id === id) ?? -1;
|
||||||
|
if (index < 0) return;
|
||||||
|
manager.id = id;
|
||||||
|
el.versionName.value = manager.entries[index].name;
|
||||||
|
Array.from(el.versionList.children).forEach((button, position) => {
|
||||||
|
button.setAttribute("aria-selected", String(position === index));
|
||||||
|
button.tabIndex = position === index ? 0 : -1;
|
||||||
|
});
|
||||||
|
updateVersionControls();
|
||||||
|
if (focus) el.versionList.children[index]?.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function changeVersion(action) {
|
||||||
|
const manager = state.versionManagement;
|
||||||
|
if (!state.editing || !manager?.entries || manager.loading || manager.failed || document.body.hasAttribute("aria-busy")) return;
|
||||||
|
const entry = manager.entries.find(entry => entry.id === manager.id);
|
||||||
|
if (!entry) return;
|
||||||
|
if (action === "delete" && (!entry.id || !window.confirm(`删除版本“${entry.name || entry.index}”?`))) return;
|
||||||
|
el.versionStatus.textContent = "正在处理版本";
|
||||||
|
if (await changeDocument("ofdgoChangeVersion", null, action, entry.id, el.versionName.value.trim())) {
|
||||||
|
if (state.versionManagement !== manager || !el.versionPanel.open) return;
|
||||||
|
if (action === "add" || action === "select") manager.id = state.doc.documentVersion || "";
|
||||||
|
await refreshVersionManagement(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateVersionControls() {
|
||||||
|
const manager = state.versionManagement, busy = document.body.hasAttribute("aria-busy");
|
||||||
|
const disabled = !state.editing || !state.ready || state.exporting || busy;
|
||||||
|
el.versionManageButton.hidden = !state.editing;
|
||||||
|
el.versionManageButton.disabled = disabled;
|
||||||
|
el.versionNotice.textContent = state.editorInfo?.editWarnings?.join(";") || "";
|
||||||
|
el.versionNotice.hidden = !el.versionNotice.textContent;
|
||||||
|
const entry = manager?.entries?.find(entry => entry.id === manager.id);
|
||||||
|
const unavailable = disabled || !entry || Boolean(manager?.loading || manager?.failed);
|
||||||
|
el.versionList.inert = busy || Boolean(manager?.loading);
|
||||||
|
el.versionName.disabled = el.versionAdd.disabled = unavailable;
|
||||||
|
el.versionRename.disabled = unavailable || !entry?.id || el.versionName.value.trim() === entry.name;
|
||||||
|
el.versionDelete.disabled = unavailable || !entry?.id;
|
||||||
|
el.versionDefault.disabled = unavailable || Boolean(entry?.default);
|
||||||
|
el.versionSelect.disabled = unavailable || entry?.id === (state.doc?.documentVersion || "");
|
||||||
|
}
|
||||||
|
|
||||||
function managedDocumentIndex() {
|
function managedDocumentIndex() {
|
||||||
return state.documentManagement?.index ?? state.doc?.documentIndex ?? 0;
|
return state.documentManagement?.index ?? state.doc?.documentIndex ?? 0;
|
||||||
}
|
}
|
||||||
@@ -3098,7 +3239,8 @@ async function changeDocument(name, item, ...args) {
|
|||||||
const previousDocument = state.doc.documents?.[state.doc.documentIndex || 0];
|
const previousDocument = state.doc.documents?.[state.doc.documentIndex || 0];
|
||||||
const nextDocument = doc.documents?.[doc.documentIndex || 0];
|
const nextDocument = doc.documents?.[doc.documentIndex || 0];
|
||||||
const sameDocument = previousDocument?.id && previousDocument.id === nextDocument?.id && state.doc.documentIndex === doc.documentIndex;
|
const sameDocument = previousDocument?.id && previousDocument.id === nextDocument?.id && state.doc.documentIndex === doc.documentIndex;
|
||||||
const documentChanged = previousDocument?.id !== nextDocument?.id || previousDocument?.root !== nextDocument?.root
|
const documentChanged = (state.doc.documentVersion || "") !== (doc.documentVersion || "")
|
||||||
|
|| previousDocument?.id !== nextDocument?.id || previousDocument?.root !== nextDocument?.root
|
||||||
&& !(sameDocument && (name === "ofdgoChangeFontBinding" || restoring));
|
&& !(sameDocument && (name === "ofdgoChangeFontBinding" || restoring));
|
||||||
const packageChanged = documentChanged || name === "ofdgoChangeDocument" || restoring
|
const packageChanged = documentChanged || name === "ofdgoChangeDocument" || restoring
|
||||||
&& JSON.stringify(doc.documents?.map(entry => [entry.root, entry.id])) !== JSON.stringify(state.doc.documents?.map(entry => [entry.root, entry.id]));
|
&& JSON.stringify(doc.documents?.map(entry => [entry.root, entry.id])) !== JSON.stringify(state.doc.documents?.map(entry => [entry.root, entry.id]));
|
||||||
@@ -3227,6 +3369,8 @@ async function changeDocument(name, item, ...args) {
|
|||||||
el.createStatus.textContent = err.message;
|
el.createStatus.textContent = err.message;
|
||||||
} else if (el.importPanel.open) {
|
} else if (el.importPanel.open) {
|
||||||
el.importStatus.textContent = err.message;
|
el.importStatus.textContent = err.message;
|
||||||
|
} else if (el.versionPanel.open) {
|
||||||
|
el.versionStatus.textContent = err.message;
|
||||||
} else if (el.documentPanel.open) {
|
} else if (el.documentPanel.open) {
|
||||||
el.documentStatus.textContent = err.message;
|
el.documentStatus.textContent = err.message;
|
||||||
} else {
|
} else {
|
||||||
@@ -3971,6 +4115,8 @@ async function openOFD(file, remote = null) {
|
|||||||
el.infoPanel.close();
|
el.infoPanel.close();
|
||||||
el.documentPanel.close();
|
el.documentPanel.close();
|
||||||
state.documentManagement = null;
|
state.documentManagement = null;
|
||||||
|
el.versionPanel.close();
|
||||||
|
state.versionManagement = null;
|
||||||
state.infoDocumentIndex = null;
|
state.infoDocumentIndex = null;
|
||||||
el.annotationNote.close();
|
el.annotationNote.close();
|
||||||
el.annotationCreate.close();
|
el.annotationCreate.close();
|
||||||
@@ -8785,6 +8931,7 @@ function updateDocumentControls() {
|
|||||||
el.documentDeleteButton.disabled = actionsDisabled || count <= 1;
|
el.documentDeleteButton.disabled = actionsDisabled || count <= 1;
|
||||||
el.documentUpButton.disabled = actionsDisabled || index === 0;
|
el.documentUpButton.disabled = actionsDisabled || index === 0;
|
||||||
el.documentDownButton.disabled = actionsDisabled || index >= count - 1;
|
el.documentDownButton.disabled = actionsDisabled || index >= count - 1;
|
||||||
|
updateVersionControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateControls() {
|
function updateControls() {
|
||||||
@@ -9006,6 +9153,7 @@ function setBusy(busy, text = "", percent = 0, status = "") {
|
|||||||
el.paragraphForm.inert = busy;
|
el.paragraphForm.inert = busy;
|
||||||
el.infoForm.inert = busy;
|
el.infoForm.inert = busy;
|
||||||
el.documentForm.inert = busy;
|
el.documentForm.inert = busy;
|
||||||
|
el.versionForm.inert = busy;
|
||||||
el.attachmentForm.inert = busy;
|
el.attachmentForm.inert = busy;
|
||||||
el.attachmentPanel.inert = busy;
|
el.attachmentPanel.inert = busy;
|
||||||
el.annotationForm.inert = busy;
|
el.annotationForm.inert = busy;
|
||||||
|
|||||||
+59
-1
@@ -186,6 +186,8 @@ func RunWASM() {
|
|||||||
registerAsyncCallback("ofdgoDetectFormat", detectDocumentFormat)
|
registerAsyncCallback("ofdgoDetectFormat", detectDocumentFormat)
|
||||||
registerCallback("ofdgoOpen", openDocument)
|
registerCallback("ofdgoOpen", openDocument)
|
||||||
registerCallback("ofdgoSelectDocument", selectDocument)
|
registerCallback("ofdgoSelectDocument", selectDocument)
|
||||||
|
registerCallback("ofdgoDocumentVersions", documentVersions)
|
||||||
|
registerCallback("ofdgoChangeVersion", changeDocumentVersion)
|
||||||
registerCallback("ofdgoChangeDocument", changePackageDocument)
|
registerCallback("ofdgoChangeDocument", changePackageDocument)
|
||||||
registerCallback("ofdgoPackageDocuments", packageDocuments)
|
registerCallback("ofdgoPackageDocuments", packageDocuments)
|
||||||
registerAsyncCallback("ofdgoConvertPDF", convertPDFDocument)
|
registerAsyncCallback("ofdgoConvertPDF", convertPDFDocument)
|
||||||
@@ -3443,6 +3445,60 @@ func packageDocuments(args []js.Value) (any, error) {
|
|||||||
return entries, nil
|
return entries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentVersions 读取当前编辑文档的版本列表,不切换版本或解析页面
|
||||||
|
// 入参: args 保留参数
|
||||||
|
// 返回: any 版本列表, error 读取错误
|
||||||
|
func documentVersions(args []js.Value) (any, error) {
|
||||||
|
if currentEditor == nil {
|
||||||
|
return nil, fmt.Errorf("no document is being edited")
|
||||||
|
}
|
||||||
|
versions, err := currentEditor.DocumentVersions()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
entries := make([]VersionEntry, 1, len(versions)+1)
|
||||||
|
entries[0].Default = true
|
||||||
|
for _, version := range versions {
|
||||||
|
entries = append(entries, VersionEntry{ID: version.ID, Index: version.Index, Name: version.Name, Default: version.Current})
|
||||||
|
if version.Current {
|
||||||
|
entries[0].Default = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// changeDocumentVersion 调用库层版本操作,沿用编辑历史和预览更新流程
|
||||||
|
// 入参: args 操作、版本标识及可选名称
|
||||||
|
// 返回: any 文档信息, error 操作错误
|
||||||
|
func changeDocumentVersion(args []js.Value) (any, error) {
|
||||||
|
if len(args) != 3 {
|
||||||
|
return nil, fmt.Errorf("invalid version arguments")
|
||||||
|
}
|
||||||
|
return changeAtomicObjects(func() error {
|
||||||
|
id, name := args[1].String(), args[2].String()
|
||||||
|
switch args[0].String() {
|
||||||
|
case "add":
|
||||||
|
return currentEditor.Transaction(func(editor *ofdgo.Editor) error {
|
||||||
|
if err := editor.SelectVersion(id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err := editor.AddVersion(name)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
case "rename":
|
||||||
|
return currentEditor.RenameVersion(id, name)
|
||||||
|
case "delete":
|
||||||
|
return currentEditor.DeleteVersion(id)
|
||||||
|
case "default":
|
||||||
|
return currentEditor.SetDefaultVersion(id)
|
||||||
|
case "select":
|
||||||
|
return currentEditor.SelectVersion(id)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid version operation")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// changeAttachment 编辑附件,逐个读取文件并复用库层事务和历史
|
// changeAttachment 编辑附件,逐个读取文件并复用库层事务和历史
|
||||||
// 入参: args 操作、附件标识、名称列表、文件读取回调
|
// 入参: args 操作、附件标识、名称列表、文件读取回调
|
||||||
// 返回: any 编辑状态, error 错误信息
|
// 返回: any 编辑状态, error 错误信息
|
||||||
@@ -3649,7 +3705,9 @@ func previewEditor(editor *ofdgo.Editor, annotations bool) (editorInfo, error) {
|
|||||||
if currentSession != nil {
|
if currentSession != nil {
|
||||||
previous := currentSession.Reader
|
previous := currentSession.Reader
|
||||||
oldBody, newBody := previous.OFD.DocBody[previous.DocumentIndex()], reader.OFD.DocBody[reader.DocumentIndex()]
|
oldBody, newBody := previous.OFD.DocBody[previous.DocumentIndex()], reader.OFD.DocBody[reader.DocumentIndex()]
|
||||||
if oldBody.DocRoot != newBody.DocRoot || oldBody.DocInfo.DocID != newBody.DocInfo.DocID {
|
oldVersion, _ := previous.DocumentVersionID()
|
||||||
|
newVersion, _ := reader.DocumentVersionID()
|
||||||
|
if oldBody.DocRoot != newBody.DocRoot || oldBody.DocInfo.DocID != newBody.DocInfo.DocID || oldVersion != newVersion {
|
||||||
copiedObjects, copiedStyle = nil, nil
|
copiedObjects, copiedStyle = nil, nil
|
||||||
clearImport()
|
clearImport()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ type pageBoxInfo struct {
|
|||||||
// DocumentInfo 文档信息
|
// DocumentInfo 文档信息
|
||||||
type DocumentInfo struct {
|
type DocumentInfo struct {
|
||||||
DocumentIndex int `json:"documentIndex"`
|
DocumentIndex int `json:"documentIndex"`
|
||||||
|
DocumentVersion string `json:"documentVersion"`
|
||||||
Documents []DocumentEntry `json:"documents,omitempty"`
|
Documents []DocumentEntry `json:"documents,omitempty"`
|
||||||
Encryption EncryptionInfo `json:"encryption"`
|
Encryption EncryptionInfo `json:"encryption"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
@@ -98,6 +99,14 @@ type DocumentInfo struct {
|
|||||||
DetailsPending bool `json:"detailsPending,omitempty"`
|
DetailsPending bool `json:"detailsPending,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VersionEntry 版本管理列表中的入口,空ID表示主文档
|
||||||
|
type VersionEntry struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Index int32 `json:"index"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Default bool `json:"default"`
|
||||||
|
}
|
||||||
|
|
||||||
// DocumentEntry 包内文档入口,管理列表按需补充元数据和页数
|
// DocumentEntry 包内文档入口,管理列表按需补充元数据和页数
|
||||||
type DocumentEntry struct {
|
type DocumentEntry struct {
|
||||||
Index int `json:"index"`
|
Index int `json:"index"`
|
||||||
@@ -441,6 +450,7 @@ func (s *Session) Summary() DocumentInfo {
|
|||||||
Outlines: s.doc.OutlineInfos(),
|
Outlines: s.doc.OutlineInfos(),
|
||||||
DetailsPending: true,
|
DetailsPending: true,
|
||||||
}
|
}
|
||||||
|
info.DocumentVersion, _ = s.Reader.DocumentVersionID()
|
||||||
for index, body := range s.Reader.OFD.DocBody {
|
for index, body := range s.Reader.OFD.DocBody {
|
||||||
info.Documents = append(info.Documents, DocumentEntry{Index: index, Title: body.DocInfo.Title, Root: body.DocRoot, ID: body.DocInfo.DocID})
|
info.Documents = append(info.Documents, DocumentEntry{Index: index, Title: body.DocInfo.Title, Root: body.DocRoot, ID: body.DocInfo.DocID})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user