Merge pull request #17242 from Snuffleupagus/fieldObjects-async-fetch

Ensure that `fieldObjects` and `#collectFieldObjects` handles References correctly
This commit is contained in:
Jonas Jenwald 2023-11-08 15:28:11 +01:00 committed by GitHub
commit 42f3d57365
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1711,13 +1711,18 @@ class PDFDocument {
: clearGlobalCaches(); : clearGlobalCaches();
} }
#collectFieldObjects(name, fieldRef, promises, annotationGlobals) { async #collectFieldObjects(name, fieldRef, promises, annotationGlobals) {
const field = this.xref.fetchIfRef(fieldRef); const { xref } = this;
if (!(fieldRef instanceof Ref)) {
return;
}
const field = await xref.fetchAsync(fieldRef);
if (!(field instanceof Dict)) { if (!(field instanceof Dict)) {
return; return;
} }
if (field.has("T")) { if (field.has("T")) {
const partName = stringToPDFString(field.get("T")); const partName = stringToPDFString(await field.getAsync("T"));
name = name === "" ? partName : `${name}.${partName}`; name = name === "" ? partName : `${name}.${partName}`;
} }
@ -1726,10 +1731,10 @@ class PDFDocument {
} }
promises.get(name).push( promises.get(name).push(
AnnotationFactory.create( AnnotationFactory.create(
this.xref, xref,
fieldRef, fieldRef,
annotationGlobals, annotationGlobals,
this._localIdFactory, /* idFactory = */ null,
/* collectFields */ true, /* collectFields */ true,
/* pageRef */ null /* pageRef */ null
) )
@ -1740,10 +1745,13 @@ class PDFDocument {
}) })
); );
const kids = field.get("Kids"); if (!field.has("Kids")) {
return;
}
const kids = await field.getAsync("Kids");
if (Array.isArray(kids)) { if (Array.isArray(kids)) {
for (const kid of kids) { for (const kid of kids) {
this.#collectFieldObjects(name, kid, promises, annotationGlobals); await this.#collectFieldObjects(name, kid, promises, annotationGlobals);
} }
} }
} }
@ -1753,39 +1761,40 @@ class PDFDocument {
return shadow(this, "fieldObjects", Promise.resolve(null)); return shadow(this, "fieldObjects", Promise.resolve(null));
} }
const promise = this.pdfManager const promise = Promise.all([
.ensureDoc("annotationGlobals") this.pdfManager.ensureDoc("annotationGlobals"),
.then(async annotationGlobals => { this.pdfManager.ensureCatalog("acroForm"),
if (!annotationGlobals) { ]).then(async ([annotationGlobals, acroForm]) => {
return null; if (!annotationGlobals) {
} return null;
}
const allFields = Object.create(null); const allFields = Object.create(null);
const fieldPromises = new Map(); const fieldPromises = new Map();
for (const fieldRef of this.catalog.acroForm.get("Fields")) { for (const fieldRef of await acroForm.getAsync("Fields")) {
this.#collectFieldObjects( await this.#collectFieldObjects(
"", "",
fieldRef, fieldRef,
fieldPromises, fieldPromises,
annotationGlobals annotationGlobals
); );
} }
const allPromises = []; const allPromises = [];
for (const [name, promises] of fieldPromises) { for (const [name, promises] of fieldPromises) {
allPromises.push( allPromises.push(
Promise.all(promises).then(fields => { Promise.all(promises).then(fields => {
fields = fields.filter(field => !!field); fields = fields.filter(field => !!field);
if (fields.length > 0) { if (fields.length > 0) {
allFields[name] = fields; allFields[name] = fields;
} }
}) })
); );
} }
await Promise.all(allPromises); await Promise.all(allPromises);
return allFields; return allFields;
}); });
return shadow(this, "fieldObjects", promise); return shadow(this, "fieldObjects", promise);
} }