Re-factor the blob-URL caching in DownloadManager.openOrDownloadData
Cache blob-URLs on the actual data, rather than DOM elements, to reduce potential duplicates (note the updated unit-test).
This commit is contained in:
parent
22d6d95f03
commit
674052d3fc
@ -806,7 +806,6 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
link.href = this.linkService.getAnchorUrl("");
|
link.href = this.linkService.getAnchorUrl("");
|
||||||
link.onclick = () => {
|
link.onclick = () => {
|
||||||
this.downloadManager?.openOrDownloadData(
|
this.downloadManager?.openOrDownloadData(
|
||||||
this.container,
|
|
||||||
attachment.content,
|
attachment.content,
|
||||||
attachment.filename,
|
attachment.filename,
|
||||||
dest
|
dest
|
||||||
@ -2861,11 +2860,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
|
|||||||
* Download the file attachment associated with this annotation.
|
* Download the file attachment associated with this annotation.
|
||||||
*/
|
*/
|
||||||
#download() {
|
#download() {
|
||||||
this.downloadManager?.openOrDownloadData(
|
this.downloadManager?.openOrDownloadData(this.content, this.filename);
|
||||||
this.container,
|
|
||||||
this.content,
|
|
||||||
this.filename
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2883,6 +2883,11 @@ describe("api", function () {
|
|||||||
|
|
||||||
expect(attachmentDest).toEqual('[0,{"name":"Fit"}]');
|
expect(attachmentDest).toEqual('[0,{"name":"Fit"}]');
|
||||||
|
|
||||||
|
// Check that the attachments, which are identical, aren't duplicated.
|
||||||
|
for (let i = 1, ii = annotations.length; i < ii; i++) {
|
||||||
|
expect(annotations[i].attachment).toBe(attachment);
|
||||||
|
}
|
||||||
|
|
||||||
await loadingTask.destroy();
|
await loadingTask.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class DownloadManager {
|
|||||||
/**
|
/**
|
||||||
* @returns {boolean} Indicating if the data was opened.
|
* @returns {boolean} Indicating if the data was opened.
|
||||||
*/
|
*/
|
||||||
openOrDownloadData(element, data, filename, dest = null) {
|
openOrDownloadData(data, filename, dest = null) {
|
||||||
const isPdfData = isPdfFile(filename);
|
const isPdfData = isPdfFile(filename);
|
||||||
const contentType = isPdfData ? "application/pdf" : "";
|
const contentType = isPdfData ? "application/pdf" : "";
|
||||||
|
|
||||||
@ -75,10 +75,10 @@ class DownloadManager {
|
|||||||
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("COMPONENTS")) &&
|
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("COMPONENTS")) &&
|
||||||
isPdfData
|
isPdfData
|
||||||
) {
|
) {
|
||||||
let blobUrl = this.#openBlobUrls.get(element);
|
let blobUrl = this.#openBlobUrls.get(data);
|
||||||
if (!blobUrl) {
|
if (!blobUrl) {
|
||||||
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
|
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
|
||||||
this.#openBlobUrls.set(element, blobUrl);
|
this.#openBlobUrls.set(data, blobUrl);
|
||||||
}
|
}
|
||||||
let viewerUrl;
|
let viewerUrl;
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||||
@ -105,7 +105,7 @@ class DownloadManager {
|
|||||||
// Release the `blobUrl`, since opening it failed, and fallback to
|
// Release the `blobUrl`, since opening it failed, and fallback to
|
||||||
// downloading the PDF file.
|
// downloading the PDF file.
|
||||||
URL.revokeObjectURL(blobUrl);
|
URL.revokeObjectURL(blobUrl);
|
||||||
this.#openBlobUrls.delete(element);
|
this.#openBlobUrls.delete(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,15 +132,15 @@ class DownloadManager {
|
|||||||
/**
|
/**
|
||||||
* @returns {boolean} Indicating if the data was opened.
|
* @returns {boolean} Indicating if the data was opened.
|
||||||
*/
|
*/
|
||||||
openOrDownloadData(element, data, filename, dest = null) {
|
openOrDownloadData(data, filename, dest = null) {
|
||||||
const isPdfData = isPdfFile(filename);
|
const isPdfData = isPdfFile(filename);
|
||||||
const contentType = isPdfData ? "application/pdf" : "";
|
const contentType = isPdfData ? "application/pdf" : "";
|
||||||
|
|
||||||
if (isPdfData) {
|
if (isPdfData) {
|
||||||
let blobUrl = this.#openBlobUrls.get(element);
|
let blobUrl = this.#openBlobUrls.get(data);
|
||||||
if (!blobUrl) {
|
if (!blobUrl) {
|
||||||
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
|
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
|
||||||
this.#openBlobUrls.set(element, blobUrl);
|
this.#openBlobUrls.set(data, blobUrl);
|
||||||
}
|
}
|
||||||
// Let Firefox's content handler catch the URL and display the PDF.
|
// Let Firefox's content handler catch the URL and display the PDF.
|
||||||
let viewerUrl = blobUrl + "?filename=" + encodeURIComponent(filename);
|
let viewerUrl = blobUrl + "?filename=" + encodeURIComponent(filename);
|
||||||
@ -156,7 +156,7 @@ class DownloadManager {
|
|||||||
// Release the `blobUrl`, since opening it failed, and fallback to
|
// Release the `blobUrl`, since opening it failed, and fallback to
|
||||||
// downloading the PDF file.
|
// downloading the PDF file.
|
||||||
URL.revokeObjectURL(blobUrl);
|
URL.revokeObjectURL(blobUrl);
|
||||||
this.#openBlobUrls.delete(element);
|
this.#openBlobUrls.delete(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,12 +158,12 @@ class IDownloadManager {
|
|||||||
downloadData(data, filename, contentType) {}
|
downloadData(data, filename, contentType) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {HTMLElement} element
|
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {string} filename
|
* @param {string} filename
|
||||||
|
* @param {string | null} [dest]
|
||||||
* @returns {boolean} Indicating if the data was opened.
|
* @returns {boolean} Indicating if the data was opened.
|
||||||
*/
|
*/
|
||||||
openOrDownloadData(element, data, filename) {}
|
openOrDownloadData(data, filename, dest = null) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Blob} blob
|
* @param {Blob} blob
|
||||||
|
@ -91,7 +91,7 @@ class PDFAttachmentViewer extends BaseTreeViewer {
|
|||||||
*/
|
*/
|
||||||
_bindLink(element, { content, filename }) {
|
_bindLink(element, { content, filename }) {
|
||||||
element.onclick = () => {
|
element.onclick = () => {
|
||||||
this.downloadManager.openOrDownloadData(element, content, filename);
|
this.downloadManager.openOrDownloadData(content, filename);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,6 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
|||||||
element.href = linkService.getAnchorUrl("");
|
element.href = linkService.getAnchorUrl("");
|
||||||
element.onclick = () => {
|
element.onclick = () => {
|
||||||
this.downloadManager.openOrDownloadData(
|
this.downloadManager.openOrDownloadData(
|
||||||
element,
|
|
||||||
attachment.content,
|
attachment.content,
|
||||||
attachment.filename
|
attachment.filename
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user