mozilla / pdf.js

PDF Reader in JavaScript
https://mozilla.github.io/pdf.js/
Apache License 2.0
48.78k stars 10.03k forks source link

PDF Viewer extension does not detect PDFs in objecturls #11788

Open SzDavidHUN opened 4 years ago

SzDavidHUN commented 4 years ago

Issue template: Attach (recommended) or Link to PDF file here: Any PDF will do it, that can be properly openend with PDFjs. Anyway, there's one: https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf

Configuration:

Steps to reproduce the problem: Open any PDF in objecturl. One of many ways to reproduce

  1. Open this JSFiddle: http://jsfiddle.net/SzDavidHUN/qg6zud4p/1/
  2. Upload PDF
  3. Copy the bloburl, open it in a new tab.

What is the expected behavior? PDF is opened by PDF Viewer extension.

What went wrong? PDF is opened by the built in PDF viewer of Google Chrome

Link to a viewer (if hosted on a site other than mozilla.github.io/pdf.js or as Firefox/Chrome extension):

Somewhat helpful story about the issue: I've installed the PDF Viewer extension to Google Chrome. Our company have an application, that shows PDF files: it downloads the PDF, creates an object url and creates an iframe for it. The problem is, that the extension does not detects it as a PDF File, so the default PDF viewer opens it. As a workaround I can force it pasting the address of the extension before the object url, but then it breaks for those users, who does not have it installed. I can't even show a warning for it, since I can't detect that the user have it installed or not.

timvandermeij commented 4 years ago

/cc @Rob--W since he may have ideas for this.

Rob--W commented 4 years ago

It is a limitation of Chrome that extensions cannot intercept blob:-URLs, nor run content scripts in them:

There is a possible work-around. Another similar scheme, filesystem: is not subject to this limitation. This scheme is part of the deprecated, Chrome-only Filesystem API. Although deprecated for many years, it is still around. The currently published PDF viewer is able to run content scripts in it, but it does not intercept the request because I didn't account for it. However, I can publish an update if you believe that it serves a purpose.

Here is a code snippet that shows how it could be used (with fallback to blob:-URL):

function getUrlForBlob(blob, callback) {
  function fallback() {
    callback(URL.createObjectURL(blob));
  }
  var requestFileSystem = window.webkitRequestFileSystem;
  if (!requestFileSystem) {
    return fallback();
  }
  // second param = size, seems to be ignored by Chrome, so just use 0.
  requestFileSystem(window.TEMPORARY, 0, function(fs) {
    fs.root.getFile("temp.pdf", {create:true}, function(entry) {
      entry.createWriter(function(writer) {
        writer.onwriteend = function() {
          callback(entry.toURL());
        };
        writer.onerror = fallback;
        writer.write(blob);
      }, fallback);
    }, fallback);
  }, fallback);
}

Demo: http://jsfiddle.net/7a8grdcp/

@SzDavidHUN Does this look like something that you are willing to use? Should I publish a new version of the extension that detects and displays PDFs from filesystem:-URLs?

SzDavidHUN commented 4 years ago

That sounds like an okay solution for me, it would be great if you published a new version like that.

Rob--W commented 4 years ago

@SzDavidHUN Just to confirm before I do a load of work: would you use the Filesystem API to obtain a filesystem:-URL instead of a blob:-URLs if I published an update of the extension that recognized filesystem:-URLs?

SzDavidHUN commented 4 years ago

@Rob--W I'm sure I would use it! I talked with one of the reviewer colleagues, and he's fine with it, but if you'd like, I can the other too to be extra sure. Only thing is, that there is a few holidays around the weekend, so the answer might take a few days.

SzDavidHUN commented 4 years ago

Sorry for late replying. I'm happy to say. that there's absolutely no roadblock for me to use your recommended solution, so once it gets implemented it will be definitely used by us/me.

Thanks in advance!