Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add *official* support for passing ArrayBuffer-data to getDocument (issue 15269) #15299

Merged
merged 1 commit into from
Aug 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
* } TypedArray
*/

/**
* @typedef { TypedArray | ArrayBuffer | Array<number> | string } BinaryData
*/

/**
* @typedef {Object} RefProxy
* @property {number} num
Expand All @@ -127,10 +131,10 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
* Document initialization / loading parameters object.
*
* @typedef {Object} DocumentInitParameters
* @property {string|URL} [url] - The URL of the PDF.
* @property {TypedArray|Array<number>|string} [data] - Binary PDF data. Use
* typed arrays (Uint8Array) to improve the memory usage. If PDF data is
* BASE64-encoded, use `atob()` to convert it to a binary string first.
* @property {string | URL} [url] - The URL of the PDF.
* @property {BinaryData} [data] - Binary PDF data.
* Use typed arrays (Uint8Array) to improve the memory usage. If PDF data is
* BASE64-encoded, use `atob()` to convert it to a binary string first.
* @property {Object} [httpHeaders] - Basic authentication headers.
* @property {boolean} [withCredentials] - Indicates whether or not
* cross-site Access-Control requests should be made using credentials such
Expand Down Expand Up @@ -217,14 +221,20 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
* (see `web/debugger.js`). The default value is `false`.
*/

/**
* @typedef { string | URL | TypedArray | ArrayBuffer |
* PDFDataRangeTransport | DocumentInitParameters
* } GetDocumentParameters
*/

/**
* This is the main entry point for loading a PDF and interacting with it.
*
* NOTE: If a URL is used to fetch the PDF data a standard Fetch API call (or
* XHR as fallback) is used, which means it must follow same origin rules,
* e.g. no cross-domain requests without CORS.
*
* @param {string|URL|TypedArray|PDFDataRangeTransport|DocumentInitParameters}
* @param {GetDocumentParameters}
* src - Can be a URL where a PDF file is located, a typed array (Uint8Array)
* already populated with data, or a parameter object.
* @returns {PDFDocumentLoadingTask}
Expand All @@ -243,7 +253,7 @@ function getDocument(src) {
if (typeof src !== "object") {
throw new Error(
"Invalid parameter in getDocument, " +
"need either string, URL, Uint8Array, or parameter object."
"need either string, URL, TypedArray, or parameter object."
);
}
if (!src.url && !src.data && !src.range) {
Expand Down Expand Up @@ -308,7 +318,7 @@ function getDocument(src) {
params[key] = new Uint8Array(value);
} else {
throw new Error(
"Invalid PDF binary data: either typed array, " +
"Invalid PDF binary data: either TypedArray, " +
"string, or array-like object is expected in the data property."
);
}
Expand Down
32 changes: 30 additions & 2 deletions test/unit/api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,13 @@ describe("api", function () {
expect(true).toEqual(true);
});

it("creates pdf doc from typed array", async function () {
it("creates pdf doc from TypedArray", async function () {
const typedArrayPdf = await DefaultFileReaderFactory.fetch({
path: TEST_PDFS_PATH + basicApiFileName,
});

// Sanity check to make sure that we fetched the entire PDF file.
expect(typedArrayPdf instanceof Uint8Array).toEqual(true);
expect(typedArrayPdf.length).toEqual(basicApiFileLength);

const loadingTask = getDocument(typedArrayPdf);
Expand All @@ -196,6 +197,33 @@ describe("api", function () {
await loadingTask.destroy();
});

it("creates pdf doc from ArrayBuffer", async function () {
const { buffer: arrayBufferPdf } = await DefaultFileReaderFactory.fetch({
path: TEST_PDFS_PATH + basicApiFileName,
});

// Sanity check to make sure that we fetched the entire PDF file.
expect(arrayBufferPdf instanceof ArrayBuffer).toEqual(true);
expect(arrayBufferPdf.byteLength).toEqual(basicApiFileLength);

const loadingTask = getDocument(arrayBufferPdf);
expect(loadingTask instanceof PDFDocumentLoadingTask).toEqual(true);

const progressReportedCapability = createPromiseCapability();
loadingTask.onProgress = function (data) {
progressReportedCapability.resolve(data);
};

const data = await Promise.all([
loadingTask.promise,
progressReportedCapability.promise,
]);
expect(data[0] instanceof PDFDocumentProxy).toEqual(true);
expect(data[1].loaded / data[1].total).toEqual(1);

await loadingTask.destroy();
});

it("creates pdf doc from invalid PDF file", async function () {
// A severely corrupt PDF file (even Adobe Reader fails to open it).
const loadingTask = getDocument(buildGetDocumentParams("bug1020226.pdf"));
Expand Down Expand Up @@ -441,7 +469,7 @@ describe("api", function () {
}
);

it("creates pdf doc from empty typed array", async function () {
it("creates pdf doc from empty TypedArray", async function () {
const loadingTask = getDocument(new Uint8Array(0));
expect(loadingTask instanceof PDFDocumentLoadingTask).toEqual(true);

Expand Down