Move the opening of PDF file attachments into the DownloadManager-implementations

Note how the `PDFAttachmentViewer` handles PDF file attachments specially, by opening them in a new window/tab, rather than forcing them to be downloaded. This is done to improve the overall UX, since browsers in general are able to handle PDF files internally.
However, for file *annotations* we're currently not attempting to do the same thing and are instead just downloading them directly. In order to unify the behaviour, without having to duplicate a lot of code, the opening of PDF file attachments is thus moved into a new `DownloadManager.openOrDownloadData` method.
This commit is contained in:
Jonas Jenwald 2021-02-23 12:58:17 +01:00
parent fafe039849
commit df931ef685
5 changed files with 97 additions and 61 deletions

View file

@ -14,6 +14,7 @@
*/
import { createObjectURL, createValidAbsoluteUrl } from "pdfjs-lib";
import { PdfFileRegExp } from "./ui_utils.js";
import { viewerCompatibilityParams } from "./viewer_compatibility.js";
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("CHROME || GENERIC")) {
@ -43,6 +44,10 @@ function download(blobUrl, filename) {
}
class DownloadManager {
constructor() {
this._openBlobUrls = new WeakMap();
}
downloadUrl(url, filename) {
if (!createValidAbsoluteUrl(url, "http://example.com")) {
return; // restricted/invalid URL
@ -59,6 +64,49 @@ class DownloadManager {
download(blobUrl, filename);
}
/**
* @returns {boolean} Indicating if the data was opened.
*/
openOrDownloadData(element, data, filename) {
const isPdfFile = PdfFileRegExp.test(filename);
const contentType = isPdfFile ? "application/pdf" : "";
if (isPdfFile && !viewerCompatibilityParams.disableCreateObjectURL) {
let blobUrl = this._openBlobUrls.get(element);
if (!blobUrl) {
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
this._openBlobUrls.set(element, blobUrl);
}
let viewerUrl;
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
// The current URL is the viewer, let's use it and append the file.
viewerUrl = "?file=" + encodeURIComponent(blobUrl + "#" + filename);
} else if (PDFJSDev.test("CHROME")) {
// In the Chrome extension, the URL is rewritten using the history API
// in viewer.js, so an absolute URL must be generated.
viewerUrl =
// eslint-disable-next-line no-undef
chrome.runtime.getURL("/content/web/viewer.html") +
"?file=" +
encodeURIComponent(blobUrl + "#" + filename);
}
try {
window.open(viewerUrl);
return true;
} catch (ex) {
console.error(`openOrDownloadData: ${ex}`);
// Release the `blobUrl`, since opening it failed, and fallback to
// downloading the PDF file.
URL.revokeObjectURL(blobUrl);
this._openBlobUrls.delete(element);
}
}
this.downloadData(data, filename, contentType);
return false;
}
/**
* @param sourceEventType {string} Used to signal what triggered the download.
* The version of PDF.js integrated with Firefox uses this to to determine