From 01d12b465c1d065f148ed9a5107f27c5b09a48e7 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 20 Nov 2020 14:17:23 +0100 Subject: [PATCH] [api-minor] Add "contentLength" to the information returned by the `getMetadata` method Given that we already include the "Content-Disposition"-header filename, when it exists, it shouldn't hurt to also include the information from the "Content-Length"-header. For PDF documents opened via a URL, which should be a very common way for the PDF.js library to be used, this will[1] thus provide a way of getting the PDF filesize without having to wait for the `getDownloadInfo`-promise to resolve[2]. With these API improvements, we can also simplify the filesize handling in the `PDFDocumentProperties` class. --- [1] Assuming that the server is correctly configured, of course. [2] Since that's not *guaranteed* to happen in general, with e.g. `disableAutoFetch = true` set. --- src/display/api.js | 5 ++- test/unit/api_spec.js | 24 +++++++++++-- web/app.js | 9 ++--- web/pdf_document_properties.js | 62 +++++++++++++--------------------- 4 files changed, 49 insertions(+), 51 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 6482121efa3e1..bc914119d8230 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -2654,9 +2654,8 @@ class WorkerTransport { return { info: results[0], metadata: results[1] ? new Metadata(results[1]) : null, - contentDispositionFilename: this._fullReader - ? this._fullReader.filename - : null, + contentDispositionFilename: this._fullReader?.filename ?? null, + contentLength: this._fullReader?.contentLength ?? null, }; }); } diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 6fcc068a841c9..5cbbcc773d337 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -1132,7 +1132,12 @@ describe("api", function () { it("gets metadata", function (done) { const promise = pdfDocument.getMetadata(); promise - .then(function ({ info, metadata, contentDispositionFilename }) { + .then(function ({ + info, + metadata, + contentDispositionFilename, + contentLength, + }) { expect(info.Title).toEqual("Basic API Test"); // Custom, non-standard, information dictionary entries. expect(info.Custom).toEqual(undefined); @@ -1147,6 +1152,7 @@ describe("api", function () { expect(metadata.get("dc:title")).toEqual("Basic API Test"); expect(contentDispositionFilename).toEqual(null); + expect(contentLength).toEqual(basicApiFileLength); done(); }) .catch(done.fail); @@ -1160,7 +1166,12 @@ describe("api", function () { .then(function (pdfDoc) { return pdfDoc.getMetadata(); }) - .then(function ({ info, metadata, contentDispositionFilename }) { + .then(function ({ + info, + metadata, + contentDispositionFilename, + contentLength, + }) { expect(info.Creator).toEqual("TeX"); expect(info.Producer).toEqual("pdfeTeX-1.21a"); expect(info.CreationDate).toEqual("D:20090401163925-07'00'"); @@ -1181,6 +1192,7 @@ describe("api", function () { expect(metadata).toEqual(null); expect(contentDispositionFilename).toEqual(null); + expect(contentLength).toEqual(1016315); loadingTask.destroy().then(done); }) @@ -1193,7 +1205,12 @@ describe("api", function () { .then(function (pdfDoc) { return pdfDoc.getMetadata(); }) - .then(function ({ info, metadata, contentDispositionFilename }) { + .then(function ({ + info, + metadata, + contentDispositionFilename, + contentLength, + }) { // The following are PDF.js specific, non-standard, properties. expect(info.PDFFormatVersion).toEqual(null); expect(info.IsLinearized).toEqual(false); @@ -1203,6 +1220,7 @@ describe("api", function () { expect(metadata).toEqual(null); expect(contentDispositionFilename).toEqual(null); + expect(contentLength).toEqual(624); loadingTask.destroy().then(done); }) diff --git a/web/app.js b/web/app.js index 91384891b80ef..b64302ce850e5 100644 --- a/web/app.js +++ b/web/app.js @@ -863,15 +863,10 @@ const PDFViewerApplication = { } parameters[key] = value; } - + // Finally, update the API parameters with the arguments (if they exist). if (args) { for (const key in args) { - const value = args[key]; - - if (key === "length") { - this.pdfDocumentProperties.setFileSize(value); - } - parameters[key] = value; + parameters[key] = args[key]; } } diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index 8b38fb08ecd91..416dbff06d3b1 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -128,23 +128,25 @@ class PDFDocumentProperties { // Get the document properties. this.pdfDocument .getMetadata() - .then(({ info, metadata, contentDispositionFilename }) => { - return Promise.all([ - info, - metadata, - contentDispositionFilename || getPDFFileNameFromURL(this.url), - this._parseFileSize(this.maybeFileSize), - this._parseDate(info.CreationDate), - this._parseDate(info.ModDate), - this.pdfDocument.getPage(currentPageNumber).then(pdfPage => { - return this._parsePageSize( - getPageSizeInches(pdfPage), - pagesRotation - ); - }), - this._parseLinearization(info.IsLinearized), - ]); - }) + .then( + ({ info, metadata, contentDispositionFilename, contentLength }) => { + return Promise.all([ + info, + metadata, + contentDispositionFilename || getPDFFileNameFromURL(this.url), + this._parseFileSize(contentLength), + this._parseDate(info.CreationDate), + this._parseDate(info.ModDate), + this.pdfDocument.getPage(currentPageNumber).then(pdfPage => { + return this._parsePageSize( + getPageSizeInches(pdfPage), + pagesRotation + ); + }), + this._parseLinearization(info.IsLinearized), + ]); + } + ) .then( ([ info, @@ -176,15 +178,13 @@ class PDFDocumentProperties { }); this._updateUI(); - // Get the correct fileSize, since it may not have been set (if - // `this.setFileSize` wasn't called) or may be incorrectly set. - return this.pdfDocument.getDownloadInfo(); + // Get the correct fileSize, since it may not have been available + // or could potentially be wrong. + return this.pdfDocument.getDownloadInfo().then(downloadInfo => { + return this._parseFileSize(downloadInfo.length); + }); } ) - .then(({ length }) => { - this.maybeFileSize = length; - return this._parseFileSize(length); - }) .then(fileSize => { if (fileSize === this.fieldData.fileSize) { return; // The fileSize has already been correctly set. @@ -228,19 +228,6 @@ class PDFDocumentProperties { this._dataAvailableCapability.resolve(); } - /** - * Set the file size of the PDF document. This method is used to - * update the file size in the document properties overlay once it - * is known so we do not have to wait until the entire file is loaded. - * - * @param {number} fileSize - The file size of the PDF document. - */ - setFileSize(fileSize) { - if (Number.isInteger(fileSize) && fileSize > 0) { - this.maybeFileSize = fileSize; - } - } - /** * @private */ @@ -248,7 +235,6 @@ class PDFDocumentProperties { this.pdfDocument = null; this.url = null; - this.maybeFileSize = 0; delete this.fieldData; this._dataAvailableCapability = createPromiseCapability(); this._currentPageNumber = 1;