Skip to content

Commit 80be0c1

Browse files
committed
Add option to set the default filename in the base64 fallback scenario
Can set the filename explicitly or optionally get it from the data uri's metadata Resolves #301
1 parent 55878c7 commit 80be0c1

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

pdfobject.js

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
let isModernBrowser = function (){
4141

4242
/*
43-
userAgent sniffing is not the ideal path, but most browsers revoked the ability to check navigator.mimeTypes
43+
userAgent sniffing is not the ideal path, but most browsers revoked the ability to check navigator.mimeTypes
4444
for security purposes. As of 2023, browsers have begun implementing navigator.pdfViewerEnabled, but older versions
45-
do not have navigator.pdfViewerEnabled or the ability to check navigator.mimeTypes. We're left with basic browser
45+
do not have navigator.pdfViewerEnabled or the ability to check navigator.mimeTypes. We're left with basic browser
4646
sniffing and assumptions of PDF support based on browser vendor.
4747
*/
4848

@@ -52,21 +52,21 @@
5252
//Note that MS Edge opts to use a different PDF rendering engine. As of 2024, Edge uses a version of Adobe's Reader
5353
let isChromium = (win.chrome !== undefined);
5454

55-
//Safari on macOS has provided native PDF support since 2009.
55+
//Safari on macOS has provided native PDF support since 2009.
5656
//This code snippet also detects the DuckDuckGo browser, which uses Safari/Webkit under the hood.
5757
let isSafari = (win.safari !== undefined || (nav.vendor !== undefined && /Apple/.test(nav.vendor) && /Safari/.test(ua)));
5858

5959
//Firefox has provided PDF support via PDFJS since 2013.
6060
let isFirefox = (win.Mozilla !== undefined || /irefox/.test(ua));
6161

62-
return isChromium || isSafari || isFirefox;
62+
return isChromium || isSafari || isFirefox;
6363

6464
};
6565

6666
/*
6767
Special handling for Internet Explorer 11.
6868
Check for ActiveX support, then whether "AcroPDF.PDF" or "PDF.PdfCtrl" are valid.
69-
IE11 uses ActiveX for Adobe Reader and other PDF plugins, but window.ActiveXObject will evaluate to false.
69+
IE11 uses ActiveX for Adobe Reader and other PDF plugins, but window.ActiveXObject will evaluate to false.
7070
("ActiveXObject" in window) evaluates to true.
7171
MS Edge does not support ActiveX so this test will evaluate false for MS Edge.
7272
*/
@@ -92,7 +92,7 @@
9292

9393
//As of June 2023, no mobile browsers properly support inline PDFs. If mobile, just say no.
9494
if(isMobileDevice){ return false; }
95-
95+
9696
//Modern browsers began supporting navigator.pdfViewerEnabled in late 2022 and early 2023.
9797
let supportsPDFVE = (typeof nav.pdfViewerEnabled === "boolean");
9898

@@ -113,20 +113,20 @@
113113
let prop;
114114
let paramArray = [];
115115
let fdf = "";
116-
117-
//The comment, viewrect, and highlight parameters require page to be set first.
116+
117+
//The comment, viewrect, and highlight parameters require page to be set first.
118118

119119
//Check to ensure page is used if comment, viewrect, or highlight are specified
120120
if(pdfParams.comment || pdfParams.viewrect || pdfParams.highlight){
121121

122122
if(!pdfParams.page){
123-
123+
124124
//If page is not set, use the first page
125125
pdfParams.page = 1;
126-
126+
127127
//Inform user that page needs to be set properly
128128
embedError("The comment, viewrect, and highlight parameters require a page parameter, but none was specified. Defaulting to page 1.");
129-
129+
130130
}
131131

132132
}
@@ -142,7 +142,7 @@
142142
fdf = pdfParams.fdf;
143143
delete pdfParams.fdf;
144144
}
145-
145+
146146
//Add all other parameters, as needed
147147
if(pdfParams){
148148

@@ -225,7 +225,7 @@
225225
xhr.onload = function() {
226226

227227
if (xhr.status === 200) {
228-
228+
229229
var blob = xhr.response;
230230
var link = document.createElement('a');
231231
link.innerText = "Download PDF";
@@ -238,7 +238,7 @@
238238
};
239239

240240
xhr.send();
241-
241+
242242
}
243243

244244
};
@@ -251,9 +251,9 @@
251251

252252
let source = url;
253253

254-
if(embedType === "pdfjs"){
254+
if(embedType === "pdfjs"){
255255
//If PDFJS_URL already contains a ?, assume querystring is in place, and use an ampersand to append PDFJS's file parameter
256-
let connector = (PDFJS_URL.indexOf("?") !== -1) ? "&" : "?";
256+
let connector = (PDFJS_URL.indexOf("?") !== -1) ? "&" : "?";
257257
source = PDFJS_URL + connector + "file=" + encodeURIComponent(url) + pdfOpenFragment;
258258
} else {
259259
source += pdfOpenFragment;
@@ -280,7 +280,7 @@
280280
style += "position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;";
281281
}
282282

283-
el.style.cssText = style;
283+
el.style.cssText = style;
284284

285285
}
286286

@@ -320,6 +320,7 @@
320320
let targetNode = getTargetElement(selector);
321321
let pdfOpenFragment = "";
322322
let customAttribute = opt.customAttribute || {};
323+
let fallbackFileNameForBase64 = opt.fallbackFileNameForBase64;
323324
let fallbackHTML_default = "<p>This browser does not support inline PDFs. Please download the PDF to view it: [pdflink]</p>";
324325

325326
//Ensure URL is available. If not, exit now.
@@ -341,22 +342,22 @@
341342
if(forcePDFJS && PDFJS_URL){
342343
return generatePDFObjectMarkup("pdfjs", targetNode, url, pdfOpenFragment, width, height, id, title, omitInlineStyles, customAttribute, PDFJS_URL);
343344
}
344-
345+
345346
// --== Embed attempt #2 ==--
346347

347-
//Embed PDF if support is detected, or if this is a relatively modern browser
348+
//Embed PDF if support is detected, or if this is a relatively modern browser
348349
if(supportsPDFs){
349350
return generatePDFObjectMarkup("iframe", targetNode, url, pdfOpenFragment, width, height, id, title, omitInlineStyles, customAttribute);
350351
}
351-
352+
352353
// --== Embed attempt #3 ==--
353-
354+
354355
//If everything else has failed and a PDFJS fallback is provided, try to use it
355356
if(PDFJS_URL){
356357
return generatePDFObjectMarkup("pdfjs", targetNode, url, pdfOpenFragment, width, height, id, title, omitInlineStyles, customAttribute, PDFJS_URL);
357358
}
358-
359-
// --== PDF embed not supported! Use fallback ==--
359+
360+
// --== PDF embed not supported! Use fallback ==--
360361

361362
//Display the fallback link if available
362363
if(fallbackLink){
@@ -370,11 +371,17 @@
370371
} else {
371372

372373
//If the PDF is a base64 string, convert it to a downloadable link
373-
if(url.indexOf("data:application/pdf;base64") !== -1){
374+
const match = url.match(/data:application\/pdf;(?:.*filename=([^;]+);)?.*base64,/i);
375+
if(match){
376+
377+
fallbackFileNameForBase64 =
378+
fallbackFileNameForBase64 // from options
379+
|| match[1] // from data URI metadata
380+
|| "file.pdf"; // default
374381

375382
//Asynchronously append the link to the targetNode
376-
convertBase64ToDownloadableLink(url, "file.pdf", targetNode, fallbackHTML_default);
377-
383+
convertBase64ToDownloadableLink(url, fallbackFileNameForBase64, targetNode, fallbackHTML_default);
384+
378385
} else {
379386

380387
//Use default fallback link

0 commit comments

Comments
 (0)