akhaliq HF Staff commited on
Commit
1c7c9b7
Β·
1 Parent(s): 069d21e

Use PDF.js canvas rendering instead of blocked iframe for PDF preview

Browse files
Files changed (1) hide show
  1. index.html +44 -17
index.html CHANGED
@@ -172,15 +172,25 @@
172
  #image-preview { width: 100%; height: 100%; object-fit: contain; background: #000; display: none; }
173
  #image-preview.visible { display: block; }
174
 
175
- /* PDF viewer iframe */
176
- #pdf-viewer {
177
  display: none;
178
- width: 100%;
 
 
 
 
179
  height: 100%;
180
- border: none;
181
- background: #fff;
 
 
 
 
 
 
 
182
  }
183
- #pdf-viewer.visible { display: block; }
184
 
185
  /* ── Output ── */
186
  .output-area {
@@ -313,7 +323,7 @@
313
  </div>
314
 
315
  <img id="image-preview" alt="Document preview" />
316
- <iframe id="pdf-viewer" title="PDF viewer"></iframe>
317
 
318
  <div class="prompt-bar">
319
  <span class="prompt-label">PROMPT</span>
@@ -353,6 +363,9 @@
353
 
354
  <script type="module">
355
  import { Client, handle_file } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
 
 
 
356
 
357
  // ── State ─────────────────────────────────────────────────────────────────────
358
  let client = null;
@@ -413,26 +426,40 @@ window.scrollOutputBottom = () => {
413
  };
414
 
415
  // ── File loading ──────────────────────────────────────────────────────────────
416
- function loadFile(file) {
417
  currentFile = file;
418
  isPDF = file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf');
419
 
420
  // Hide drop zone, reset previews
421
  document.getElementById('drop-zone').style.display = 'none';
422
  document.getElementById('image-preview').classList.remove('visible');
423
- document.getElementById('pdf-viewer').classList.remove('visible');
424
  document.getElementById('zoom-btn').style.display = 'flex';
425
  document.getElementById('input-type-tag').textContent =
426
  isPDF ? 'PDF' : file.name.split('.').pop().toUpperCase();
427
 
428
  if (isPDF) {
429
- // Render PDF natively in an iframe using a blob object URL
430
- const pdfURL = URL.createObjectURL(file);
431
- const viewer = document.getElementById('pdf-viewer');
432
- viewer.src = pdfURL;
433
- viewer.classList.add('visible');
434
  document.getElementById('page-info').style.display = 'flex';
435
- document.getElementById('page-count').textContent = '?';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  } else {
437
  const preview = document.getElementById('image-preview');
438
  preview.src = URL.createObjectURL(file);
@@ -643,8 +670,8 @@ function clearAll() {
643
  document.getElementById('drop-zone').style.display = '';
644
  const p = document.getElementById('image-preview');
645
  p.classList.remove('visible'); p.src = '';
646
- const v = document.getElementById('pdf-viewer');
647
- v.classList.remove('visible'); v.src = '';
648
  document.getElementById('zoom-btn').style.display = 'none';
649
  document.getElementById('input-type-tag').textContent = 'EMPTY';
650
  document.getElementById('start-btn').disabled = true;
 
172
  #image-preview { width: 100%; height: 100%; object-fit: contain; background: #000; display: none; }
173
  #image-preview.visible { display: block; }
174
 
175
+ /* PDF.js canvas viewer */
176
+ #pdf-canvas-wrap {
177
  display: none;
178
+ flex-direction: column;
179
+ align-items: center;
180
+ gap: 10px;
181
+ overflow-y: auto;
182
+ padding: 12px;
183
  height: 100%;
184
+ background: #525659;
185
+ }
186
+ #pdf-canvas-wrap.visible { display: flex; }
187
+ #pdf-canvas-wrap canvas {
188
+ display: block;
189
+ width: 100%;
190
+ max-width: 680px;
191
+ box-shadow: 0 2px 10px rgba(0,0,0,0.6);
192
+ border-radius: 2px;
193
  }
 
194
 
195
  /* ── Output ── */
196
  .output-area {
 
323
  </div>
324
 
325
  <img id="image-preview" alt="Document preview" />
326
+ <div id="pdf-canvas-wrap"></div>
327
 
328
  <div class="prompt-bar">
329
  <span class="prompt-label">PROMPT</span>
 
363
 
364
  <script type="module">
365
  import { Client, handle_file } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
366
+ import * as pdfjsLib from "https://cdn.jsdelivr.net/npm/pdfjs-dist@4.4.168/build/pdf.min.mjs";
367
+ pdfjsLib.GlobalWorkerOptions.workerSrc =
368
+ "https://cdn.jsdelivr.net/npm/pdfjs-dist@4.4.168/build/pdf.worker.min.mjs";
369
 
370
  // ── State ─────────────────────────────────────────────────────────────────────
371
  let client = null;
 
426
  };
427
 
428
  // ── File loading ──────────────────────────────────────────────────────────────
429
+ async function loadFile(file) {
430
  currentFile = file;
431
  isPDF = file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf');
432
 
433
  // Hide drop zone, reset previews
434
  document.getElementById('drop-zone').style.display = 'none';
435
  document.getElementById('image-preview').classList.remove('visible');
436
+ document.getElementById('pdf-canvas-wrap').classList.remove('visible');
437
  document.getElementById('zoom-btn').style.display = 'flex';
438
  document.getElementById('input-type-tag').textContent =
439
  isPDF ? 'PDF' : file.name.split('.').pop().toUpperCase();
440
 
441
  if (isPDF) {
442
+ // Render PDF pages with PDF.js into canvases (blob: URLs are blocked in iframes on HTTPS)
443
+ const wrap = document.getElementById('pdf-canvas-wrap');
444
+ wrap.innerHTML = '<div style="color:var(--teal);font-family:var(--font-mono);font-size:11px;padding:20px">Rendering PDF…</div>';
445
+ wrap.classList.add('visible');
 
446
  document.getElementById('page-info').style.display = 'flex';
447
+
448
+ const buffer = await file.arrayBuffer();
449
+ const pdf = await pdfjsLib.getDocument({ data: buffer }).promise;
450
+ const total = pdf.numPages;
451
+ document.getElementById('page-count').textContent = total;
452
+ wrap.innerHTML = '';
453
+
454
+ for (let i = 1; i <= total; i++) {
455
+ const page = await pdf.getPage(i);
456
+ const viewport = page.getViewport({ scale: 2.0 });
457
+ const canvas = document.createElement('canvas');
458
+ canvas.width = viewport.width;
459
+ canvas.height = viewport.height;
460
+ await page.render({ canvasContext: canvas.getContext('2d'), viewport }).promise;
461
+ wrap.appendChild(canvas);
462
+ }
463
  } else {
464
  const preview = document.getElementById('image-preview');
465
  preview.src = URL.createObjectURL(file);
 
670
  document.getElementById('drop-zone').style.display = '';
671
  const p = document.getElementById('image-preview');
672
  p.classList.remove('visible'); p.src = '';
673
+ const v = document.getElementById('pdf-canvas-wrap');
674
+ v.classList.remove('visible'); v.innerHTML = '';
675
  document.getElementById('zoom-btn').style.display = 'none';
676
  document.getElementById('input-type-tag').textContent = 'EMPTY';
677
  document.getElementById('start-btn').disabled = true;