1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-26 01:58:06 +02:00

[Editor] Add the ability to create/update the structure tree when saving a pdf containing newly added annotations (bug 1845087)

When there is no tree, the tags for the new annotions are just put under the root element.
When there is a tree, we insert the new tags at the right place in using the value
of structTreeParentId (added in PR #16916).
This commit is contained in:
Calixte Denizet 2023-09-11 17:51:22 +02:00
parent 7f8de83e96
commit a8573d4e1b
8 changed files with 613 additions and 14 deletions

View file

@ -42,6 +42,7 @@ import { clearGlobalCaches } from "./cleanup_helper.js";
import { incrementalUpdate } from "./writer.js";
import { MessageHandler } from "../shared/message_handler.js";
import { PDFWorkerStream } from "./worker_stream.js";
import { StructTreeRoot } from "./struct_tree.js";
class WorkerTask {
constructor(name) {
@ -542,24 +543,54 @@ class WorkerMessageHandler {
pdfManager.ensureDoc("startXRef"),
pdfManager.ensureDoc("xref"),
pdfManager.ensureDoc("linearization"),
pdfManager.ensureCatalog("structTreeRoot"),
];
const promises = [];
const newAnnotationsByPage = !isPureXfa
? getNewAnnotationsMap(annotationStorage)
: null;
const [stream, acroForm, acroFormRef, startXRef, xref, linearization] =
await Promise.all(globalPromises);
const [
stream,
acroForm,
acroFormRef,
startXRef,
xref,
linearization,
_structTreeRoot,
] = await Promise.all(globalPromises);
const catalogRef = xref.trailer.getRaw("Root") || null;
let structTreeRoot;
if (newAnnotationsByPage) {
if (!_structTreeRoot) {
if (
await StructTreeRoot.canCreateStructureTree({
catalogRef,
pdfManager,
newAnnotationsByPage,
})
) {
structTreeRoot = null;
}
} else if (
await _structTreeRoot.canUpdateStructTree({
pdfManager,
newAnnotationsByPage,
})
) {
structTreeRoot = _structTreeRoot;
}
const imagePromises = AnnotationFactory.generateImages(
annotationStorage.values(),
xref,
pdfManager.evaluatorOptions.isOffscreenCanvasSupported
);
const newAnnotationPromises =
structTreeRoot === undefined ? promises : [];
for (const [pageIndex, annotations] of newAnnotationsByPage) {
promises.push(
newAnnotationPromises.push(
pdfManager.getPage(pageIndex).then(page => {
const task = new WorkerTask(`Save (editor): page ${pageIndex}`);
return page
@ -570,6 +601,32 @@ class WorkerMessageHandler {
})
);
}
if (structTreeRoot === null) {
// No structTreeRoot exists, so we need to create one.
promises.push(
Promise.all(newAnnotationPromises).then(async newRefs => {
await StructTreeRoot.createStructureTree({
newAnnotationsByPage,
xref,
catalogRef,
pdfManager,
newRefs,
});
return newRefs;
})
);
} else if (structTreeRoot) {
promises.push(
Promise.all(newAnnotationPromises).then(async newRefs => {
await structTreeRoot.updateStructureTree({
newAnnotationsByPage,
pdfManager,
newRefs,
});
return newRefs;
})
);
}
}
if (isPureXfa) {
@ -643,7 +700,7 @@ class WorkerMessageHandler {
}
newXrefInfo = {
rootRef: xref.trailer.getRaw("Root") || null,
rootRef: catalogRef,
encryptRef: xref.trailer.getRaw("Encrypt") || null,
newRef: xref.getNewTemporaryRef(),
infoRef: xref.trailer.getRaw("Info") || null,