Merge pull request #19674 from Snuffleupagus/core-document-more-async
Introduce more `async` code in the `src/core/document.js` file
This commit is contained in:
commit
00e3a4d87a
@ -251,20 +251,20 @@ class Page {
|
|||||||
/**
|
/**
|
||||||
* @returns {Promise<BaseStream>}
|
* @returns {Promise<BaseStream>}
|
||||||
*/
|
*/
|
||||||
getContentStream() {
|
async getContentStream() {
|
||||||
return this.pdfManager.ensure(this, "content").then(content => {
|
const content = await this.pdfManager.ensure(this, "content");
|
||||||
if (content instanceof BaseStream) {
|
|
||||||
return content;
|
if (content instanceof BaseStream) {
|
||||||
}
|
return content;
|
||||||
if (Array.isArray(content)) {
|
}
|
||||||
return new StreamsSequenceStream(
|
if (Array.isArray(content)) {
|
||||||
content,
|
return new StreamsSequenceStream(
|
||||||
this._onSubStreamError.bind(this)
|
content,
|
||||||
);
|
this._onSubStreamError.bind(this)
|
||||||
}
|
);
|
||||||
// Replace non-existent page content with empty content.
|
}
|
||||||
return new NullStream();
|
// Replace non-existent page content with empty content.
|
||||||
});
|
return new NullStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
get xfaData() {
|
get xfaData() {
|
||||||
@ -375,7 +375,7 @@ class Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
save(handler, task, annotationStorage, changes) {
|
async save(handler, task, annotationStorage, changes) {
|
||||||
const partialEvaluator = new PartialEvaluator({
|
const partialEvaluator = new PartialEvaluator({
|
||||||
xref: this.xref,
|
xref: this.xref,
|
||||||
handler,
|
handler,
|
||||||
@ -392,37 +392,34 @@ class Page {
|
|||||||
|
|
||||||
// Fetch the page's annotations and save the content
|
// Fetch the page's annotations and save the content
|
||||||
// in case of interactive form fields.
|
// in case of interactive form fields.
|
||||||
return this._parsedAnnotations.then(function (annotations) {
|
const annotations = await this._parsedAnnotations;
|
||||||
const promises = [];
|
|
||||||
for (const annotation of annotations) {
|
|
||||||
promises.push(
|
|
||||||
annotation
|
|
||||||
.save(partialEvaluator, task, annotationStorage, changes)
|
|
||||||
.catch(function (reason) {
|
|
||||||
warn(
|
|
||||||
"save - ignoring annotation data during " +
|
|
||||||
`"${task.name}" task: "${reason}".`
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(promises);
|
const promises = [];
|
||||||
});
|
for (const annotation of annotations) {
|
||||||
|
promises.push(
|
||||||
|
annotation
|
||||||
|
.save(partialEvaluator, task, annotationStorage, changes)
|
||||||
|
.catch(function (reason) {
|
||||||
|
warn(
|
||||||
|
"save - ignoring annotation data during " +
|
||||||
|
`"${task.name}" task: "${reason}".`
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadResources(keys) {
|
async loadResources(keys) {
|
||||||
// TODO: add async `_getInheritableProperty` and remove this.
|
// TODO: add async `_getInheritableProperty` and remove this.
|
||||||
this.resourcesPromise ||= this.pdfManager.ensure(this, "resources");
|
await (this.resourcesPromise ??= this.pdfManager.ensure(this, "resources"));
|
||||||
|
|
||||||
return this.resourcesPromise.then(() => {
|
const objectLoader = new ObjectLoader(this.resources, keys, this.xref);
|
||||||
const objectLoader = new ObjectLoader(this.resources, keys, this.xref);
|
await objectLoader.load();
|
||||||
return objectLoader.load();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getOperatorList({
|
async getOperatorList({
|
||||||
handler,
|
handler,
|
||||||
sink,
|
sink,
|
||||||
task,
|
task,
|
||||||
@ -527,7 +524,7 @@ class Page {
|
|||||||
const pageListPromise = Promise.all([
|
const pageListPromise = Promise.all([
|
||||||
contentStreamPromise,
|
contentStreamPromise,
|
||||||
resourcesPromise,
|
resourcesPromise,
|
||||||
]).then(([contentStream]) => {
|
]).then(async ([contentStream]) => {
|
||||||
const opList = new OperatorList(intent, sink);
|
const opList = new OperatorList(intent, sink);
|
||||||
|
|
||||||
handler.send("StartRenderPage", {
|
handler.send("StartRenderPage", {
|
||||||
@ -539,109 +536,102 @@ class Page {
|
|||||||
cacheKey,
|
cacheKey,
|
||||||
});
|
});
|
||||||
|
|
||||||
return partialEvaluator
|
await partialEvaluator.getOperatorList({
|
||||||
.getOperatorList({
|
stream: contentStream,
|
||||||
stream: contentStream,
|
task,
|
||||||
task,
|
resources: this.resources,
|
||||||
resources: this.resources,
|
operatorList: opList,
|
||||||
operatorList: opList,
|
});
|
||||||
})
|
return opList;
|
||||||
.then(() => opList);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch the page's annotations and add their operator lists to the
|
// Fetch the page's annotations and add their operator lists to the
|
||||||
// page's operator list to render them.
|
// page's operator list to render them.
|
||||||
return Promise.all([
|
// eslint-disable-next-line prefer-const
|
||||||
|
let [pageOpList, annotations, newAnnotations] = await Promise.all([
|
||||||
pageListPromise,
|
pageListPromise,
|
||||||
this._parsedAnnotations,
|
this._parsedAnnotations,
|
||||||
newAnnotationsPromise,
|
newAnnotationsPromise,
|
||||||
]).then(function ([pageOpList, annotations, newAnnotations]) {
|
]);
|
||||||
if (newAnnotations) {
|
|
||||||
// Some annotations can already exist (if it has the refToReplace
|
if (newAnnotations) {
|
||||||
// property). In this case, we replace the old annotation by the new
|
// Some annotations can already exist (if it has the refToReplace
|
||||||
// one.
|
// property). In this case, we replace the old annotation by the new one.
|
||||||
annotations = annotations.filter(
|
annotations = annotations.filter(
|
||||||
a => !(a.ref && deletedAnnotations.has(a.ref))
|
a => !(a.ref && deletedAnnotations.has(a.ref))
|
||||||
);
|
);
|
||||||
for (let i = 0, ii = newAnnotations.length; i < ii; i++) {
|
for (let i = 0, ii = newAnnotations.length; i < ii; i++) {
|
||||||
const newAnnotation = newAnnotations[i];
|
const newAnnotation = newAnnotations[i];
|
||||||
if (newAnnotation.refToReplace) {
|
if (newAnnotation.refToReplace) {
|
||||||
const j = annotations.findIndex(
|
const j = annotations.findIndex(
|
||||||
a => a.ref && isRefsEqual(a.ref, newAnnotation.refToReplace)
|
a => a.ref && isRefsEqual(a.ref, newAnnotation.refToReplace)
|
||||||
);
|
);
|
||||||
if (j >= 0) {
|
if (j >= 0) {
|
||||||
annotations.splice(j, 1, newAnnotation);
|
annotations.splice(j, 1, newAnnotation);
|
||||||
newAnnotations.splice(i--, 1);
|
newAnnotations.splice(i--, 1);
|
||||||
ii--;
|
ii--;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
annotations = annotations.concat(newAnnotations);
|
|
||||||
}
|
}
|
||||||
|
annotations = annotations.concat(newAnnotations);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
annotations.length === 0 ||
|
||||||
|
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
|
||||||
|
) {
|
||||||
|
pageOpList.flush(/* lastChunk = */ true);
|
||||||
|
return { length: pageOpList.totalLength };
|
||||||
|
}
|
||||||
|
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
|
||||||
|
isEditing = !!(intent & RenderingIntentFlag.IS_EDITING),
|
||||||
|
intentAny = !!(intent & RenderingIntentFlag.ANY),
|
||||||
|
intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
|
||||||
|
intentPrint = !!(intent & RenderingIntentFlag.PRINT);
|
||||||
|
|
||||||
|
// Collect the operator list promises for the annotations. Each promise
|
||||||
|
// is resolved with the complete operator list for a single annotation.
|
||||||
|
const opListPromises = [];
|
||||||
|
for (const annotation of annotations) {
|
||||||
if (
|
if (
|
||||||
annotations.length === 0 ||
|
intentAny ||
|
||||||
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
|
(intentDisplay &&
|
||||||
|
annotation.mustBeViewed(annotationStorage, renderForms) &&
|
||||||
|
annotation.mustBeViewedWhenEditing(isEditing, modifiedIds)) ||
|
||||||
|
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
||||||
) {
|
) {
|
||||||
pageOpList.flush(/* lastChunk = */ true);
|
opListPromises.push(
|
||||||
return { length: pageOpList.totalLength };
|
annotation
|
||||||
}
|
.getOperatorList(partialEvaluator, task, intent, annotationStorage)
|
||||||
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
|
.catch(function (reason) {
|
||||||
isEditing = !!(intent & RenderingIntentFlag.IS_EDITING),
|
warn(
|
||||||
intentAny = !!(intent & RenderingIntentFlag.ANY),
|
"getOperatorList - ignoring annotation data during " +
|
||||||
intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
|
`"${task.name}" task: "${reason}".`
|
||||||
intentPrint = !!(intent & RenderingIntentFlag.PRINT);
|
);
|
||||||
|
return {
|
||||||
// Collect the operator list promises for the annotations. Each promise
|
opList: null,
|
||||||
// is resolved with the complete operator list for a single annotation.
|
separateForm: false,
|
||||||
const opListPromises = [];
|
separateCanvas: false,
|
||||||
for (const annotation of annotations) {
|
};
|
||||||
if (
|
})
|
||||||
intentAny ||
|
|
||||||
(intentDisplay &&
|
|
||||||
annotation.mustBeViewed(annotationStorage, renderForms) &&
|
|
||||||
annotation.mustBeViewedWhenEditing(isEditing, modifiedIds)) ||
|
|
||||||
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
|
||||||
) {
|
|
||||||
opListPromises.push(
|
|
||||||
annotation
|
|
||||||
.getOperatorList(
|
|
||||||
partialEvaluator,
|
|
||||||
task,
|
|
||||||
intent,
|
|
||||||
annotationStorage
|
|
||||||
)
|
|
||||||
.catch(function (reason) {
|
|
||||||
warn(
|
|
||||||
"getOperatorList - ignoring annotation data during " +
|
|
||||||
`"${task.name}" task: "${reason}".`
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
opList: null,
|
|
||||||
separateForm: false,
|
|
||||||
separateCanvas: false,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(opListPromises).then(function (opLists) {
|
|
||||||
let form = false,
|
|
||||||
canvas = false;
|
|
||||||
|
|
||||||
for (const { opList, separateForm, separateCanvas } of opLists) {
|
|
||||||
pageOpList.addOpList(opList);
|
|
||||||
|
|
||||||
form ||= separateForm;
|
|
||||||
canvas ||= separateCanvas;
|
|
||||||
}
|
|
||||||
pageOpList.flush(
|
|
||||||
/* lastChunk = */ true,
|
|
||||||
/* separateAnnots = */ { form, canvas }
|
|
||||||
);
|
);
|
||||||
return { length: pageOpList.totalLength };
|
}
|
||||||
});
|
}
|
||||||
});
|
|
||||||
|
const opLists = await Promise.all(opListPromises);
|
||||||
|
let form = false,
|
||||||
|
canvas = false;
|
||||||
|
|
||||||
|
for (const { opList, separateForm, separateCanvas } of opLists) {
|
||||||
|
pageOpList.addOpList(opList);
|
||||||
|
|
||||||
|
form ||= separateForm;
|
||||||
|
canvas ||= separateCanvas;
|
||||||
|
}
|
||||||
|
pageOpList.flush(
|
||||||
|
/* lastChunk = */ true,
|
||||||
|
/* separateAnnots = */ { form, canvas }
|
||||||
|
);
|
||||||
|
return { length: pageOpList.totalLength };
|
||||||
}
|
}
|
||||||
|
|
||||||
async extractTextContent({
|
async extractTextContent({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user