Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML embedded PDF all links override to open in a new tab (target="_blank")

I currently have a PDF embedded into an webpage. The PDF has several hyperlinks within it, but the links open in the parent frame when clicked. This takes the user to a new page with no option to return to the original PDF (navigation turned off). I can't seem to figure out how to get the links to open in a new window.

Sample PDF

<embed src="https://www.antennahouse.com/XSLsample/pdf/sample-link_1.pdf" type="application/pdf" />

Problem

Clicking second(External) link on this PDF will navigate to another website within the same tab.

Working Plunkr

The PDF documents were originally created in PowerPoint, which prevents me from adding the proper href attribute. Is there a way to modify links within a PDF to include target="_blank"?

If not, I'm wondering if there is a something I can include within the html code that would universally control how links open.

Any suggestions are welcome.

Thanks.

like image 809
IanM Avatar asked Aug 26 '15 13:08

IanM


1 Answers

Just to quickly qualify this answer, this should work for modern browsers, and only if the PDF and PDFJS are hosted on the same domain that you are embedding it in.

The trick here is to force the use of PDF.js and override Chrome's default behavior of rendering it like an extension. That way you get an iframe with html elements you can manipulate if you don't try and do it CORS. If this is for a CORS related use case, you are pretty much out of luck as editing a CORS pdf is kind of a security risk and rightfully disallowed.

You are going to want to start by getting a site set up following the example of "forced" usage. Resources here:

https://github.com/mozilla/pdf.js/wiki/Setup-PDF.js-in-a-website https://pdfobject.com/examples/pdfjs-forced.html

You'll need to run it on a webserver as well, because it won't server correctly off the filesystem alone.. Hooray more CORS issues.

Then, you'll set up your page and call it like this (based on @Paco's gist)

<html>
<head>
    <title>test pdf</title>
</head>
<div id="pdf"
     style="width:900px; height:500px"></div>
<script src="https://pdfobject.com/js/pdfobject.min.js"></script>
<script>
    var options = {
        pdfOpenParams: {
            page: 1,
            view: "Fit",
            toolbar: 0
        },
        forcePDFJS: true, //*** Forces the use of PDF.js instead of default behavior
        PDFJS_URL: "web/viewer.html" //*** Required to use PDF.js
    };
    PDFObject.embed("../pdf-test.pdf", "#pdf", options);

    document.querySelector('#pdf iframe').onload = function () {
        //can try and hook the PDF.js event for rendering completed and call it then instead. 
        //https://stackoverflow.com/questions/12693207/how-to-know-if-pdf-js-has-finished-rendering
        setTimeout(function () {
            document.querySelector('#pdf iframe').contentDocument.querySelectorAll('a:not(.bookmark)').forEach(function (a, i) {
                a.setAttribute('target', '_blank');
            })
        }, 5000)

    }
</script>
</body>
</html>
like image 164
Matti Price Avatar answered Oct 17 '22 22:10

Matti Price