1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-19 06:38:07 +02:00

Merge pull request #19632 from Snuffleupagus/issue-15085

[api-minor] Attempt to support fetching the raw data of the PDF document from the `PDFDocumentLoadingTask`-instance (issue 15085)
This commit is contained in:
Tim van der Meij 2025-03-16 12:32:20 +01:00 committed by GitHub
commit d86045eacb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 92 additions and 30 deletions

View file

@ -629,39 +629,48 @@ const isValidExplicitDest = _isValidExplicitDest.bind(
class PDFDocumentLoadingTask {
static #docId = 0;
constructor() {
this._capability = Promise.withResolvers();
this._transport = null;
this._worker = null;
/**
* @private
*/
_capability = Promise.withResolvers();
/**
* Unique identifier for the document loading task.
* @type {string}
*/
this.docId = `d${PDFDocumentLoadingTask.#docId++}`;
/**
* @private
*/
_transport = null;
/**
* Whether the loading task is destroyed or not.
* @type {boolean}
*/
this.destroyed = false;
/**
* @private
*/
_worker = null;
/**
* Callback to request a password if a wrong or no password was provided.
* The callback receives two parameters: a function that should be called
* with the new password, and a reason (see {@link PasswordResponses}).
* @type {function}
*/
this.onPassword = null;
/**
* Unique identifier for the document loading task.
* @type {string}
*/
docId = `d${PDFDocumentLoadingTask.#docId++}`;
/**
* Callback to be able to monitor the loading progress of the PDF file
* (necessary to implement e.g. a loading bar).
* The callback receives an {@link OnProgressParameters} argument.
* @type {function}
*/
this.onProgress = null;
}
/**
* Whether the loading task is destroyed or not.
* @type {boolean}
*/
destroyed = false;
/**
* Callback to request a password if a wrong or no password was provided.
* The callback receives two parameters: a function that should be called
* with the new password, and a reason (see {@link PasswordResponses}).
* @type {function}
*/
onPassword = null;
/**
* Callback to be able to monitor the loading progress of the PDF file
* (necessary to implement e.g. a loading bar).
* The callback receives an {@link OnProgressParameters} argument.
* @type {function}
*/
onProgress = null;
/**
* Promise for document loading task completion.
@ -699,6 +708,16 @@ class PDFDocumentLoadingTask {
this._worker?.destroy();
this._worker = null;
}
/**
* Attempt to fetch the raw data of the PDF document, when e.g.
* - An exception was thrown during document initialization.
* - An `onPassword` callback is delaying initialization.
* @returns {Promise<Uint8Array>}
*/
async getData() {
return this._transport.getData();
}
}
/**

View file

@ -828,6 +828,47 @@ describe("api", function () {
await loadingTask.destroy();
});
it("gets data, on failure, from `PDFDocumentLoadingTask`-instance", async function () {
const typedArrayPdf = await DefaultFileReaderFactory.fetch({
path: TEST_PDFS_PATH + "issue6010_1.pdf",
});
// Sanity check to make sure that we fetched the entire PDF file.
expect(typedArrayPdf instanceof Uint8Array).toEqual(true);
expect(typedArrayPdf.length).toEqual(1116);
const loadingTask = getDocument(typedArrayPdf.slice());
expect(loadingTask instanceof PDFDocumentLoadingTask).toEqual(true);
let passwordData = null;
// Attach the callback that is used to request a password;
// similarly to how the default viewer handles passwords.
loadingTask.onPassword = async (updatePassword, reason) => {
passwordData = await loadingTask.getData();
updatePassword(new Error("Should reject the loadingTask."));
};
try {
await loadingTask.promise;
// Shouldn't get here.
expect(false).toEqual(true);
} catch (ex) {
expect(ex instanceof PasswordException).toEqual(true);
expect(ex.code).toEqual(PasswordResponses.NEED_PASSWORD);
}
// Ensure that the raw PDF document can be fetched while
// an `onPassword` callback is delaying initialization...
expect(passwordData).toEqual(typedArrayPdf);
// ... and once an exception has stopped initialization.
const data = await loadingTask.getData();
expect(data).toEqual(typedArrayPdf);
await loadingTask.destroy();
});
});
describe("PDFWorker", function () {

View file

@ -1153,7 +1153,9 @@ const PDFViewerApplication = {
async download() {
let data;
try {
data = await this.pdfDocument.getData();
data = await (this.pdfDocument
? this.pdfDocument.getData()
: this.pdfLoadingTask.getData());
} catch {
// When the PDF document isn't ready, simply download using the URL.
}