Skip to content

Commit

Permalink
XFA - Move the fake HTML representation of XFA from the worker to the…
Browse files Browse the repository at this point in the history
… main thread

  - the only goal of this patch is to be able to get synchronously the fake html when printing from firefox:
    - in order to print we need to inject some html in beforeprint callback but we cannot block in waiting for all the pages.
  - from a memory point of view: it doesn't change anything since the fake HTML is deleted in the worker;
  - this way we don't break any assumptions.
  • Loading branch information
calixteman committed May 27, 2021
1 parent b6d67f1 commit ac134ec
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 32 deletions.
14 changes: 9 additions & 5 deletions src/core/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ class Page {

_getBoundingBox(name) {
if (this.xfaData) {
const { width, height } = this.xfaData.attributes.style;
return [0, 0, parseInt(width), parseInt(height)];
return this.xfaData.bbox;
}

const box = this._getInheritableProperty(name, /* getArray = */ true);
Expand Down Expand Up @@ -241,7 +240,9 @@ class Page {

get xfaData() {
if (this.xfaFactory) {
return shadow(this, "xfaData", this.xfaFactory.getPage(this.pageIndex));
return shadow(this, "xfaData", {
bbox: this.xfaFactory.getBoundingBox(this.pageIndex),
});
}
return shadow(this, "xfaData", null);
}
Expand Down Expand Up @@ -851,8 +852,11 @@ class PDFDocument {
return shadow(this, "xfaFaxtory", null);
}

get isPureXfa() {
return this.xfaFactory !== null;
get htmlForXfa() {
if (this.xfaFactory) {
return this.xfaFactory.getPages();
}
return null;
}

async loadXfaFonts(handler, task) {
Expand Down
14 changes: 4 additions & 10 deletions src/core/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,13 @@ class WorkerMessageHandler {
await pdfManager.ensureDoc("checkFirstPage");
}

const [numPages, fingerprint, isPureXfa] = await Promise.all([
const [numPages, fingerprint, htmlForXfa] = await Promise.all([
pdfManager.ensureDoc("numPages"),
pdfManager.ensureDoc("fingerprint"),
pdfManager.ensureDoc("isPureXfa"),
pdfManager.ensureDoc("htmlForXfa"),
]);

if (isPureXfa) {
if (htmlForXfa) {
const task = new WorkerTask("loadXfaFonts");
startWorkerTask(task);
await pdfManager
Expand All @@ -203,7 +203,7 @@ class WorkerMessageHandler {
})
.then(() => finishWorkerTask(task));
}
return { numPages, fingerprint, isPureXfa };
return { numPages, fingerprint, htmlForXfa };
}

function getPdfManager(data, evaluatorOptions, enableXfa) {
Expand Down Expand Up @@ -501,12 +501,6 @@ class WorkerMessageHandler {
});
});

handler.on("GetPageXfa", function wphSetupGetXfa({ pageIndex }) {
return pdfManager.getPage(pageIndex).then(function (page) {
return pdfManager.ensure(page, "xfaData");
});
});

handler.on("GetOutline", function wphSetupGetOutline(data) {
return pdfManager.ensureCatalog("documentOutline");
});
Expand Down
25 changes: 21 additions & 4 deletions src/core/xfa/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,35 @@ class XFAFactory {
try {
this.root = new XFAParser().parse(XFAFactory._createDocument(data));
this.form = new Binder(this.root).bind();
this.pages = this.form[$toHTML]();
this._createPages();
} catch (e) {
console.log(e);
}
}

getPage(pageIndex) {
return this.pages.children[pageIndex];
_createPages() {
this.pages = this.form[$toHTML]();
this.dims = this.pages.children.map(c => {
const { width, height } = c.attributes.style;
return [0, 0, parseInt(width), parseInt(height)];
});
}

getBoundingBox(pageIndex) {
return this.dims[pageIndex];
}

get numberPages() {
return this.pages.children.length;
return this.dims.length;
}

getPages() {
if (!this.pages) {
this._createPages();
}
const pages = this.pages;
this.pages = null;
return pages;
}

static _createDocument(data) {
Expand Down
24 changes: 13 additions & 11 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,15 @@ class PDFDocumentProxy {
* @type {boolean} True if only XFA form.
*/
get isPureXfa() {
return this._pdfInfo.isPureXfa;
return !!this._transport._htmlForXfa;
}

/**
* @type {Object | null} An object representing a HTML tree structure
* to render the XFA, or `null` when no XFA form exists.
*/
get allXfaHtml() {
return this._transport._htmlForXfa;
}

/**
Expand Down Expand Up @@ -1255,8 +1263,8 @@ class PDFPageProxy {
* are {Object} with a name, attributes (class, style, ...), value and
* children, very similar to a HTML DOM tree), or `null` if no XFA exists.
*/
getXfa() {
return (this._xfaPromise ||= this._transport.getPageXfa(this._pageIndex));
async getXfa() {
return this._transport._htmlForXfa?.children[this._pageIndex] || null;
}

/**
Expand Down Expand Up @@ -1552,7 +1560,6 @@ class PDFPageProxy {
this.objs.clear();
this._annotationsPromise = null;
this._jsActionsPromise = null;
this._xfaPromise = null;
this._structTreePromise = null;
this.pendingCleanup = false;
return Promise.all(waitOn);
Expand Down Expand Up @@ -1588,7 +1595,6 @@ class PDFPageProxy {
this.objs.clear();
this._annotationsPromise = null;
this._jsActionsPromise = null;
this._xfaPromise = null;
this._structTreePromise = null;
if (resetStats && this._stats) {
this._stats = new StatTimer();
Expand Down Expand Up @@ -2456,6 +2462,8 @@ class WorkerTransport {

messageHandler.on("GetDoc", ({ pdfInfo }) => {
this._numPages = pdfInfo.numPages;
this._htmlForXfa = pdfInfo.htmlForXfa;
delete pdfInfo.htmlForXfa;
loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this));
});

Expand Down Expand Up @@ -2812,12 +2820,6 @@ class WorkerTransport {
});
}

getPageXfa(pageIndex) {
return this.messageHandler.sendWithPromise("GetPageXfa", {
pageIndex,
});
}

getStructTree(pageIndex) {
return this.messageHandler.sendWithPromise("GetStructTree", {
pageIndex,
Expand Down
5 changes: 3 additions & 2 deletions test/unit/xfa_tohtml_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ describe("XFAFactory", function () {

expect(factory.numberPages).toEqual(2);

const page1 = factory.getPage(0);
const pages = factory.getPages();
const page1 = pages.children[0];
expect(page1.attributes.style).toEqual({
height: "789px",
width: "456px",
Expand Down Expand Up @@ -99,7 +100,7 @@ describe("XFAFactory", function () {

// draw element must be on each page.
expect(draw.attributes.style).toEqual(
factory.getPage(1).children[1].children[0].attributes.style
pages.children[1].children[1].children[0].attributes.style
);
});
});
Expand Down

0 comments on commit ac134ec

Please sign in to comment.