From 5f5c4ef8b498a6558e9b775f7748b7c0dbe3fcb9 Mon Sep 17 00:00:00 2001 From: Timur Sufiev Date: Fri, 12 Sep 2025 12:27:05 +0100 Subject: [PATCH 1/4] feat: truncate pdf page height to fit webpage --- src/worker.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/worker.js b/src/worker.js index 47ee4725..28e9b5b6 100644 --- a/src/worker.js +++ b/src/worker.js @@ -46,6 +46,7 @@ Worker.template = { }, opt: { filename: 'file.pdf', + trimPages: false, margin: [0,0,0,0], image: { type: 'jpeg', quality: 0.95 }, enableLinks: true, @@ -212,10 +213,19 @@ Worker.prototype.toPdf = function toPdf() { pageCtx.drawImage(canvas, 0, page*pxPageHeight, w, h, 0, 0, w, h); // Add the page to the PDF. - if (page) this.prop.pdf.addPage(); + var pageWidth = this.prop.pageSize.inner.width; + if (opt.trimPages) { + this.prop.pdf.addPage([pageWidth, pageHeight], pageWidth > pageHeight ? 'l' : 'p'); + if (!page && !this.prop._firstPageDeleted) { + this.prop.pdf.deletePage(1); + this.prop._firstPageDeleted = true; + } + } else { + if (page) this.prop.pdf.addPage(); + } + var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality); - this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], - this.prop.pageSize.inner.width, pageHeight); + this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], pageWidth, pageHeight); } }); }; From 84f88e827959f25ffaf0d9e8156941f0818933df Mon Sep 17 00:00:00 2001 From: Timur Sufiev Date: Fri, 19 Sep 2025 15:13:08 +0100 Subject: [PATCH 2/4] fix: correctly render pdf pages for `trimPages: false` --- src/worker.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/worker.js b/src/worker.js index 28e9b5b6..1b8226c6 100644 --- a/src/worker.js +++ b/src/worker.js @@ -214,19 +214,18 @@ Worker.prototype.toPdf = function toPdf() { // Add the page to the PDF. var pageWidth = this.prop.pageSize.inner.width; - if (opt.trimPages) { - this.prop.pdf.addPage([pageWidth, pageHeight], pageWidth > pageHeight ? 'l' : 'p'); - if (!page && !this.prop._firstPageDeleted) { - this.prop.pdf.deletePage(1); - this.prop._firstPageDeleted = true; - } - } else { - if (page) this.prop.pdf.addPage(); - } + this.prop.pdf.addPage( + ...(opt.trimPages ? [[pageWidth, pageHeight], pageWidth > pageHeight ? 'l' : 'p'] : []) + ); var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality); this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], pageWidth, pageHeight); } + + if (!this.prop._firstPageDeleted) { + this.prop.pdf.deletePage(1); + this.prop._firstPageDeleted = true; + } }); }; From d421f43b42b4443639764714ed354e99e82f5679 Mon Sep 17 00:00:00 2001 From: Timur Sufiev Date: Sat, 20 Sep 2025 18:24:49 +0100 Subject: [PATCH 3/4] Consider margins for trimmed pages --- src/worker.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/worker.js b/src/worker.js index 1b8226c6..424480fe 100644 --- a/src/worker.js +++ b/src/worker.js @@ -214,12 +214,16 @@ Worker.prototype.toPdf = function toPdf() { // Add the page to the PDF. var pageWidth = this.prop.pageSize.inner.width; + const [mTop, mLeft, mBottom, mRight] = opt.margin || []; + const adjustedPageWidth = pageWidth + mLeft + mRight; + const adjustedPageHeight = pageHeight + mTop + mBottom; + this.prop.pdf.addPage( - ...(opt.trimPages ? [[pageWidth, pageHeight], pageWidth > pageHeight ? 'l' : 'p'] : []) + ...(opt.trimPages ? [[adjustedPageWidth, adjustedPageHeight], adjustedPageWidth > adjustedPageHeight ? 'l' : 'p'] : []) ); var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality); - this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], pageWidth, pageHeight); + this.prop.pdf.addImage(imgData, opt.image.type, mLeft, mTop, pageWidth, pageHeight); } if (!this.prop._firstPageDeleted) { From 369e2e9ae368cbc5630d09924f74ae5bcbff4db9 Mon Sep 17 00:00:00 2001 From: Timur Sufiev Date: Fri, 14 Nov 2025 18:34:55 +0000 Subject: [PATCH 4/4] Support hyperlinks for manually added PDF pages Old mechanism of putting hyperlinks to various pages based on link coordinates and first page height didn't work for the case when pages are added to PDF document programmatically by a client app. Allow to pass a new format of `enableLinks` which tells the hyperlinks plugin in which container should the links be searched in and to which page they should be put. --- src/plugin/hyperlinks.js | 34 +++++++++++++++++++++++----------- type.d.ts | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/plugin/hyperlinks.js b/src/plugin/hyperlinks.js index 8646d235..6df5e43f 100644 --- a/src/plugin/hyperlinks.js +++ b/src/plugin/hyperlinks.js @@ -11,31 +11,43 @@ var orig = { }; Worker.prototype.toContainer = function toContainer() { + var self = this; return orig.toContainer.call(this).then(function toContainer_hyperlink() { // Retrieve hyperlink info if the option is enabled. - if (this.opt.enableLinks) { - // Find all anchor tags and get the container's bounds for reference. - var container = this.prop.container; + + function storeLinkInfo(container, externalPage) { var links = container.querySelectorAll('a'); - var containerRect = unitConvert(container.getBoundingClientRect(), this.prop.pageSize.k); - linkInfo = []; + var containerRect = unitConvert(container.getBoundingClientRect(), self.prop.pageSize.k); // Loop through each anchor tag. Array.prototype.forEach.call(links, function(link) { - // Treat each client rect as a separate link (for text-wrapping). + // Treat each client rect as a separ nmate link (for text-wrapping). var clientRects = link.getClientRects(); for (var i=0; i