Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Permission denied to access property 'print' #10290

Closed
dotnetCarpenter opened this issue Nov 22, 2018 · 41 comments
Closed

Error: Permission denied to access property 'print' #10290

dotnetCarpenter opened this issue Nov 22, 2018 · 41 comments
Labels

Comments

@dotnetCarpenter
Copy link

dotnetCarpenter commented Nov 22, 2018

Configuration:

  • Web browser and its version: all versions of Firefox since PDF.js was included (5+ years)
  • Operating system and its version: all
  • PDF.js version: all
  • Is a browser extension: n/a

Steps to reproduce the problem:

  1. https://bugzilla.mozilla.org/show_bug.cgi?id=911444

What is the expected behaviour?
That the PDF can print as in every other browser than Firefox

What went wrong?
Error: Permission denied to access property 'print'

Please fix this as the go to universal print solution of PDF in browser has been broken for 5 years in Firefox since pdf.js was included in Firefox.

The web developer community has hundreds of bad solutions to this, because of a single project, pdf.js.

@dotnetCarpenter
Copy link
Author

Similar to #5397, but it does not matter if you use an iframe or not.

@dotnetCarpenter dotnetCarpenter changed the title or: Permission denied to access property 'print' Error: Permission denied to access property 'print' Nov 22, 2018
@dotnetCarpenter
Copy link
Author

Same issue if using <object>

<object type="application/pdf"
    data="/media/examples/In-CC0.pdf"
    width="250"
    height="200">
</object>

@Snuffleupagus
Copy link
Collaborator

Steps to reproduce the problem:

1. https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c53

Why open a duplicate issue here, when this is clearly already tracked in Bugzilla!?
Especially since this isn't even a bug in the (general) PDF.js library itself, but rather a limitation in the Firefox browser (as outlined in the linked bug, and a fix would thus not happen in this repository anyway).

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Nov 22, 2018

@Snuffleupagus Because the Firefox bug was reported 5 years ago and the root cause is pdf.js and not Firefox. No Firefox developer has touch this and I have bump into this issue multiple times and it can only be solved by changing pdf.js not Firefox.

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Nov 22, 2018

To clarify, the way pdf.js works is that the normal (15+ years) of printing a document, print(), in this case a PDF, is throwing an error when pdf.js is used, which is the default way of showing a PDF in Firefox for the past 5 years.

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Nov 22, 2018

I might be wrong that the error is really how pdf.js is embedded into Firefox. But I assume that pdf.js could more easily listen for print() and use its internal logic to print the PDF document.

@dotnetCarpenter
Copy link
Author

window.onbeforeprint = function() {
    console.log('This will be called before the user prints.');
};
window.onafterprint = function() {
    console.log('This will be called after the user prints');   
};

Should work since Firefox 6

@dotnetCarpenter
Copy link
Author

window.matchMedia('print') will probably not work since bug https://bugzilla.mozilla.org/show_bug.cgi?id=774398 is not marked as fixed or resolved.

@automatedbugreportingfacility

This is a duplicate of #5397 -- the root cause of the problem is that pdf.js is embedded into a document with a "resource://pdf.js" security principal. It's different from the embedding principal, so the same-origin policy blocks access to print and other properties. It doesn't matter if it's embedded in an iframe or an object.

@dotnetCarpenter
Copy link
Author

@Snuffleupagus is the web folder part of the pdf.js bundle that's embedded in Firefox?
The only printing logic I have found is in https://github.com/mozilla/pdf.js/blob/master/web/firefox_print_service.js

@dotnetCarpenter
Copy link
Author

The main issue with #5397 is that it's half about printing when using pdf.js and half about how to print a document in Firefox when pdf.js is rendering the document, as in this ticket. @automatedbugreportingfacility you're right but I felt this requires a fresh issue since #5397 is mudding the waters.

@dotnetCarpenter
Copy link
Author

Changing the URI should happen in https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c53 but in lieu of a fix in Firefox (haven't happen in 5 years), a work around would be to listen for the beforeprint event and start printing via pdf.js. If the beforeprint is blocked by Firefox, due to same-origin security policy, then it can only happen in Firefox.
Perhaps one of you can clarify the matter?

@automatedbugreportingfacility

a work around would be to listen for the beforeprint event and start printing via pdf.js.

Can you clarify? For the beforeprint event to be sent to an embedded pdf.js document, you need to invoke print() in the context of a parent window. The browser will then print the contents of the parent window. You can't "start printing" in the event handler, because it had already started printing the parent document.

A potential workaround on the pdf.js side would be to implement an onmessage handler to allow printing through pdfWindow.postMessage("print");, but I'm not sure if it's a desired solution.

@dotnetCarpenter
Copy link
Author

A potential workaround on the pdf.js side would be to implement an onmessage handler to allow printing through pdfWindow.postMessage("print");, but I'm not sure if it's a desired solution.

@automatedbugreportingfacility uf, no that is not desirable at all. The perfect solution would be to have DOM API parity with all other browsers, where you can use .print() on the PDF document container.

I didn't create this issue because I use pdf.js but because Firefox uses pdf.js and print() hasn't worked since pdf.js became the standard for rendering PDF's in Firefox.

I will be happy if this gets fixed in Firefox and not pdf.js or the other way around - either way I'll be happy 😃

@Snuffleupagus
Copy link
Collaborator

[...] then it can only happen in Firefox.
Perhaps one of you can clarify the matter?

I already state in #10290 (comment) that it's not relevant to this repository, and #10290 (comment) outlines (in some detail) why that is. Again, please note that it's not necessary/desirable to have duplicate issues open.

@automatedbugreportingfacility

In order to even touch .print without a security error being thrown, a fix is needed for the resource://pdf.js situation I described above, and this would be done in Firefox. We can close this issue since there's no pdf.js work to do here, and the upstream bug is mirrored in #5397.

@dotnetCarpenter
Copy link
Author

@Snuffleupagus and @automatedbugreportingfacility just to be sure I understand what you are saying.

There is no way to create a work-around Firefox security policy in pdf.js, when print() is called. Hence print() will always throw in Firefox because of how pdf.js is embedded in Firefox.

Is the above correct?

@automatedbugreportingfacility

Yes, you can't punch a hole in the browser's security mechanisms. Embedding pdf.js in a semi-privileged document was a big mistake in the first place, but there's no going back, and Mozilla sadly prefers spending money on ephemeral things like "Project Mortar". But I digress.

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Nov 23, 2018

The Mortar experiment has concluded. Mozilla does not consider the PDF use case justifies the burden of implementing and maintaining PDFium and a Pepper API implementation in Gecko.

Well at least Motar is discontinued.

This issue could definitely be closed but before I (you) do, since I got 2 pdf.js experts here, I have two questions that possibly could help https://bugzilla.mozilla.org/show_bug.cgi?id=911444 along in the right direction.

  1. How should pdf.js be embedded in Firefox, if not as a special document (resource:// protocol)?
  2. What is the paper print layout when Firefox prints pdf.js, toolbars etc?

@dotnetCarpenter
Copy link
Author

Embedding pdf.js in a semi-privileged document was a big mistake in the first place, but there's no going back

@automatedbugreportingfacility Why is this decision irreversible?

Couldn't you just create a new blank document with pdf.js and the same origin as the parent window and feed the PDF file to pdf.js?

<iframe id="pdf" src="some-same-origin.pdf"></iframe>
<script>
  document.getElementById('pdf').print()
</script>

Bonus points, if pdf.js listen for beforeprint, cancel the event and print the <canvas> (PDF document) and not letting FIrefox print the pdf.js UI.

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Nov 23, 2018

I imagine, if pdf.js was embedded as a regular document, you would able to listen to the parent window.

window.opener.addEventListener('beforeprint', event => {
  event.preventDefault()

  window.print() // pdf.js overrides the native print function already
})

Or change pdf.js to:

let print = (window.opener || window).print;
window.print = function print() {
  if (activeService) {
    console.warn('Ignored window.print() because of a pending print job.');
    return;
  }
  ...

On second thought, this would mean that pdf.js would swallow prints from the parent which is not what we want.

@dotnetCarpenter
Copy link
Author

Actually pdf.js is already doing the right thing. We just need firefox to dispatch print() on the document that embeds pdf.js.

@dotnetCarpenter
Copy link
Author

Excerpt from pdf_print_service.js (found on https://mozilla.github.io/pdf.js/web/viewer.html):

let print = window.print;
window.print = function print() {
  if (activeService) {
    console.warn('Ignored window.print() because of a pending print job.');
    return;
  }
  ensureOverlay().then(function() {
    if (activeService) {
      overlayManager.open('printServiceOverlay');
    }
  });

  try {
    dispatchEvent('beforeprint');
  } finally {
    if (!activeService) {
      console.error('Expected print service to be initialized.');
      ensureOverlay().then(function() {
        if (overlayManager.active === 'printServiceOverlay') {
          overlayManager.close('printServiceOverlay');
        }
      });
      return; // eslint-disable-line no-unsafe-finally
    }
    let activeServiceOnEntry = activeService;
    activeService.renderPages().then(function() {
      return activeServiceOnEntry.performPrint();
    }).catch(function() {
      // Ignore any error messages.
    }).then(function() {
      // aborts acts on the "active" print request, so we need to check
      // whether the print request (activeServiceOnEntry) is still active.
      // Without the check, an unrelated print request (created after aborting
      // this print request while the pages were being generated) would be
      // aborted.
      if (activeServiceOnEntry.active) {
        abort();
      }
    });
  }
};

function dispatchEvent(eventType) {
  let event = document.createEvent('CustomEvent');
  event.initCustomEvent(eventType, false, false, 'custom');
  window.dispatchEvent(event);
}

function abort() {
  if (activeService) {
    activeService.destroy();
    dispatchEvent('afterprint');
  }
}

@dotnetCarpenter
Copy link
Author

@Ugoku and @jtraulle Please vote on https://bugzilla.mozilla.org/show_bug.cgi?id=911444 to get it on the radar for Firefox developers.

@jtraulle
Copy link

Thanks @dotnetCarpenter, I have voted on Bugzilla 🐞

@meenvenenaronelgato
Copy link

Had the same issue using firefox. Solved it including the pdf into an iframe like this (the key is the way the pdf is linked):

`$(".div_class").html('<iframe id="frame_id"></iframe>');
$('#frame_id')
.attr("src", "path_to/PDFJS/web/viewer.html?file=path_to/file.pdf")
.on("load", function(){
setTimeout(printWhenReady, 3000);
});
}

function printWhenReady(){
document.getElementById(frame_id).contentWindow.print();
}`

@Snuffleupagus
Copy link
Collaborator

Why was this re-opened, when it's been stated repeatedly that it's a duplicate of https://bugzilla.mozilla.org/show_bug.cgi?id=911444 and not something that can be fixed in this repository!?

@timvandermeij Can you please close this issue?

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Jan 8, 2019 via email

@shmilyoo
Copy link

Had the same issue using firefox. Solved it including the pdf into an iframe like this (the key is the way the pdf is linked):

`$(".div_class").html('<iframe id="frame_id"></iframe>');
$('#frame_id')
.attr("src", "path_to/PDFJS/web/viewer.html?file=path_to/file.pdf")
.on("load", function(){
setTimeout(printWhenReady, 3000);
});
}

function printWhenReady(){
document.getElementById(frame_id).contentWindow.print();
}`

no, still SecurityError: Permission denied to access property "print" on cross-origin object error in firefox console

@didagu
Copy link

didagu commented Sep 11, 2019

Had the same issue using firefox. Solved it including the pdf into an iframe like this (the key is the way the pdf is linked):
$(".div_class").html('<iframe id="frame_id"></iframe>'); $('#frame_id') .attr("src", "path_to/PDFJS/web/viewer.html?file=path_to/file.pdf") .on("load", function(){ setTimeout(printWhenReady, 3000); }); } function printWhenReady(){ document.getElementById(frame_id).contentWindow.print(); }

no, still SecurityError: Permission denied to access property "print" on cross-origin object error in firefox console

@shmilyoo Please how did you get the path to PDFjs ??

@vaspervnp
Copy link

vaspervnp commented Sep 24, 2019

The problem is the viewer. The embedded viewer causes the cross-origin problem. Try creating your own viewer. That will solve the problem. e.g. from here: https://pspdfkit.com/blog/2019/implement-pdf-viewer-pdf-js/

Or if you need a full featured viewer, you can use the Mozilla one from here: http://mozilla.github.io/pdf.js/web/viewer.html (for this one you will need to download the latest pdf.js and pdf.worker.js implementation). I just did that for a project at work, and it works like a charm.

@didagu
Copy link

didagu commented Sep 25, 2019

@vaspervnp If I may ask, were you able to programmatically call the print function ?

@dotnetCarpenter
Copy link
Author

dotnetCarpenter commented Oct 9, 2019

@vaspervnp The irony is that, that is the exact same Mozilla viewer embedded in Firefox!

We really need someone to change how pdf.js is embedded in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=911444#c58

@vaspervnp
Copy link

@vaspervnp If I may ask, were you able to programmatically call the print function ?

Yes, I was.

@didagu
Copy link

didagu commented Oct 12, 2019

@vaspervnp it will be nice if you could provide a little code snippet on how you did that.

@vaspervnp
Copy link

vaspervnp commented Dec 6, 2019

@didagu
I didn't write any additional code. I just included the javascript and the viewer from here: http://mozilla.github.io/pdf.js/web/viewer.html Then, when using the viewer the way the embeded one is used, it just worked.

@mdodge-ecgrow
Copy link

Do you need special privileges to vote on bugzilla? I don't see that option anywhere.

@dotnetCarpenter
Copy link
Author

@mdodge-ecgrow looks like bugzilla removed the voting feature when they made the re-design. I'm not sure how we´re suppose to get firefox developers attention now...

@adamt-ci
Copy link

adamt-ci commented Feb 6, 2020

@dotnetCarpenter the icing on the cake is that, over a year ago, one of the developers complained that all of the +1 comments make it harder to see the technical discussion and therefore harder to resolve the bug. As if that's why it's been open for over 6 years and counting. Without the voting system, such comments are now the ONLY way to call attention to an issue, so I see no alternative.

@swistak
Copy link

swistak commented Mar 2, 2021

Stumbled upon this bug because that issue still persists to this day. You have to use setTimeout inside onload to have a chance of the print working, and that chance is only a recent development.

Unfortunately it's one of those things that means I can't use Firefox in my workplace. If I can't use Firefox, there's no testing for Firefox, because why waste time and money when we only target Chrome (because that's where it works).

So even if this issue is fixed eventually, my company will probably not ever switch back to Firefox, because "It works in Chrome".

This issue is both regression and parity issue, and it was not fixed for 6 years now. Firefox keeps loosing market share and they wonder why.

@dotnetCarpenter
Copy link
Author

@swistak The good news is that this bug was fixed 1 month ago and will be in the next stable version of Firefox!

Firefox 87 should be release on 2021-03-23 - in just 13 days. You can download Firefox Developer Edition and begin testing at your work place now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests