diff --git a/src/core/catalog.js b/src/core/catalog.js index 1a2513758..3a0b3bb26 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -302,7 +302,7 @@ class Catalog { throw new FormatError("Invalid outline item encountered."); } - const data = { url: null, dest: null }; + const data = { url: null, dest: null, action: null }; Catalog.parseDestDictionary({ destDict: outlineDict, resultObj: data, @@ -324,6 +324,7 @@ class Catalog { } const outlineItem = { + action: data.action, dest: data.dest, url: data.url, unsafeUrl: data.unsafeUrl, diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index b3f167b00..e17ce2b67 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -50,6 +50,7 @@ !issue7439.pdf !issue7847_radial.pdf !issue14953.pdf +!issue15367.pdf !issue7446.pdf !issue7492.pdf !issue7544.pdf diff --git a/test/pdfs/issue15367.pdf b/test/pdfs/issue15367.pdf new file mode 100644 index 000000000..1ee10d22b Binary files /dev/null and b/test/pdfs/issue15367.pdf differ diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index bdcfb05d1..0f7b38c4e 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -1535,6 +1535,7 @@ describe("api", function () { expect(outline.length).toEqual(6); expect(outline[4]).toEqual({ + action: null, dest: "Händel -- Halle🎆lujah", url: null, unsafeUrl: undefined, @@ -1550,6 +1551,31 @@ describe("api", function () { await loadingTask.destroy(); }); + it("gets outline, with named-actions (issue 15367)", async function () { + const loadingTask = getDocument(buildGetDocumentParams("issue15367.pdf")); + const pdfDoc = await loadingTask.promise; + const outline = await pdfDoc.getOutline(); + + expect(Array.isArray(outline)).toEqual(true); + expect(outline.length).toEqual(4); + + expect(outline[1]).toEqual({ + action: "PrevPage", + dest: null, + url: null, + unsafeUrl: undefined, + newWindow: undefined, + title: "Previous Page", + color: new Uint8ClampedArray([0, 0, 0]), + count: undefined, + bold: false, + italic: false, + items: [], + }); + + await loadingTask.destroy(); + }); + it("gets outline with non-displayable chars", async function () { const loadingTask = getDocument(buildGetDocumentParams("issue14267.pdf")); const pdfDoc = await loadingTask.promise; diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index de02e3a97..46d20937d 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -109,13 +109,21 @@ class PDFOutlineViewer extends BaseTreeViewer { /** * @private */ - _bindLink(element, { url, newWindow, dest }) { + _bindLink(element, { url, newWindow, action, dest }) { const { linkService } = this; if (url) { linkService.addLinkAttributes(element, url, newWindow); return; } + if (action) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + linkService.executeNamedAction(action); + return false; + }; + return; + } element.href = linkService.getDestinationHash(dest); element.onclick = evt => {