1/** 2 * PDFObject v2.2.6 3 * https://github.com/pipwerks/PDFObject 4 * @license 5 * Copyright (c) 2008-2021 Philip Hutchison 6 * MIT-style license: http://pipwerks.mit-license.org/ 7 * UMD module pattern from https://github.com/umdjs/umd/blob/master/templates/returnExports.js 8 */ 9 10(function (root, factory) { 11 if (typeof define === "function" && define.amd) { 12 // AMD. Register as an anonymous module. 13 define([], factory); 14 } else if (typeof module === "object" && module.exports) { 15 // Node. Does not work with strict CommonJS, but 16 // only CommonJS-like environments that support module.exports, 17 // like Node. 18 module.exports = factory(); 19 } else { 20 // Browser globals (root is window) 21 root.PDFObject = factory(); 22 } 23}(this, function () { 24 25 "use strict"; 26 27 //PDFObject is designed for client-side (browsers), not server-side (node) 28 //Will choke on undefined navigator and window vars when run on server 29 //Return boolean false and exit function when running server-side 30 31 if( typeof window === "undefined" || 32 window.navigator === undefined || 33 window.navigator.userAgent === undefined || 34 window.navigator.mimeTypes === undefined){ 35 return false; 36 } 37 38 let pdfobjectversion = "2.2.6"; 39 let nav = window.navigator; 40 let ua = window.navigator.userAgent; 41 42 //Time to jump through hoops -- browser vendors do not make it easy to detect PDF support. 43 44 /* 45 IE11 still uses ActiveX for Adobe Reader, but IE 11 doesn't expose window.ActiveXObject the same way 46 previous versions of IE did. window.ActiveXObject will evaluate to false in IE 11, but "ActiveXObject" 47 in window evaluates to true. 48 49 MS Edge does not support ActiveX so this test will evaluate false 50 */ 51 let isIE = ("ActiveXObject" in window); 52 53 /* 54 There is a coincidental correlation between implementation of window.promises and native PDF support in desktop browsers 55 We use this to assume if the browser supports promises it supports embedded PDFs 56 Is this fragile? Sort of. But browser vendors removed mimetype detection, so we're left to improvise 57 */ 58 let isModernBrowser = (window.Promise !== undefined); 59 60 //Older browsers still expose the mimeType 61 let supportsPdfMimeType = (nav.mimeTypes["application/pdf"] !== undefined); 62 63 //Safari on iPadOS doesn't report as 'mobile' when requesting desktop site, yet still fails to embed PDFs 64 let isSafariIOSDesktopMode = ( nav.platform !== undefined && 65 nav.platform === "MacIntel" && 66 nav.maxTouchPoints !== undefined && 67 nav.maxTouchPoints > 1 ); 68 69 //Quick test for mobile devices. 70 let isMobileDevice = (isSafariIOSDesktopMode || /Mobi|Tablet|Android|iPad|iPhone/.test(ua)); 71 72 //Safari desktop requires special handling 73 let isSafariDesktop = ( !isMobileDevice && 74 nav.vendor !== undefined && 75 /Apple/.test(nav.vendor) && 76 /Safari/.test(ua) ); 77 78 //Firefox started shipping PDF.js in Firefox 19. If this is Firefox 19 or greater, assume PDF.js is available 79 let isFirefoxWithPDFJS = (!isMobileDevice && /irefox/.test(ua) && ua.split("rv:").length > 1) ? (parseInt(ua.split("rv:")[1].split(".")[0], 10) > 18) : false; 80 81 82 /* ---------------------------------------------------- 83 Supporting functions 84 ---------------------------------------------------- */ 85 86 let createAXO = function (type){ 87 var ax; 88 try { 89 ax = new ActiveXObject(type); 90 } catch (e) { 91 ax = null; //ensure ax remains null 92 } 93 return ax; 94 }; 95 96 //If either ActiveX support for "AcroPDF.PDF" or "PDF.PdfCtrl" are found, return true 97 //Constructed as a method (not a prop) to avoid unneccesarry overhead -- will only be evaluated if needed 98 let supportsPdfActiveX = function (){ return !!(createAXO("AcroPDF.PDF") || createAXO("PDF.PdfCtrl")); }; 99 100 //Determines whether PDF support is available 101 let supportsPDFs = ( 102 //As of Sept 2020 no mobile browsers properly support PDF embeds 103 !isMobileDevice && ( 104 //We're moving into the age of MIME-less browsers. They mostly all support PDF rendering without plugins. 105 isModernBrowser || 106 //Modern versions of Firefox come bundled with PDFJS 107 isFirefoxWithPDFJS || 108 //Browsers that still support the original MIME type check 109 supportsPdfMimeType || 110 //Pity the poor souls still using IE 111 (isIE && supportsPdfActiveX()) 112 ) 113 ); 114 115 //Create a fragment identifier for using PDF Open parameters when embedding PDF
116 let buildURLFragmentString = function(pdfParams){ 117 118 let string = ""; 119 let prop; 120 121 if(pdfParams){ 122 123 for (prop in pdfParams) { 124 if (pdfParams.hasOwnProperty(prop)) { 125 string += encodeURIComponent(prop) + "=" + encodeURIComponent(pdfParams[prop]) + "&"; 126 } 127 } 128 129 //The string will be empty if no PDF Params found 130 if(string){ 131 132 string = "#" + string; 133 134 //Remove last ampersand 135 string = string.slice(0, string.length - 1); 136 137 } 138 139 } 140 141 return string; 142 143 }; 144 145 let embedError = function (msg, suppressConsole){ 146 if(!suppressConsole){ 147 // console.log("[PDFObject] " + msg); //added by EP developer 148 } 149 return false; 150 }; 151 152 let emptyNodeContents = function (node){ 153 while(node.firstChild){ 154 node.removeChild(node.firstChild); 155 } 156 }; 157 158 let getTargetElement = function (targetSelector){ 159 160 //Default to body for full-browser PDF 161 let targetNode = document.body; 162 163 //If a targetSelector is specified, check to see whether 164 //it's passing a selector, jQuery object, or an HTML element 165 166 if(typeof targetSelector === "string"){ 167 168 //Is CSS selector 169 targetNode = document.querySelector(targetSelector); 170 171 } else if (window.jQuery !== undefined && targetSelector instanceof jQuery && targetSelector.length) { 172 173 //Is jQuery element. Extract HTML node 174 targetNode = targetSelector.get(0); 175 176 } else if (targetSelector.nodeType !== undefined && targetSelector.nodeType === 1){ 177 178 //Is HTML element 179 targetNode = targetSelector; 180 181 } 182 183 return targetNode; 184 185 }; 186 187 let generatePDFJSMarkup = function (targetNode, url, pdfOpenFragment, PDFJS_URL, id, omitInlineStyles){ 188 189 //Ensure target element is empty first 190 emptyNodeContents(targetNode); 191 192 let fullURL = PDFJS_URL + "?file=" + encodeURIComponent(url) + pdfOpenFragment; 193 let div = document.createElement("div"); 194 let iframe = document.createElement("iframe"); 195 196 iframe.src = fullURL; 197 iframe.className = "pdfobject"; 198 iframe.type = "application/pdf"; 199 iframe.frameborder = "0"; 200 iframe.allow = "fullscreen"; 201 202 if(id){ 203 iframe.id = id; 204 } 205 206 if(!omitInlineStyles){ 207 div.style.cssText = "position: absolute; top: 0; right: 0; bottom: 0; left: 0;"; 208 iframe.style.cssText = "border: none; width: 100%; height: 100%;"; 209 targetNode.style.position = "relative"; 210 targetNode.style.overflow = "auto"; 211 } 212 213 div.appendChild(iframe); 214 targetNode.appendChild(div); 215 targetNode.classList.add("pdfobject-container"); 216 217 return targetNode.getElementsByTagName("iframe")[0]; 218 219 }; 220 221 let generatePDFObjectMarkup = function (embedType, targetNode, targetSelector, url, pdfOpenFragment, width, height, id, title, omitInlineStyles){ 222 223 //Ensure target element is empty first 224 emptyNodeContents(targetNode); 225 226 let embed = document.createElement(embedType); 227 if ('object' === embedType ) { 228 embed.data = url + pdfOpenFragment; 229 }else{ 230 embed.src = url + pdfOpenFragment; 231 } 232 embed.className = "pdfobject"; 233 embed.type = "application/pdf"; 234 embed.title = title; 235 236 if(id){ 237 embed.id = id; 238 } 239 240 if(embedType === "iframe"){ 241 embed.allow = "fullscreen"; 242 } 243 244 if(!omitInlineStyles){ 245 246 let style = (embedType === "embed") ? "overflow: auto;" : "border: none;"; 247 248 if(targetSelector && targetSelector !== document.body){ 249 style += "width: " + width + "; height: " + height + ";"; 250 } else { 251 style += "position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;"; 252 } 253 254 embed.style.cssText = style; 255 256 } 257 258 targetNode.classList.add("pdfobject-container"); 259 targetNode.appendChild(embed); 260 261 return targetNode.getElementsByTagName(embedType)[0]; 262 263 }; 264 265 let embed = function(url, targetSelector, options){ 266
267 //If targetSelector is not defined, convert to boolean 268 let selector = targetSelector || false; 269 270 //Ensure options object is not undefined -- enables easier error checking below 271 let opt = options || {}; 272 273 //Get passed options, or set reasonable defaults 274 let id = (typeof opt.id === "string") ? opt.id : ""; 275 let page = opt.page || false; 276 let pdfOpenParams = opt.pdfOpenParams || {}; 277 let fallbackLink = opt.fallbackLink || true; 278 let width = opt.width || "100%"; 279 let height = opt.height || "100%"; 280 let title = opt.title || "Embedded PDF"; 281 let assumptionMode = (typeof opt.assumptionMode === "boolean") ? opt.assumptionMode : true; 282 let forcePDFJS = (typeof opt.forcePDFJS === "boolean") ? opt.forcePDFJS : false; 283 let supportRedirect = (typeof opt.supportRedirect === "boolean") ? opt.supportRedirect : false; 284 let omitInlineStyles = (typeof opt.omitInlineStyles === "boolean") ? opt.omitInlineStyles : false; 285 let suppressConsole = (typeof opt.suppressConsole === "boolean") ? opt.suppressConsole : false; 286 let forceIframe = (typeof opt.forceIframe === "boolean") ? opt.forceIframe : false; 287 let forceObject = (typeof opt.forceObject === "boolean") ? opt.forceObject : false; 288 let PDFJS_URL = opt.PDFJS_URL || false; 289 let targetNode = getTargetElement(selector); 290 let fallbackHTML = ""; 291 let pdfOpenFragment = ""; 292 let fallbackHTML_default = "<p>This browser does not support inline PDFs. Please download the PDF to view it: <a href='[url]'>Download PDF</a></p>"; 293 294 //Ensure URL is available. If not, exit now. 295 if(typeof url !== "string"){ return embedError("URL is not valid", suppressConsole); } 296 297 //If target element is specified but is not valid, exit without doing anything 298 if(!targetNode){ return embedError("Target element cannot be determined", suppressConsole); } 299 300 //page option overrides pdfOpenParams, if found 301 if(page){ pdfOpenParams.page = page; } 302 303 //Stringify optional Adobe params for opening document (as fragment identifier) 304 pdfOpenFragment = buildURLFragmentString(pdfOpenParams); 305 306 307 // --== Do the dance: Embed attempt #1 ==-- 308 309 //If the forcePDFJS option is invoked, skip everything else and embed as directed 310 if(forcePDFJS && PDFJS_URL){ 311 return generatePDFJSMarkup(targetNode, url, pdfOpenFragment, PDFJS_URL, id, omitInlineStyles); 312 } 313 314 // --== Embed attempt #2 ==-- 315 316 //Embed PDF if traditional support is provided, or if this developer is willing to roll with assumption 317 //that modern desktop (not mobile) browsers natively support PDFs 318 if(supportsPDFs || (assumptionMode && !isMobileDevice)){ 319 320 //Should we use <embed> or <iframe>? In most cases <embed>. 321 //Allow developer to force <iframe>, if desired
322 //There is an edge case where Safari does not respect 302 redirect requests for PDF files when using <embed> element. 323 //Redirect appears to work fine when using <iframe> instead of <embed> (Addresses issue #210) 324 //Forcing Safari desktop to use iframe due to freezing bug in macOS 11 (Big Sur) 325 let embedtype = (forceIframe || supportRedirect || isSafariDesktop) ? "iframe" : (forceObject ? "object" : "embed"); 326 return generatePDFObjectMarkup(embedtype, targetNode, targetSelector, url, pdfOpenFragment, width, height, id, title, omitInlineStyles); 327 328 } 329 330 // --== Embed attempt #3 ==-- 331 332 //If everything else has failed and a PDFJS fallback is provided, try to use it 333 if(PDFJS_URL){ 334 return generatePDFJSMarkup(targetNode, url, pdfOpenFragment, PDFJS_URL, id, omitInlineStyles); 335 } 336 337 // --== PDF embed not supported! Use fallback ==-- 338 339 //Display the fallback link if available 340 if(fallbackLink){ 341 342 fallbackHTML = (typeof fallbackLink === "string") ? fallbackLink : fallbackHTML_default; 343 targetNode.innerHTML = fallbackHTML.replace(/\[url\]/g, url); 344 345 } 346 347 return embedError("This browser does not support embedded PDFs", suppressConsole); 348 349 }; 350 351 return { 352 embed: function (a,b,c){ return embed(a,b,c); }, 353 pdfobjectversion: (function () { return pdfobjectversion; })(), 354 supportsPDFs: (function (){ return supportsPDFs; })() 355 }; 356 357}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.