mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
Merge pull request #14240 from calixteman/14014
XFA - Get each page asynchronously in order to avoid blocking the event loop (#14014)
This commit is contained in:
commit
efb4455749
5 changed files with 81 additions and 47 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue