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 · 28 comments

Comments

Projects
None yet
6 participants
@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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 22, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 22, 2018

Same issue if using <object>

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

This comment has been minimized.

Copy link
Contributor

Snuffleupagus commented Nov 22, 2018

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 22, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 22, 2018

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 comment has been minimized.

Copy link

automatedbugreportingfacility commented Nov 23, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

@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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

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

This comment has been minimized.

Copy link

automatedbugreportingfacility commented Nov 23, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

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

This comment has been minimized.

Copy link
Contributor

Snuffleupagus commented Nov 23, 2018

[...] 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

This comment has been minimized.

Copy link

automatedbugreportingfacility commented Nov 23, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

@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

This comment has been minimized.

Copy link

automatedbugreportingfacility commented Nov 23, 2018

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

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

@dotnetCarpenter

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Nov 23, 2018

@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

This comment has been minimized.

Copy link

jtraulle commented Nov 23, 2018

Thanks @dotnetCarpenter, I have voted on Bugzilla 🐞

@meenvenenaronelgato

This comment has been minimized.

Copy link

meenvenenaronelgato commented Jan 4, 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();
}`

@Snuffleupagus

This comment has been minimized.

Copy link
Contributor

Snuffleupagus commented Jan 8, 2019

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

This comment has been minimized.

Copy link
Author

dotnetCarpenter commented Jan 8, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.