1/** 2 * EmbedPress PDF Lightbox â thumbnail preview + lightbox for single PDF block/widget/shortcode 3 */ 4(function () { 5 'use strict'; 6 7 // ========================================= 8 // Module 1: Thumbnail Generator 9 // ========================================= 10 var ThumbnailGenerator = { 11 pdfjsLoaded: false, 12 pdfjsLoading: false, 13 loadCallbacks: [], 14 15 loadPdfJs: function (callback) { 16 if (this.pdfjsLoaded && window.pdfjsLib) { 17 callback(); 18 return; 19 } 20 21 this.loadCallbacks.push(callback); 22 23 if (this.pdfjsLoading) return; 24 this.pdfjsLoading = true; 25 26 var self = this; 27 var scriptUrl = (typeof embedpressObj !== 'undefined' && embedpressObj.pluginUrl) 28 ? embedpressObj.pluginUrl + 'assets/pdf/build/script.js' 29 : null; 30 31 if (!scriptUrl) { 32 var scripts = document.querySelectorAll('script[src*="embedpress"]'); 33 for (var i = 0; i < scripts.length; i++) { 34 var match = scripts[i].src.match(/(.*embedpress[^/]*\/(?:assets|static)\/)/); 35 if (match) { 36 scriptUrl = match[1] + 'pdf/build/script.js'; 37 break; 38 } 39 } 40 } 41 42 if (!scriptUrl) { 43 self.pdfjsLoading = false; 44 return; 45 } 46 47 var script = document.createElement('script'); 48 script.src = scriptUrl; 49 script.type = 'module'; 50 script.onload = function () { 51 setTimeout(function () { 52 if (window.pdfjsLib || globalThis.pdfjsLib) { 53 if (!window.pdfjsLib) window.pdfjsLib = globalThis.pdfjsLib; 54 var workerUrl = scriptUrl.replace('script.js', 'pdf.worker.js'); 55 window.pdfjsLib.GlobalWorkerOptions.workerSrc = workerUrl; 56 self.pdfjsLoaded = true; 57 } 58 self.pdfjsLoading = false; 59 self.loadCallbacks.forEach(function (cb) { cb(); }); 60 self.loadCallbacks = []; 61 }, 50); 62 }; 63 script.onerror = function () { 64 self.pdfjsLoading = false; 65 self.loadCallbacks = []; 66 }; 67 document.head.appendChild(script); 68 }, 69 70 renderThumbnail: function (canvas, pdfUrl) { 71 if (!window.pdfjsLib) return; 72 73 canvas.setAttribute('data-loading', 'true'); 74 75 var loadingTask = window.pdfjsLib.getDocument(pdfUrl); 76 loadingTask.promise.then(function (pdf) { 77 pdf.getPage(1).then(function (page) { 78 var containerWidth = canvas.parentElement ? canvas.parentElement.offsetWidth : 400; 79 var scale = containerWidth / page.getViewport({ scale: 1 }).width; 80 scale = Math.max(scale, 0.5); 81 var viewport = page.getViewport({ scale: scale }); 82 83 canvas.width = viewport.width; 84 canvas.height = viewport.height; 85 86 var ctx = canvas.getContext('2d'); 87 page.render({ 88 canvasContext: ctx, 89 viewport: viewport 90 }).promise.then(function () { 91 canvas.removeAttribute('data-loading'); 92 }); 93 }); 94 }).catch(function () { 95 canvas.removeAttribute('data-loading'); 96 canvas.style.display = 'none'; 97 var wrap = canvas.parentElement; 98 if (wrap && !wrap.querySelector('.ep-pdf-thumbnail-placeholder')) { 99 var placeholder = document.createElement('div'); 100 placeholder.className = 'ep-pdf-thumbnail-placeholder'; 101 placeholder.innerHTML = '<svg viewBox="0 0 24 24" width="48" height="48" fill="#999"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zm-1 2l5 5h-5V4zM6 20V4h5v7h7v9H6z"/></svg>'; 102 wrap.appendChild(placeholder); 103 } 104 }); 105 }, 106 107 initAll: function () {
108 var canvases = document.querySelectorAll('.ep-pdf-thumbnail-canvas[data-pdf-url]'); 109 if (!canvases.length) return; 110 111 var self = this; 112 this.loadPdfJs(function () { 113 if (!window.pdfjsLib) return; 114 115 if ('IntersectionObserver' in window) { 116 var observer = new IntersectionObserver(function (entries) { 117 entries.forEach(function (entry) { 118 if (entry.isIntersecting) { 119 var c = entry.target; 120 observer.unobserve(c); 121 self.renderThumbnail(c, c.dataset.pdfUrl); 122 } 123 }); 124 }, { rootMargin: '200px' }); 125 126 canvases.forEach(function (c) { observer.observe(c); }); 127 } else { 128 canvases.forEach(function (c) { 129 self.renderThumbnail(c, c.dataset.pdfUrl); 130 }); 131 } 132 }); 133 } 134 }; 135 136 // ========================================= 137 // Module 2: Lightbox 138 // ========================================= 139 var Lightbox = { 140 lightboxEl: null, 141 iframe: null, 142 isOpen: false, 143 144 init: function () { 145 this.createLightboxElement(); 146 this.bindEvents(); 147 }, 148 149 createLightboxElement: function () { 150 if (document.querySelector('.ep-pdf-lightbox')) return; 151 152 var lightbox = document.createElement('div'); 153 lightbox.className = 'ep-pdf-lightbox'; 154 lightbox.innerHTML = 155 '<div class="ep-pdf-lightbox__overlay">' + 156 '<button class="ep-pdf-lightbox__close" aria-label="Close">×</button>' + 157 '<div class="ep-pdf-lightbox__viewer">' + 158 '<iframe class="ep-pdf-lightbox__iframe" src="" allowfullscreen></iframe>' + 159 '</div>' + 160 '</div>'; 161 162 document.body.appendChild(lightbox); 163 164 this.lightboxEl = lightbox; 165 this.iframe = lightbox.querySelector('.ep-pdf-lightbox__iframe'); 166 }, 167 168 bindEvents: function () { 169 var self = this; 170 171 // Delegate click on thumbnail wraps 172 document.addEventListener('click', function (e) { 173 var wrap = e.target.closest('.ep-pdf-thumbnail-wrap'); 174 if (!wrap) return; 175 176 e.preventDefault(); 177 self.openFromElement(wrap); 178 }); 179 180 // Close button 181 if (this.lightboxEl) { 182 this.lightboxEl.querySelector('.ep-pdf-lightbox__close').addEventListener('click', function () { 183 self.close(); 184 }); 185 186 // Close on overlay click (not on viewer) 187 this.lightboxEl.querySelector('.ep-pdf-lightbox__overlay').addEventListener('click', function (e) { 188 if (e.target === e.currentTarget) { 189 self.close(); 190 } 191 }); 192 } 193 194 // Keyboard escape 195 document.addEventListener('keydown', function (e) { 196 if (!self.isOpen) return; 197 if (e.key === 'Escape') self.close(); 198 }); 199 }, 200 201 openFromElement: function (wrapEl) { 202 var pdfUrl = wrapEl.dataset.pdfUrl; 203 var viewerStyle = wrapEl.dataset.viewerStyle || 'modern'; 204 var viewerParams = wrapEl.dataset.viewerParams || ''; 205 206 if (!pdfUrl) return; 207 208 var viewerSrc = this.buildViewerUrl(pdfUrl, viewerStyle, viewerParams); 209 this.iframe.src = viewerSrc; 210 211 this.lightboxEl.classList.add('ep-pdf-lightbox--open'); 212 document.body.style.overflow = 'hidden'; 213 this.isOpen = true; 214 }, 215 216 close: function () { 217 if (!this.lightboxEl) return; 218 this.lightboxEl.classList.remove('ep-pdf-lightbox--open'); 219 this.iframe.src = ''; 220 document.body.style.overflow = ''; 221 this.isOpen = false;
222 }, 223 224 buildViewerUrl: function (pdfUrl, viewerStyle, viewerParams) { 225 var encodedFile = encodeURIComponent(pdfUrl); 226 var pdfRenderer = ''; 227 var flipbookRenderer = ''; 228 229 if (typeof embedpressObj !== 'undefined') { 230 pdfRenderer = embedpressObj.pdfRenderer || ''; 231 flipbookRenderer = embedpressObj.flipbookRenderer || ''; 232 } 233 234 if (viewerStyle === 'flip-book' && flipbookRenderer) { 235 return flipbookRenderer + '&file=' + encodedFile + '&key=' + viewerParams; 236 } else if (pdfRenderer) { 237 return pdfRenderer + '&file=' + encodedFile + '#key=' + viewerParams; 238 } 239 240 return pdfUrl; 241 } 242 }; 243 244 // ========================================= 245 // Module 3: Initialization 246 // ========================================= 247 function init() { 248 var thumbnails = document.querySelectorAll('.ep-pdf-thumbnail-wrap'); 249 if (!thumbnails.length) return; 250 251 ThumbnailGenerator.initAll(); 252 Lightbox.init(); 253 } 254 255 if (document.readyState === 'loading') { 256 document.addEventListener('DOMContentLoaded', init); 257 } else { 258 init(); 259 } 260 261 // Elementor re-init support 262 function registerElementorHandler() { 263 if (typeof elementorFrontend === 'undefined') return; 264 elementorFrontend.hooks.addAction( 265 'frontend/element_ready/embedpress_pdf.default', 266 function ($scope) { 267 var canvases = $scope.find('.ep-pdf-thumbnail-canvas[data-pdf-url]'); 268 if (canvases.length) { 269 ThumbnailGenerator.loadPdfJs(function () { 270 if (!window.pdfjsLib) return; 271 canvases.each(function () { 272 ThumbnailGenerator.renderThumbnail(this, this.dataset.pdfUrl); 273 }); 274 }); 275 } 276 if (!Lightbox.lightboxEl) { 277 Lightbox.init(); 278 } 279 } 280 ); 281 } 282 283 if (typeof jQuery !== 'undefined') { 284 // If elementorFrontend is already available, register immediately 285 if (typeof elementorFrontend !== 'undefined') { 286 registerElementorHandler(); 287 } else { 288 // Otherwise wait for it to initialize 289 jQuery(window).on('elementor/frontend/init', registerElementorHandler); 290 } 291 } 292})();
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.