diff --git a/changelog.md b/changelog.md index 31d20e7..f3429e5 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2026-01-29 - 3.41.3 - fix(dees-pdf-viewer) +use in-memory PDF data for download and print; add robust print wrapper, cleanup and error handling + +- Download and Print now use pdfDocument.getData() to create Blob URLs so in-memory PDFs (pdf.js) can be saved/printed. +- Print flow now opens an HTML wrapper with an iframe to allow onafterprint handling, auto-close, popup-fallback and timed cleanup of Blob URLs. +- Added try/catch logging, URL.revokeObjectURL calls and safety timeouts to avoid resource leaks. +- Removed context menu items that relied on the raw PDF URL (Open in New Tab, Copy PDF URL); Download/Print actions now await the async handlers. + ## 2026-01-28 - 3.41.2 - fix(dees-pdf-viewer) account for devicePixelRatio when setting canvas dimensions and scale 2D context to render crisp PDF pages and thumbnails on high-DPI displays diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 550e219..1905409 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-catalog', - version: '3.41.2', + version: '3.41.3', description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' } diff --git a/ts_web/elements/00group-media/dees-pdf-viewer/component.ts b/ts_web/elements/00group-media/dees-pdf-viewer/component.ts index 4587ac8..23becde 100644 --- a/ts_web/elements/00group-media/dees-pdf-viewer/component.ts +++ b/ts_web/elements/00group-media/dees-pdf-viewer/component.ts @@ -935,15 +935,98 @@ export class DeesPdfViewer extends DeesElement { }); } - private downloadPdf() { - const link = document.createElement('a'); - link.href = this.pdfUrl; - link.download = this.pdfUrl.split('/').pop() || 'document.pdf'; - link.click(); + private async downloadPdf() { + if (!this.pdfDocument) return; + + try { + // Get raw PDF data from the loaded document + const data = await this.pdfDocument.getData(); + const blob = new Blob([data.buffer], { type: 'application/pdf' }); + const blobUrl = URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.href = blobUrl; + link.download = this.pdfUrl ? this.pdfUrl.split('/').pop() || 'document.pdf' : 'document.pdf'; + link.click(); + + // Clean up blob URL after short delay + setTimeout(() => URL.revokeObjectURL(blobUrl), 1000); + } catch (error) { + console.error('Error downloading PDF:', error); + } } - private printPdf() { - window.open(this.pdfUrl, '_blank')?.print(); + private async printPdf() { + if (!this.pdfDocument) return; + + try { + // Get raw PDF data from the loaded document + const data = await this.pdfDocument.getData(); + const blob = new Blob([data.buffer], { type: 'application/pdf' }); + const pdfUrl = URL.createObjectURL(blob); + + // Create an HTML wrapper page that embeds the PDF and handles print/close + // This gives us control over the afterprint event (direct PDF URLs don't support it) + const htmlContent = ` + + +
+