pdf.js.mirror/web/base_download_manager.js
Jonas Jenwald 6323afab46 Convert the PDFObjects class to use a Map internally
This patch also adds unconditional `Map.prototype.getOrInsertComputed()` usage, which should be fine since it's [supported in the latest browsers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/getOrInsertComputed#browser_compatibility) and it'll be polyfilled (via core-js) in the `legacy` builds.
2026-02-17 09:42:27 +01:00

103 lines
2.8 KiB
JavaScript

/* Copyright 2013 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { isPdfFile } from "pdfjs-lib";
class BaseDownloadManager {
#openBlobUrls = new WeakMap();
constructor() {
if (
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
this.constructor === BaseDownloadManager
) {
throw new Error("Cannot initialize BaseDownloadManager.");
}
}
_triggerDownload(blobUrl, originalUrl, filename, isAttachment = false) {
throw new Error("Not implemented: _triggerDownload");
}
_getOpenDataUrl(blobUrl, filename, dest = null) {
throw new Error("Not implemented: _getOpenDataUrl");
}
/**
* @param {Uint8Array} data
* @param {string} filename
* @param {string} [contentType]
*/
downloadData(data, filename, contentType) {
const blobUrl = URL.createObjectURL(
new Blob([data], { type: contentType })
);
this._triggerDownload(
blobUrl,
/* originalUrl = */ blobUrl,
filename,
/* isAttachment = */ true
);
}
/**
* @param {Uint8Array} data
* @param {string} filename
* @param {string | null} [dest]
* @returns {boolean} Indicating if the data was opened.
*/
openOrDownloadData(data, filename, dest = null) {
const isPdfData = isPdfFile(filename);
const contentType = isPdfData ? "application/pdf" : "";
if (isPdfData) {
const blobUrl = this.#openBlobUrls.getOrInsertComputed(data, () =>
URL.createObjectURL(new Blob([data], { type: contentType }))
);
try {
const viewerUrl = this._getOpenDataUrl(blobUrl, filename, dest);
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(data);
}
}
this.downloadData(data, filename, contentType);
return false;
}
/**
* @param {Uint8Array} data
* @param {string} url
* @param {string} filename
*/
download(data, url, filename) {
const blobUrl = data
? URL.createObjectURL(new Blob([data], { type: "application/pdf" }))
: null;
this._triggerDownload(blobUrl, /* originalUrl = */ url, filename);
}
}
export { BaseDownloadManager };