Skip to content

Commit 5dd749c

Browse files
authored
Merge pull request #13014 from Snuffleupagus/Firefox-contentDispositionFilename
[api-minor] Support the Content-Disposition filename in the Firefox PDF Viewer (bug 1694556, PR 9379 follow-up)
2 parents 061637d + 6fd899d commit 5dd749c

10 files changed

+55
-30
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/display_utils.js

+5
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
451451
link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL;
452452
}
453453

454+
function isPdfFile(filename) {
455+
return typeof filename === "string" && /\.pdf$/i.test(filename);
456+
}
457+
454458
/**
455459
* Gets the file name from a given URL.
456460
* @param {string} url
@@ -652,6 +656,7 @@ export {
652656
DOMSVGFactory,
653657
getFilenameFromUrl,
654658
isFetchSupported,
659+
isPdfFile,
655660
isValidFetchUrl,
656661
LinkTarget,
657662
loadScript,

src/display/network_utils.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
UnexpectedResponseException,
2020
} from "../shared/util.js";
2121
import { getFilenameFromContentDispositionHeader } from "./content_disposition.js";
22+
import { isPdfFile } from "./display_utils.js";
2223

2324
function validateRangeRequestCapabilities({
2425
getResponseHeader,
@@ -70,7 +71,7 @@ function extractFilenameFromHeader(getResponseHeader) {
7071
filename = decodeURIComponent(filename);
7172
} catch (ex) {}
7273
}
73-
if (/\.pdf$/i.test(filename)) {
74+
if (isPdfFile(filename)) {
7475
return filename;
7576
}
7677
}
@@ -82,11 +83,7 @@ function createResponseStatusError(status, url) {
8283
return new MissingPDFException('Missing PDF "' + url + '".');
8384
}
8485
return new UnexpectedResponseException(
85-
"Unexpected server response (" +
86-
status +
87-
') while retrieving PDF "' +
88-
url +
89-
'".',
86+
`Unexpected server response (${status}) while retrieving PDF "${url}".`,
9087
status
9188
);
9289
}

src/display/transport_stream.js

+14-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
import { assert, createPromiseCapability } from "../shared/util.js";
17+
import { isPdfFile } from "./display_utils.js";
1718

1819
/** @implements {IPDFStream} */
1920
class PDFDataTransportStream {
@@ -25,6 +26,8 @@ class PDFDataTransportStream {
2526

2627
this._queuedChunks = [];
2728
this._progressiveDone = params.progressiveDone || false;
29+
this._contentDispositionFilename =
30+
params.contentDispositionFilename || null;
2831

2932
const initialData = params.initialData;
3033
if (initialData?.length > 0) {
@@ -125,7 +128,8 @@ class PDFDataTransportStream {
125128
return new PDFDataTransportStreamReader(
126129
this,
127130
queuedChunks,
128-
this._progressiveDone
131+
this._progressiveDone,
132+
this._contentDispositionFilename
129133
);
130134
}
131135

@@ -153,10 +157,17 @@ class PDFDataTransportStream {
153157

154158
/** @implements {IPDFStreamReader} */
155159
class PDFDataTransportStreamReader {
156-
constructor(stream, queuedChunks, progressiveDone = false) {
160+
constructor(
161+
stream,
162+
queuedChunks,
163+
progressiveDone = false,
164+
contentDispositionFilename = null
165+
) {
157166
this._stream = stream;
158167
this._done = progressiveDone || false;
159-
this._filename = null;
168+
this._filename = isPdfFile(contentDispositionFilename)
169+
? contentDispositionFilename
170+
: null;
160171
this._queuedChunks = queuedChunks || [];
161172
this._loaded = 0;
162173
for (const chunk of this._queuedChunks) {

src/pdf.js

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
addLinkAttributes,
1919
getFilenameFromUrl,
2020
isFetchSupported,
21+
isPdfFile,
2122
isValidFetchUrl,
2223
LinkTarget,
2324
loadScript,
@@ -128,6 +129,7 @@ export {
128129
// From "./display/display_utils.js":
129130
addLinkAttributes,
130131
getFilenameFromUrl,
132+
isPdfFile,
131133
LinkTarget,
132134
loadScript,
133135
PDFDateString,

web/app.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
getFilenameFromUrl,
4545
GlobalWorkerOptions,
4646
InvalidPDFException,
47+
isPdfFile,
4748
LinkTarget,
4849
loadScript,
4950
MissingPDFException,
@@ -727,7 +728,10 @@ const PDFViewerApplication = {
727728
onOpenWithTransport: (url, length, transport) => {
728729
this.open(url, { length, range: transport });
729730
},
730-
onOpenWithData: data => {
731+
onOpenWithData: (data, contentDispositionFilename) => {
732+
if (isPdfFile(contentDispositionFilename)) {
733+
this._contentDispositionFilename = contentDispositionFilename;
734+
}
731735
this.open(data);
732736
},
733737
onOpenWithURL: (url, length, originalUrl) => {
@@ -1744,7 +1748,7 @@ const PDFViewerApplication = {
17441748
}
17451749
this.documentInfo = info;
17461750
this.metadata = metadata;
1747-
this._contentDispositionFilename = contentDispositionFilename;
1751+
this._contentDispositionFilename ??= contentDispositionFilename;
17481752
this._contentLength ??= contentLength; // See `getDownloadInfo`-call above.
17491753

17501754
// Provides some basic debug information

web/download_manager.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { createObjectURL, createValidAbsoluteUrl } from "pdfjs-lib";
17-
import { PdfFileRegExp } from "./ui_utils.js";
16+
import { createObjectURL, createValidAbsoluteUrl, isPdfFile } from "pdfjs-lib";
1817
import { viewerCompatibilityParams } from "./viewer_compatibility.js";
1918

2019
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("CHROME || GENERIC")) {
@@ -68,10 +67,10 @@ class DownloadManager {
6867
* @returns {boolean} Indicating if the data was opened.
6968
*/
7069
openOrDownloadData(element, data, filename) {
71-
const isPdfFile = PdfFileRegExp.test(filename);
72-
const contentType = isPdfFile ? "application/pdf" : "";
70+
const isPdfData = isPdfFile(filename);
71+
const contentType = isPdfData ? "application/pdf" : "";
7372

74-
if (isPdfFile && !viewerCompatibilityParams.disableCreateObjectURL) {
73+
if (isPdfData && !viewerCompatibilityParams.disableCreateObjectURL) {
7574
let blobUrl = this._openBlobUrls.get(element);
7675
if (!blobUrl) {
7776
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));

web/firefoxcom.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
*/
1515

1616
import "../extensions/firefox/tools/l10n.js";
17-
import { DEFAULT_SCALE_VALUE, PdfFileRegExp } from "./ui_utils.js";
1817
import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
19-
import { PDFDataRangeTransport, shadow } from "pdfjs-lib";
18+
import { isPdfFile, PDFDataRangeTransport, shadow } from "pdfjs-lib";
2019
import { BasePreferences } from "./preferences.js";
20+
import { DEFAULT_SCALE_VALUE } from "./ui_utils.js";
2121

2222
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
2323
throw new Error(
@@ -129,10 +129,10 @@ class DownloadManager {
129129
* @returns {boolean} Indicating if the data was opened.
130130
*/
131131
openOrDownloadData(element, data, filename) {
132-
const isPdfFile = PdfFileRegExp.test(filename);
133-
const contentType = isPdfFile ? "application/pdf" : "";
132+
const isPdfData = isPdfFile(filename);
133+
const contentType = isPdfData ? "application/pdf" : "";
134134

135-
if (isPdfFile) {
135+
if (isPdfData) {
136136
let blobUrl = this._openBlobUrls.get(element);
137137
if (!blobUrl) {
138138
blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
@@ -332,7 +332,8 @@ class FirefoxExternalServices extends DefaultExternalServices {
332332
pdfDataRangeTransport = new FirefoxComDataRangeTransport(
333333
args.length,
334334
args.data,
335-
args.done
335+
args.done,
336+
args.filename
336337
);
337338

338339
callbacks.onOpenWithTransport(
@@ -367,7 +368,7 @@ class FirefoxExternalServices extends DefaultExternalServices {
367368
callbacks.onError(args.errorCode);
368369
break;
369370
}
370-
callbacks.onOpenWithData(args.data);
371+
callbacks.onOpenWithData(args.data, args.filename);
371372
break;
372373
}
373374
});

web/pdf_attachment_viewer.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ class PDFAttachmentViewer extends BaseTreeViewer {
119119
let attachmentsCount = 0;
120120
for (const name of names) {
121121
const item = attachments[name];
122-
const content = item.content;
123-
const filename = getFilenameFromUrl(item.filename);
122+
const content = item.content,
123+
filename = getFilenameFromUrl(item.filename);
124124

125125
const div = document.createElement("div");
126126
div.className = "treeItem";

web/ui_utils.js

-4
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@ const SpreadMode = {
6969
// Used by `PDFViewerApplication`, and by the API unit-tests.
7070
const AutoPrintRegExp = /\bprint\s*\(/;
7171

72-
// Used by the (various) `DownloadManager`-implementations.
73-
const PdfFileRegExp = /\.pdf$/i;
74-
7572
// Replaces {{arguments}} with their values.
7673
function formatL10nValue(text, args) {
7774
if (!args) {
@@ -1062,7 +1059,6 @@ export {
10621059
normalizeWheelEventDirection,
10631060
NullL10n,
10641061
parseQueryString,
1065-
PdfFileRegExp,
10661062
PresentationModeState,
10671063
ProgressBar,
10681064
RendererType,

0 commit comments

Comments
 (0)