diff --git a/src/scripting_api/doc.js b/src/scripting_api/doc.js index bbc4c4d9f..a9cbe90d8 100644 --- a/src/scripting_api/doc.js +++ b/src/scripting_api/doc.js @@ -96,10 +96,11 @@ class Doc extends PDFObject { this._zoom = data.zoom || 100; this._actions = createActionsMap(data.actions); this._globalEval = data.globalEval; - this._pageActions = new Map(); + this._pageActions = null; this._userActivation = false; this._disablePrinting = false; this._disableSaving = false; + this._otherPageActions = null; } _initActions() { @@ -155,16 +156,19 @@ class Doc extends PDFObject { _dispatchPageEvent(name, actions, pageNumber) { if (name === "PageOpen") { + this._pageActions ||= new Map(); if (!this._pageActions.has(pageNumber)) { this._pageActions.set(pageNumber, createActionsMap(actions)); } this._pageNum = pageNumber - 1; } - actions = this._pageActions.get(pageNumber)?.get(name); - if (actions) { - for (const action of actions) { - this._globalEval(action); + for (const acts of [this._pageActions, this._otherPageActions]) { + actions = acts?.get(pageNumber)?.get(name); + if (actions) { + for (const action of actions) { + this._globalEval(action); + } } } } @@ -182,6 +186,34 @@ class Doc extends PDFObject { this._fields.set(name, field); this._fieldNames.push(name); this._numFields++; + + // Fields on a page can have PageOpen/PageClose actions. + const po = field.obj._actions.get("PageOpen"); + const pc = field.obj._actions.get("PageClose"); + if (po || pc) { + this._otherPageActions ||= new Map(); + let actions = this._otherPageActions.get(field.obj._page + 1); + if (!actions) { + actions = new Map(); + this._otherPageActions.set(field.obj._page + 1, actions); + } + if (po) { + let poActions = actions.get("PageOpen"); + if (!poActions) { + poActions = []; + actions.set("PageOpen", poActions); + } + poActions.push(...po); + } + if (pc) { + let pcActions = actions.get("PageClose"); + if (!pcActions) { + pcActions = []; + actions.set("PageClose", pcActions); + } + pcActions.push(...pc); + } + } } _getDate(date) { diff --git a/test/integration/scripting_spec.mjs b/test/integration/scripting_spec.mjs index 50e2cfe96..ed71e1580 100644 --- a/test/integration/scripting_spec.mjs +++ b/test/integration/scripting_spec.mjs @@ -2456,4 +2456,58 @@ describe("Interaction", () => { ); }); }); + + describe("PageOpen and PageClose actions in fields", () => { + let pages; + let otherPages; + + beforeAll(async () => { + otherPages = await Promise.all( + global.integrationSessions.map(async session => + session.browser.newPage() + ) + ); + pages = await loadAndWait("issue18305.pdf", getSelector("7R")); + }); + + afterAll(async () => { + await closePages(pages); + await Promise.all(otherPages.map(page => page.close())); + }); + + it("must check that PageOpen/PageClose actions are correctly executed", async () => { + await Promise.all( + pages.map(async ([browserName, page], i) => { + await page.waitForFunction( + "window.PDFViewerApplication.scriptingReady === true" + ); + + const buttonSelector = `[data-annotation-id="25R"`; + await page.waitForSelector(buttonSelector, { + timeout: 0, + }); + + const inputSelector = getSelector("7R"); + let text = await page.$eval(inputSelector, el => el.value); + expect(text).withContext(`In ${browserName}`).toEqual(""); + + text = await actAndWaitForInput( + page, + inputSelector, + () => scrollIntoView(page, buttonSelector), + false + ); + expect(text).withContext(`In ${browserName}`).toEqual("PageOpen"); + + text = await actAndWaitForInput( + page, + inputSelector, + () => scrollIntoView(page, inputSelector), + false + ); + expect(text).withContext(`In ${browserName}`).toEqual("PageClose"); + }) + ); + }); + }); }); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 2c6cad459..b92b8e391 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -651,3 +651,4 @@ !pdfjs_wikipedia.pdf !bug1539074.pdf !bug1539074.1.pdf +!issue18305.pdf diff --git a/test/pdfs/issue18305.pdf b/test/pdfs/issue18305.pdf new file mode 100755 index 000000000..fee93b6e1 Binary files /dev/null and b/test/pdfs/issue18305.pdf differ