crabbly / Print.js

A tiny javascript library to help printing from the web.
MIT License
4.32k stars 673 forks source link

[Identified Bug][PDF display from blob fails] Invalid absolute docBaseUrl, blank PDF on Firefox aboveOrEqu to 110 #655

Open Kwaadpepper opened 1 year ago

Kwaadpepper commented 1 year ago

Just opened a ticket on mozilla side since it affects developpeur edition only seems to. For anyone landing on this. https://bugzilla.mozilla.org/show_bug.cgi?id=1814029

larminen commented 1 year ago

Same behaviour also in latest non-developer version as well.

amoilanen commented 1 year ago

@Kwaadpepper @larminen

I tried debugging the Print.js locally and it seems that:

  1. It looks like this might not be a Firefox bug , but rather a Print.js bug
  2. The issue seems not to be related to the warnings printed in the console

Despite the warnings printed in the console in the test page printing

Warning: Invalid absolute docBaseUrl: "blob:http://localhost:8080/047308fc-b24a-44e0-9ce9-f9852f978320". pdf.worker.js:973:13
Warning: Bad value, for custom key "AAPL:Keywords", in Info: . pdf.worker.js:973:13
PDF 8eed11de459c2ed35fec410bf057a870 [1.3 Mac OS X 10.11.4 Quartz PDFContext / Word] (PDF.js: 3.3.56 [1e938a688]) viewer.js:2275:13

Screenshot_20230217_232639

the pdf was sometimes printed when I paused for debugging and then resumed execution, so in principle Firefox 110 is able to render the pdf and print it.

Whenever I set a breakpoint on https://github.com/crabbly/Print.js/blob/6502c73c7e1ba87346fe4913fa5de6220936095b/src/js/print.js#L66 and stop and resume immediately when printing, then PDF is printed successfully in Firefox 110

I also found the following snippet where we wait for Firefox to print the pdf:

https://github.com/crabbly/Print.js/blob/6502c73c7e1ba87346fe4913fa5de6220936095b/src/js/print.js#L16-L18

So most likely the issue is that for some reason Firefox does not manage to render the iframe fully before we print the iframe's contentWindow with performPrint https://github.com/crabbly/Print.js/blob/6502c73c7e1ba87346fe4913fa5de6220936095b/src/js/print.js#L66

I then tried increasing the timeout to 2000 or 5000, but this did not help, pdf is still a blank page.

amoilanen commented 1 year ago

@Kwaadpepper @larminen

I guess the fix might be to allow the Firefox to render the iframe with the content we are about to print, but how to do it is a good question, apparently simply increasing the timeout to a larger value of 2000 or 5000 does not help. Will try to research a bit more and maybe @crabbly might be able to look and help here also

mjp89 commented 1 year ago

Seems that this special handling part for Firefox is now broken

https://github.com/crabbly/Print.js/blob/6502c73c7e1ba87346fe4913fa5de6220936095b/src/js/print.js#L71-L75

and commenting it out resolved the issue for Firefox 110.

Kwaadpepper commented 1 year ago

So we could say that this issue is not a bug in Firefox and this fix would be to add a version number check on this if statement as of 110 ?

If this is confirmed I would close the bug thread in Firefox.

amoilanen commented 1 year ago

@mjp89 Good find, confirming for Firefox 110 that the following change fixes the bug and PDF is printed:

diff --git a/src/js/print.js b/src/js/print.js
index e09e69f..deee4ca 100644
--- a/src/js/print.js
+++ b/src/js/print.js
@@ -12,12 +12,7 @@ const Print = {
     // Wait for iframe to load all content
     iframeElement.onload = () => {
       if (params.type === 'pdf') {
-        // Add a delay for Firefox. In my tests, 1000ms was sufficient but 100ms was not
-        if (Browser.isFirefox()) {
-          setTimeout(() => performPrint(iframeElement, params), 1000)
-        } else {
-          performPrint(iframeElement, params)
-        }
+        performPrint(iframeElement, params)
         return
       }

@@ -68,12 +63,6 @@ function performPrint (iframeElement, params) {
   } catch (error) {
     params.onError(error)
   } finally {
-    if (Browser.isFirefox()) {
-      // Move the iframe element off-screen and make it invisible
-      iframeElement.style.visibility = 'hidden'
-      iframeElement.style.left = '-1px'
-    }
-
     cleanUp(params)
   }
 }

The PR/fix for Print.js should probably check the Firefox version in addition to only the browser name, for this we might use, for example https://www.npmjs.com/package/sniffr

@Kwaadpepper Yes, this is not a bug in Firefox but rather in Print.js, the bug thread in Firefox can be closed I think

I can try opening a PR a bit later in the evening but not sure how actively Print.js is currently maintained/whether the PR will be merged @crabbly

amoilanen commented 1 year ago

Opened the PR https://github.com/crabbly/Print.js/pull/657 which should fix the issue

ZakiMohammed commented 1 year ago

Thanks @amoilanen for providing the fix 😺

For time being my team have added below code just for make it runnable:

const isFirefox = () => {
  return typeof InstallTrigger !== 'undefined';
};

const getFirefoxMajorVersion = () => {
  try {
    const userAgent = navigator.userAgent;
    const firefoxVersionRegex = /firefox\/(\S+)/;
    const match = userAgent.toLowerCase().match(firefoxVersionRegex);
    if (match) {
      return match[1].split('.').map(x => parseInt(x))[0];
    }
  } catch {}

  return null;
};

const customPrint = function (url) {
  const iframe = document.createElement('iframe');
  document.body.appendChild(iframe);

  iframe.style.display = 'none';
  iframe.src = url;
  iframe.onload = function () {
    iframe.focus();
    iframe.contentWindow.print();
  };
};

btnDefault.onclick = function () {
  if (isFirefox() && getFirefoxMajorVersion() >= 110) {
    customPrint('assets/file-lg.pdf');
  } else {
    printJS({ printable: 'assets/file-lg.pdf' });
  }
};
amoilanen commented 1 year ago

@crabbly Thank you for reviewing and merging the fix https://github.com/crabbly/Print.js/pull/657, could you, please, also release it to https://www.npmjs.com/package/print-js to enable support for Firefox >=110 ?

crabbly commented 1 year ago

Hi @amoilanen , will post an update here once the new version is up. Thank you 🙏🏻

theRiley commented 1 year ago

Greetings, I ran into this issue today and found this thread. Any update on a this getting bumped into the new version? Thanks so much!

amoilanen commented 1 year ago

@crabbly When possible, could, you, please, release the fix? This might be a "blocker" with the latest Firefox for quite a few users, so your help will be very much appreciated 🙏🏻 Thank you

jerstew commented 1 year ago

I don't mean to be rude in any way -- just checking to see if there is an update or if there's help needed to get this released? I'd happily volunteer time!

cedx commented 1 year ago

A bit off topic, but I'd like to point out that the way Firefox is detected is not sustainable. cf. https://github.com/crabbly/Print.js/blob/master/src/js/browser.js#L3

Why? Because InstallTrigger will be removed in a future version of Firefox. See your DevTools console: image

jerstew commented 1 year ago

Good point. Still hoping we can get an immediate release with the patch/fix, though. Is this project dead?

nigellima commented 1 year ago

Hi @crabbly any chances this gets released?