Blogger — PDF List & Viewer

PDF Series Manager — Blogger

यह पेज आपको PDF URLs या लोकल फाइल्स को सीरियली जोड़कर एक सूची बनाने और उन्हें रेस्पॉन्सिव तरीके से देखने देता है। Blogger में HTML मोड में चिपकाएँ।

Tip: Use public PDF links (Google Drive / Dropbox direct link) for persistent embedding.
How to host on Google Drive: upload → Share → Anyone with link can view → use that share URL as PDF URL.
`; // Use srcdoc if supported try{ pdfViewer.srcdoc = wrapper; }catch(e){ pdfViewer.src = fallback; } } // smooth scroll to viewer setTimeout(()=> viewerWrap.scrollIntoView({behavior:'smooth'}),120); } // Add button handler addBtn.addEventListener('click', async ()=>{ const title = titleEl.value.trim(); const url = urlEl.value.trim(); const file = fileEl.files && fileEl.files[0]; if(!url && !file){ alert('PDF का URL डालें या local PDF अपलोड करें'); return } if(file){ const blobUrl = URL.createObjectURL(file); items.push({ title: title || file.name, blobName: file.name, blobUrl, created: Date.now() }); // note: blobUrl will only work in this browser session/device } else { // normalize Dropbox share links (common pattern) to direct link if possible let norm = url; if(norm.includes('dropbox.com') && !norm.includes('dl=1')){ norm = norm.replace('?dl=0','') + (norm.includes('?')?'&dl=1':'?dl=1'); } items.push({ title: title || ('PDF ' + (items.length+1)), url: norm, created: Date.now() }); } titleEl.value=''; urlEl.value=''; fileEl.value=''; save(); renderList(); }); // Export document.getElementById('exportBtn').addEventListener('click', ()=>{ const exportItems = items.map(it=>({title:it.title,url:it.url,created:it.created,blobName:it.blobName})); const blob = new Blob([JSON.stringify(exportItems, null, 2)], {type:'application/json'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'pdf_list.json'; document.body.appendChild(a); a.click(); a.remove(); }); // Import document.getElementById('importBtn').addEventListener('click', ()=>{ const inp = document.createElement('input'); inp.type='file'; inp.accept='.json,application/json'; inp.onchange = e=>{ const f = e.target.files[0]; if(!f) return; const r = new FileReader(); r.onload = ev=>{ try{ const arr = JSON.parse(ev.target.result); if(!Array.isArray(arr)) throw new Error('Invalid file'); // imported entries will not have blobUrl; user should add local files manually if needed arr.forEach(it=> items.push({title: it.title, url: it.url, created: it.created || Date.now()})); save(); renderList(); }catch(err){ alert('Import failed: ' + err.message) } }; r.readAsText(f); }; inp.click(); }); document.getElementById('clearBtn').addEventListener('click', ()=>{ if(confirm('Clear entire list?')){ items=[]; save(); renderList(); }}); // initial render renderList(); // Optional: allow double-click on list item to view listEl.addEventListener('dblclick', e=>{ const node = e.target.closest('.item'); if(!node) return; const idx = Array.from(listEl.children).indexOf(node); if(idx>=0) openViewer(idx); }); // Accessibility: keyboard 'Enter' to add when focused in URL or title [titleEl,urlEl].forEach(el=> el.addEventListener('keydown', ev=>{ if(ev.key==='Enter'){ addBtn.click(); ev.preventDefault(); }}));