Save form data in XFA datasets when pdf is a mix of acroforms and xfa (#12344)

* Move display/xml_parser.js in shared to use it in worker

* Save form data in XFA datasets when pdf is a mix of acroforms and xfa

Co-authored-by: Brendan Dahl <brendan.dahl@gmail.com>
This commit is contained in:
calixteman 2020-09-09 00:13:52 +02:00 committed by GitHub
parent 622e2fbd3a
commit 68b99c59ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 416 additions and 19 deletions

View file

@ -32,7 +32,7 @@ import {
VerbosityLevel,
warn,
} from "../shared/util.js";
import { clearPrimitiveCaches, Ref } from "./primitives.js";
import { clearPrimitiveCaches, Dict, isDict, Ref } from "./primitives.js";
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager.js";
import { incrementalUpdate } from "./writer.js";
import { isNodeJS } from "../shared/is_node.js";
@ -521,7 +521,10 @@ class WorkerMessageHandler {
filename,
}) {
pdfManager.requestLoadedStream();
const promises = [pdfManager.onLoadedStream()];
const promises = [
pdfManager.onLoadedStream(),
pdfManager.ensureCatalog("acroForm"),
];
const document = pdfManager.pdfDocument;
for (let pageIndex = 0; pageIndex < numPages; pageIndex++) {
promises.push(
@ -532,7 +535,7 @@ class WorkerMessageHandler {
);
}
return Promise.all(promises).then(([stream, ...refs]) => {
return Promise.all(promises).then(([stream, acroForm, ...refs]) => {
let newRefs = [];
for (const ref of refs) {
newRefs = ref
@ -545,6 +548,20 @@ class WorkerMessageHandler {
return stream.bytes;
}
acroForm = isDict(acroForm) ? acroForm : Dict.empty;
const xfa = acroForm.get("XFA") || [];
let xfaDatasets = null;
if (Array.isArray(xfa)) {
for (let i = 0, ii = xfa.length; i < ii; i += 2) {
if (xfa[i] === "datasets") {
xfaDatasets = xfa[i + 1];
}
}
} else {
// TODO: Support XFA streams.
warn("Unsupported XFA type.");
}
const xref = document.xref;
let newXrefInfo = Object.create(null);
if (xref.trailer) {
@ -572,7 +589,13 @@ class WorkerMessageHandler {
}
xref.resetNewRef();
return incrementalUpdate(stream.bytes, newXrefInfo, newRefs);
return incrementalUpdate(
stream.bytes,
newXrefInfo,
newRefs,
xref,
xfaDatasets
);
});
});