1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

XFA - Get each page asynchronously in order to avoid blocking the event loop (#14014)

This commit is contained in:
Calixte Denizet 2021-11-05 20:52:13 +01:00
parent 30bd5f0a39
commit 1681e25008
5 changed files with 81 additions and 47 deletions

View file

@ -787,7 +787,8 @@ class PDFDocument {
get numPages() {
let num = 0;
if (this.xfaFactory) {
num = this.xfaFactory.numPages;
// num is a Promise.
num = this.xfaFactory.getNumPages();
} else if (this.linearization) {
num = this.linearization.numPages;
} else {

View file

@ -19,6 +19,7 @@ import {
$nodeName,
$text,
$toHTML,
$toPages,
} from "./xfa_object.js";
import { Binder } from "./bind.js";
import { DataHandler } from "./data.js";
@ -45,9 +46,32 @@ class XFAFactory {
return this.root && this.form;
}
_createPages() {
/**
* In order to avoid to block the event loop, the conversion
* into pages is made asynchronously.
*/
_createPagesHelper() {
const iterator = this.form[$toPages]();
return new Promise((resolve, reject) => {
const nextIteration = () => {
try {
const value = iterator.next();
if (value.done) {
resolve(value.value);
} else {
setTimeout(nextIteration, 0);
}
} catch (e) {
reject(e);
}
};
setTimeout(nextIteration, 0);
});
}
async _createPages() {
try {
this.pages = this.form[$toHTML]();
this.pages = await this._createPagesHelper();
this.dims = this.pages.children.map(c => {
const { width, height } = c.attributes.style;
return [0, 0, parseInt(width), parseInt(height)];
@ -61,9 +85,9 @@ class XFAFactory {
return this.dims[pageIndex];
}
get numPages() {
async getNumPages() {
if (!this.pages) {
this._createPages();
await this._createPages();
}
return this.dims.length;
}
@ -94,9 +118,9 @@ class XFAFactory {
this.form[$globalData].fontFinder.add(fonts, reallyMissingFonts);
}
getPages() {
async getPages() {
if (!this.pages) {
this._createPages();
await this._createPages();
}
const pages = this.pages;
this.pages = null;

View file

@ -55,6 +55,7 @@ import {
$tabIndex,
$text,
$toHTML,
$toPages,
$toStyle,
$uid,
ContentObject,
@ -5395,7 +5396,12 @@ class Template extends XFAObject {
return searchNode(this, container, expr, true, true);
}
[$toHTML]() {
/**
* This function is a generator because the conversion into
* pages is done asynchronously and we want to save the state
* of the function where we were in the previous iteration.
*/
*[$toPages]() {
if (!this.subform.children.length) {
return HTMLResult.success({
name: "div",
@ -5641,6 +5647,7 @@ class Template extends XFAObject {
}
}
pageArea = targetPageArea || pageArea[$getNextPage]();
yield null;
}
}
}

View file

@ -84,6 +84,7 @@ const $setSetAttributes = Symbol();
const $setValue = Symbol();
const $tabIndex = Symbol();
const $text = Symbol();
const $toPages = Symbol();
const $toHTML = Symbol();
const $toString = Symbol();
const $toStyle = Symbol();
@ -1137,6 +1138,7 @@ export {
$tabIndex,
$text,
$toHTML,
$toPages,
$toString,
$toStyle,
$uid,