Skip to content

Commit aefc0ce

Browse files
committed
[api-minor] Support the Content-Disposition filename in the Firefox PDF Viewer (bug 1694556, PR 9379 follow-up)
As can be seen [in the mozilla-central code](https://searchfox.org/mozilla-central/rev/a6db3bd67367aa9ddd9505690cab09b47e65a762/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#1222-1225), we're already getting the Content-Disposition filename. However, that data isn't passed through to the viewer nor to the `PDFDataTransportStream`-implementation, which explains why it's currently being ignored. *Please note:* This will also require a small mozilla-central patch, see https://bugzilla.mozilla.org/show_bug.cgi?id=1694556, to forward the necessary data to the viewer.
1 parent 45329af commit aefc0ce

File tree

5 files changed

+44
-8
lines changed

5 files changed

+44
-8
lines changed

src/display/api.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ function getDocument(src) {
334334
length: params.length,
335335
initialData: params.initialData,
336336
progressiveDone: params.progressiveDone,
337+
contentDispositionFilename: params.contentDispositionFilename,
337338
disableRange: params.disableRange,
338339
disableStream: params.disableStream,
339340
},
@@ -401,6 +402,8 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
401402
source.length = pdfDataRangeTransport.length;
402403
source.initialData = pdfDataRangeTransport.initialData;
403404
source.progressiveDone = pdfDataRangeTransport.progressiveDone;
405+
source.contentDispositionFilename =
406+
pdfDataRangeTransport.contentDispositionFilename;
404407
}
405408
return worker.messageHandler
406409
.sendWithPromise("GetDocRequest", {
@@ -554,11 +557,18 @@ class PDFDataRangeTransport {
554557
* @param {number} length
555558
* @param {Uint8Array} initialData
556559
* @param {boolean} [progressiveDone]
560+
* @param {string} [contentDispositionFilename]
557561
*/
558-
constructor(length, initialData, progressiveDone = false) {
562+
constructor(
563+
length,
564+
initialData,
565+
progressiveDone = false,
566+
contentDispositionFilename = null
567+
) {
559568
this.length = length;
560569
this.initialData = initialData;
561570
this.progressiveDone = progressiveDone;
571+
this.contentDispositionFilename = contentDispositionFilename;
562572

563573
this._rangeListeners = [];
564574
this._progressListeners = [];

src/display/transport_stream.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515

1616
import { assert, createPromiseCapability } from "../shared/util.js";
1717

18+
function validateFilename(filename) {
19+
if (typeof filename === "string" && /\.pdf$/i.test(filename)) {
20+
return filename;
21+
}
22+
return null;
23+
}
24+
1825
/** @implements {IPDFStream} */
1926
class PDFDataTransportStream {
2027
constructor(params, pdfDataRangeTransport) {
@@ -25,6 +32,8 @@ class PDFDataTransportStream {
2532

2633
this._queuedChunks = [];
2734
this._progressiveDone = params.progressiveDone || false;
35+
this._contentDispositionFilename =
36+
params.contentDispositionFilename || null;
2837

2938
const initialData = params.initialData;
3039
if (initialData?.length > 0) {
@@ -125,7 +134,8 @@ class PDFDataTransportStream {
125134
return new PDFDataTransportStreamReader(
126135
this,
127136
queuedChunks,
128-
this._progressiveDone
137+
this._progressiveDone,
138+
this._contentDispositionFilename
129139
);
130140
}
131141

@@ -153,10 +163,15 @@ class PDFDataTransportStream {
153163

154164
/** @implements {IPDFStreamReader} */
155165
class PDFDataTransportStreamReader {
156-
constructor(stream, queuedChunks, progressiveDone = false) {
166+
constructor(
167+
stream,
168+
queuedChunks,
169+
progressiveDone = false,
170+
contentDispositionFilename = null
171+
) {
157172
this._stream = stream;
158173
this._done = progressiveDone || false;
159-
this._filename = null;
174+
this._filename = validateFilename(contentDispositionFilename);
160175
this._queuedChunks = queuedChunks || [];
161176
this._loaded = 0;
162177
for (const chunk of this._queuedChunks) {

web/app.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
EventBus,
2222
getActiveOrFocusedElement,
2323
getPDFFileNameFromURL,
24+
isPdfFilename,
2425
isValidRotation,
2526
isValidScrollMode,
2627
isValidSpreadMode,
@@ -727,7 +728,11 @@ const PDFViewerApplication = {
727728
onOpenWithTransport: (url, length, transport) => {
728729
this.open(url, { length, range: transport });
729730
},
730-
onOpenWithData: data => {
731+
onOpenWithData: (data, contentDispositionFilename) => {
732+
if (isPdfFilename(contentDispositionFilename)) {
733+
this._contentDispositionFilename = contentDispositionFilename;
734+
}
735+
731736
this.open(data);
732737
},
733738
onOpenWithURL: (url, length, originalUrl) => {
@@ -1744,7 +1749,7 @@ const PDFViewerApplication = {
17441749
}
17451750
this.documentInfo = info;
17461751
this.metadata = metadata;
1747-
this._contentDispositionFilename = contentDispositionFilename;
1752+
this._contentDispositionFilename ??= contentDispositionFilename;
17481753
this._contentLength ??= contentLength; // See `getDownloadInfo`-call above.
17491754

17501755
// Provides some basic debug information

web/firefoxcom.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ class FirefoxExternalServices extends DefaultExternalServices {
296296
pdfDataRangeTransport = new FirefoxComDataRangeTransport(
297297
args.length,
298298
args.data,
299-
args.done
299+
args.done,
300+
args.filename
300301
);
301302

302303
callbacks.onOpenWithTransport(
@@ -331,7 +332,7 @@ class FirefoxExternalServices extends DefaultExternalServices {
331332
callbacks.onError(args.errorCode);
332333
break;
333334
}
334-
callbacks.onOpenWithData(args.data);
335+
callbacks.onOpenWithData(args.data, args.filename);
335336
break;
336337
}
337338
});

web/ui_utils.js

+5
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ function noContextMenuHandler(evt) {
600600
evt.preventDefault();
601601
}
602602

603+
function isPdfFilename(filename) {
604+
return typeof filename === "string" && /\.pdf$/i.test(filename);
605+
}
606+
603607
function isDataSchema(url) {
604608
let i = 0;
605609
const ii = url.length;
@@ -1046,6 +1050,7 @@ export {
10461050
getPageSizeInches,
10471051
getPDFFileNameFromURL,
10481052
getVisibleElements,
1053+
isPdfFilename,
10491054
isPortraitOrientation,
10501055
isValidRotation,
10511056
isValidScrollMode,

0 commit comments

Comments
 (0)