diff --git a/src/core/document.js b/src/core/document.js index 57167a8945ac07..439256d83c952f 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -1038,10 +1038,11 @@ class PDFDocument { "hasJSActions", this.fieldObjects.then(fieldObjects => { return ( - fieldObjects !== null && - Object.values(fieldObjects).some(fieldObject => - fieldObject.some(object => object.actions !== null) - ) + (fieldObjects !== null && + Object.values(fieldObjects).some(fieldObject => + fieldObject.some(object => object.actions !== null) + )) || + !!this.catalog.jsActions ); }) ); diff --git a/test/integration/scripting_spec.js b/test/integration/scripting_spec.js index 923c7dded5580b..1a5b4d0838e790 100644 --- a/test/integration/scripting_spec.js +++ b/test/integration/scripting_spec.js @@ -16,6 +16,15 @@ const { clearInput, closePages, loadAndWait } = require("./test_utils.js"); describe("Interaction", () => { + async function actAndWaitForInput(page, selector, action) { + await clearInput(page, selector); + await action(); + await page.waitForFunction( + `document.querySelector("${selector.replace("\\", "\\\\")}").value !== ""` + ); + return page.$eval(selector, el => el.value); + } + describe("in 160F-2019.pdf", () => { let pages; @@ -280,4 +289,65 @@ describe("Interaction", () => { ); }); }); + + describe("in doc_actions.pdf for printing", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("doc_actions.pdf", "#\\34 7R"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must execute WillPrint and DidPrint actions when printing", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + let text = await actAndWaitForInput(page, "#\\34 7R", async () => { + await page.click("#print"); + }); + expect(text).withContext(`In ${browserName}`).toEqual("WillPrint"); + + await page.waitForFunction( + `document.querySelector("#\\\\35 0R").value !== ""` + ); + + text = await page.$eval("#\\35 0R", el => el.value); + expect(text).withContext(`In ${browserName}`).toEqual("DidPrint"); + }) + ); + }); + }); + + describe("in doc_actions.pdf for saving", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("doc_actions.pdf", "#\\34 7R"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must execute WillSave and DidSave actions when saving", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await clearInput(page, "#\\34 7R"); + let text = await actAndWaitForInput(page, "#\\34 7R", async () => { + await page.click("#download"); + }); + expect(text).withContext(`In ${browserName}`).toEqual("WillSave"); + + await page.waitForFunction( + `document.querySelector("#\\\\35 0R").value !== ""` + ); + + text = await page.$eval("#\\35 0R", el => el.value); + expect(text).withContext(`In ${browserName}`).toEqual("DidSave"); + }) + ); + }); + }); }); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 8d5894dee1320e..b81f2b0f685413 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -46,6 +46,7 @@ !issue7544.pdf !issue7507.pdf !issue6931_reduced.pdf +!doc_actions.pdf !issue7580.pdf !issue7598.pdf !issue12750.pdf @@ -179,7 +180,6 @@ !pattern_text_embedded_font.pdf !devicen.pdf !cmykjpeg.pdf -!docactions.pdf !issue840.pdf !160F-2019.pdf !issue4402_reduced.pdf diff --git a/test/pdfs/doc_actions.pdf b/test/pdfs/doc_actions.pdf new file mode 100644 index 00000000000000..bcc3ed923f4843 Binary files /dev/null and b/test/pdfs/doc_actions.pdf differ diff --git a/test/pdfs/docactions.pdf b/test/pdfs/docactions.pdf deleted file mode 100644 index 56381f322ad826..00000000000000 Binary files a/test/pdfs/docactions.pdf and /dev/null differ diff --git a/test/test.js b/test/test.js index 63e2a5be5d06f4..29dc94fc7a86a2 100644 --- a/test/test.js +++ b/test/test.js @@ -845,6 +845,11 @@ async function startBrowser(browserName, startUrl = "") { options.extraPrefsFirefox = { // avoid to have a prompt when leaving a page with a form "dom.disable_beforeunload": true, + // Disable dialog when saving a pdf + "pdfjs.disabled": true, + "browser.helperApps.neverAsk.saveToDisk": "application/pdf", + // Avoid popup when saving is done + "browser.download.panel.shown": true, }; } diff --git a/test/test_manifest.json b/test/test_manifest.json index 2996c1b41c761e..f5c1b0d5dfdb64 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -894,12 +894,6 @@ "link": false, "type": "eq" }, - { "id": "docactions", - "file": "pdfs/docactions.pdf", - "md5": "28ea940349cf7cb793cfe167d04b097c", - "rounds": 1, - "type": "eq" - }, { "id": "issue9084", "file": "pdfs/issue9084.pdf", "md5": "5570ec01cc869d299fec1b2f68926a08", @@ -1450,6 +1444,12 @@ "type": "eq", "about": "Type3 fonts with image resources; both pages need to be tested, otherwise the bug won't manifest." }, + { "id": "doc_actions", + "file": "pdfs/doc_actions.pdf", + "md5": "ceae4eb405a0b40394f4d63d7525a870", + "rounds": 1, + "type": "eq" + }, { "id": "issue12504", "file": "pdfs/issue12504.pdf", "md5": "04fcc87f3e7e9e925e3ef83cf0bf49f4", diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 82e3b1034087b8..5cb6dbc546ba37 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -1006,27 +1006,33 @@ describe("api", function () { }); it("gets JSActions", function (done) { // PDF document with "JavaScript" action in the OpenAction dictionary. - const loadingTask = getDocument(buildGetDocumentParams("docactions.pdf")); + const loadingTask = getDocument( + buildGetDocumentParams("doc_actions.pdf") + ); const promise = loadingTask.promise.then(async pdfDoc => { const docActions = await pdfDoc.getJSActions(); - const page5 = await pdfDoc.getPage(5); - const page12 = await pdfDoc.getPage(12); - const page5Actions = await page5.getJSActions(); - const page12Actions = await page12.getJSActions(); - return [docActions, page5Actions, page12Actions]; + const page1 = await pdfDoc.getPage(1); + const page3 = await pdfDoc.getPage(3); + const page1Actions = await page1.getJSActions(); + const page3Actions = await page3.getJSActions(); + return [docActions, page1Actions, page3Actions]; }); promise - .then(async ([docActions, page5Actions, page12Actions]) => { + .then(async ([docActions, page1Actions, page3Actions]) => { expect(docActions).toEqual({ - Open: ["console.println('Open Action');"], + DidPrint: [`this.getField("Text2").value = "DidPrint";`], + DidSave: [`this.getField("Text2").value = "DidSave";`], + WillClose: [`this.getField("Text1").value = "WillClose";`], + WillPrint: [`this.getField("Text1").value = "WillPrint";`], + WillSave: [`this.getField("Text1").value = "WillSave";`], }); - expect(page5Actions).toEqual({ - PageOpen: ["console.println('Open page 5');"], - PageClose: ["console.println('Close page 5');"], + expect(page1Actions).toEqual({ + PageOpen: [`this.getField("Text1").value = "PageOpen 1";`], + PageClose: [`this.getField("Text2").value = "PageClose 1";`], }); - expect(page12Actions).toEqual({ - PageOpen: ["console.println('Open page 12');"], - PageClose: ["console.println('Close page 12');"], + expect(page3Actions).toEqual({ + PageOpen: [`this.getField("Text5").value = "PageOpen 3";`], + PageClose: [`this.getField("Text6").value = "PageClose 3";`], }); loadingTask.destroy().then(done); })