jspdf-utils 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,7 +58,11 @@ declare function splitOversizedTables(container: HTMLElement, pageContentPx: num
58
58
  * into word-boundary chunks using binary search.
59
59
  */
60
60
  declare function splitOversizedText(container: HTMLElement, pageContentPx: number): void;
61
- /** Insert spacer divs so that no direct child straddles a page boundary. */
61
+ /**
62
+ * Insert spacer divs so that no direct child straddles a page boundary.
63
+ * For tables and text elements, attempts to split at the boundary first
64
+ * so content fills the current page before flowing to the next.
65
+ */
62
66
  declare function insertPageBreakSpacers(container: HTMLElement, pageContentPx: number): void;
63
67
  /**
64
68
  * Prepare an HTML element for doc.html() rendering.
@@ -70,15 +74,79 @@ declare function prepare(source: HTMLElement, opts?: Partial<PageOptions>): Prep
70
74
  /**
71
75
  * Render an HTML element to PDF using doc.html().
72
76
  */
73
- declare function renderHTML(doc: jsPDF, source: HTMLElement, opts?: Partial<PageOptions>): Promise<jsPDF>;
77
+ declare function renderHTML(doc: jsPDF, source: HTMLElement, opts?: Partial<PageOptions> & Pick<ImagePDFOptions, "marginContent">): Promise<jsPDF>;
78
+ type MarginFactory = (page: number, totalPages: number) => HTMLElement;
79
+ export interface ContentBorder {
80
+ /** Stroke color (default: "#000000") */
81
+ color?: string;
82
+ /** Line width in mm (default: 0.3) */
83
+ width?: number;
84
+ /** Distance in mm from the page edge to the border (default: uses page margins). */
85
+ margin?: number | {
86
+ top?: number;
87
+ right?: number;
88
+ bottom?: number;
89
+ left?: number;
90
+ };
91
+ }
92
+ export interface TextBorder {
93
+ /** The text to repeat along all four edges. */
94
+ text: string;
95
+ /** Text color (default: "#000000") */
96
+ color?: string;
97
+ /** Font size in mm (default: 2.5) */
98
+ fontSize?: number;
99
+ /** Font family (default: "Arial, sans-serif") */
100
+ fontFamily?: string;
101
+ /** Gap between repetitions in mm (default: fontSize * 0.5) */
102
+ gap?: number;
103
+ /** Distance in mm from the page edge to the text border (default: uses page margins). */
104
+ margin?: number | {
105
+ top?: number;
106
+ right?: number;
107
+ bottom?: number;
108
+ left?: number;
109
+ };
110
+ }
111
+ export interface MarginContentInput {
112
+ top?: HTMLElement | MarginFactory;
113
+ right?: HTMLElement | MarginFactory;
114
+ bottom?: HTMLElement | MarginFactory;
115
+ left?: HTMLElement | MarginFactory;
116
+ /** Draw a rectangle border around the content area. */
117
+ contentBorder?: ContentBorder;
118
+ /** Draw a repeated-text border around the content area. */
119
+ textBorder?: TextBorder;
120
+ }
74
121
  export interface ImagePDFOptions {
75
122
  imageFormat?: "JPEG" | "PNG";
76
123
  imageQuality?: number;
77
124
  scale?: number;
125
+ marginContent?: MarginContentInput;
78
126
  }
79
127
  /**
80
128
  * Render an HTML element as an image-based PDF. Each page is a rasterized
81
129
  * screenshot — no selectable or extractable text in the output.
82
130
  */
83
131
  declare function renderImagePDF(source: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<jsPDF>;
84
- export { PAGE_SIZES, PAGE_MARGINS, computeLayout, createPrintClone, normalizeTableAttributes, splitOversizedTables, splitOversizedText, insertPageBreakSpacers, prepare, renderHTML, renderImagePDF, };
132
+ /**
133
+ * Render an HTML element to an array of page images (data URLs).
134
+ * Each image represents a full page with margins, matching the
135
+ * visual output of renderImagePDF.
136
+ */
137
+ declare function renderPageImages(source: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<string[]>;
138
+ /**
139
+ * Render an HTML element as page images and inject them into a scrollable
140
+ * container. Each image is sized to match the page format dimensions.
141
+ */
142
+ declare function previewPageImages(source: HTMLElement, container: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<void>;
143
+ /**
144
+ * Add HTML content to the margin areas of each page in a jsPDF document.
145
+ *
146
+ * Each slot (top, right, bottom, left) accepts either a static HTMLElement
147
+ * (rendered once and reused on every page) or a factory function that
148
+ * receives `(page, totalPages)` and returns an HTMLElement per page
149
+ * (useful for page numbers or dynamic content).
150
+ */
151
+ declare function addMarginContent(doc: jsPDF, content: MarginContentInput, opts?: Partial<PageOptions>): Promise<jsPDF>;
152
+ export { PAGE_SIZES, PAGE_MARGINS, computeLayout, createPrintClone, normalizeTableAttributes, splitOversizedTables, splitOversizedText, insertPageBreakSpacers, prepare, renderHTML, renderImagePDF, renderPageImages, previewPageImages, addMarginContent, };
@@ -1,5 +1,5 @@
1
- import j from "html2canvas";
2
- const T = {
1
+ import W from "html2canvas";
2
+ const q = {
3
3
  a0: [841, 1189],
4
4
  a1: [594, 841],
5
5
  a2: [420, 594],
@@ -10,7 +10,7 @@ const T = {
10
10
  letter: [215.9, 279.4],
11
11
  legal: [215.9, 355.6],
12
12
  tabloid: [279.4, 431.8]
13
- }, B = {
13
+ }, $ = {
14
14
  a0: 40,
15
15
  a1: 35,
16
16
  a2: 30,
@@ -22,211 +22,508 @@ const T = {
22
22
  legal: 25.4,
23
23
  tabloid: 25
24
24
  };
25
- function v(i = {}) {
26
- const n = i.format ?? "a4", [o, e] = T[n], a = i.pageWidth ?? o, t = i.pageHeight ?? e, s = B[n], r = {
25
+ function M(t = {}) {
26
+ const e = t.format ?? "a4", [a, n] = q[e], i = t.pageWidth ?? a, o = t.pageHeight ?? n, s = $[e], r = {
27
27
  top: s,
28
28
  right: s,
29
29
  bottom: s,
30
30
  left: s
31
31
  };
32
32
  return {
33
- unit: i.unit ?? "mm",
34
- format: n,
35
- pageWidth: a,
36
- pageHeight: t,
37
- margin: { ...r, ...i.margin }
33
+ unit: t.unit ?? "mm",
34
+ format: e,
35
+ pageWidth: i,
36
+ pageHeight: o,
37
+ margin: { ...r, ...t.margin }
38
38
  };
39
39
  }
40
- function x(i, n) {
41
- const o = i.offsetWidth, e = n.pageWidth - n.margin.left - n.margin.right, a = e / o, s = (n.pageHeight - n.margin.top - n.margin.bottom) / a;
42
- return { renderedWidth: o, scale: a, contentWidthMm: e, pageContentPx: s };
40
+ function x(t, e) {
41
+ const a = t.offsetWidth, n = e.pageWidth - e.margin.left - e.margin.right, i = n / a, s = (e.pageHeight - e.margin.top - e.margin.bottom) / i;
42
+ return { renderedWidth: a, scale: i, contentWidthMm: n, pageContentPx: s };
43
43
  }
44
- function A(i, n = 210) {
45
- const o = i.cloneNode(!0);
46
- return Object.assign(o.style, {
44
+ function B(t, e = 210) {
45
+ const a = t.cloneNode(!0);
46
+ return Object.assign(a.style, {
47
47
  position: "fixed",
48
48
  top: "0",
49
49
  left: "0",
50
50
  boxSizing: "border-box",
51
- width: n + "mm",
51
+ width: e + "mm",
52
52
  opacity: "0.000001",
53
53
  pointerEvents: "none"
54
- }), document.body.appendChild(o), o;
55
- }
56
- function C() {
57
- const i = document.createElement("style");
58
- return i.setAttribute("data-jspdf-utils", ""), i.textContent = "img { display: inline !important; }", document.head.appendChild(i), () => i.remove();
59
- }
60
- function W(i) {
61
- for (const n of i.querySelectorAll("table")) {
62
- const o = n.getAttribute("cellpadding");
63
- if (o) {
64
- for (const e of n.querySelectorAll("th, td"))
65
- e.style.padding || (e.style.padding = o + "px");
66
- n.removeAttribute("cellpadding");
54
+ }), document.body.appendChild(a), a;
55
+ }
56
+ function N() {
57
+ const t = document.createElement("style");
58
+ return t.setAttribute("data-jspdf-utils", ""), t.textContent = "img { display: inline !important; }", document.head.appendChild(t), () => t.remove();
59
+ }
60
+ function E(t) {
61
+ for (const e of t.querySelectorAll("table")) {
62
+ const a = e.getAttribute("cellpadding");
63
+ if (a) {
64
+ for (const n of e.querySelectorAll("th, td"))
65
+ n.style.padding || (n.style.padding = a + "px");
66
+ e.removeAttribute("cellpadding");
67
67
  }
68
68
  }
69
69
  }
70
- function P(i, n) {
71
- for (const o of Array.from(
72
- i.querySelectorAll(":scope > table")
70
+ function T(t, e) {
71
+ for (const a of Array.from(
72
+ t.querySelectorAll(":scope > table")
73
73
  )) {
74
- if (o.offsetHeight <= n) continue;
75
- const e = Array.from(o.rows);
76
- if (e.length === 0) continue;
77
- const a = e[0].querySelector("th") !== null, t = a ? e[0] : null, s = a ? e.slice(1) : e, r = t ? t.offsetHeight : 0, d = n - r - 2, f = [];
78
- let g = [], l = 0;
79
- for (const h of s) {
80
- const c = h.offsetHeight;
81
- l + c > d && g.length > 0 && (f.push(g), g = [], l = 0), g.push(h), l += c;
74
+ if (a.offsetHeight <= e) continue;
75
+ const n = Array.from(a.rows);
76
+ if (n.length === 0) continue;
77
+ const i = n[0].querySelector("th") !== null, o = i ? n[0] : null, s = i ? n.slice(1) : n, r = o ? o.offsetHeight : 0, l = e - r - 2, d = [];
78
+ let c = [], g = 0;
79
+ for (const m of s) {
80
+ const h = m.offsetHeight;
81
+ g + h > l && c.length > 0 && (d.push(c), c = [], g = 0), c.push(m), g += h;
82
82
  }
83
- g.length > 0 && f.push(g);
84
- for (const h of f) {
85
- const c = o.cloneNode(!1);
86
- t && c.appendChild(t.cloneNode(!0));
87
- for (const m of h) c.appendChild(m.cloneNode(!0));
88
- o.parentNode.insertBefore(c, o);
83
+ c.length > 0 && d.push(c);
84
+ for (const m of d) {
85
+ const h = a.cloneNode(!1);
86
+ o && h.appendChild(o.cloneNode(!0));
87
+ for (const f of m) h.appendChild(f.cloneNode(!0));
88
+ a.parentNode.insertBefore(h, a);
89
89
  }
90
- o.remove();
90
+ a.remove();
91
91
  }
92
92
  }
93
- function S(i, n) {
94
- for (const o of Array.from(i.querySelectorAll(":scope > *"))) {
95
- const e = o;
96
- if (e.offsetHeight <= n || e.tagName === "TABLE")
93
+ function R(t, e) {
94
+ for (const a of Array.from(t.querySelectorAll(":scope > *"))) {
95
+ const n = a;
96
+ if (n.offsetHeight <= e || n.tagName === "TABLE")
97
97
  continue;
98
- const a = e.tagName, t = e.getAttribute("style") || "", s = getComputedStyle(e).width, r = (e.textContent || "").split(/\s+/).filter(Boolean), d = document.createElement(a);
99
- d.setAttribute("style", t), Object.assign(d.style, {
98
+ const i = n.tagName, o = n.getAttribute("style") || "", s = getComputedStyle(n).width, r = (n.textContent || "").split(/\s+/).filter(Boolean), l = document.createElement(i);
99
+ l.setAttribute("style", o), Object.assign(l.style, {
100
100
  position: "absolute",
101
101
  visibility: "hidden",
102
102
  width: s
103
- }), i.appendChild(d);
104
- const f = [];
105
- let g = 0;
106
- for (; g < r.length; ) {
107
- let l = g + 1, h = r.length;
108
- for (; l < h; ) {
109
- const m = Math.ceil((l + h) / 2);
110
- d.textContent = r.slice(g, m).join(" "), d.offsetHeight <= n ? l = m : h = m - 1;
103
+ }), t.appendChild(l);
104
+ const d = [];
105
+ let c = 0;
106
+ for (; c < r.length; ) {
107
+ let g = c + 1, m = r.length;
108
+ for (; g < m; ) {
109
+ const f = Math.ceil((g + m) / 2);
110
+ l.textContent = r.slice(c, f).join(" "), l.offsetHeight <= e ? g = f : m = f - 1;
111
111
  }
112
- const c = document.createElement(a);
113
- c.setAttribute("style", t), c.textContent = r.slice(g, l).join(" "), f.push(c), g = l;
112
+ const h = document.createElement(i);
113
+ h.setAttribute("style", o), h.textContent = r.slice(c, g).join(" "), d.push(h), c = g;
114
114
  }
115
- d.remove();
116
- for (const l of f)
117
- e.parentNode.insertBefore(l, e);
118
- e.remove();
119
- }
120
- }
121
- function M(i, n) {
122
- const o = Array.from(i.children);
123
- for (const e of o) {
124
- const a = e.offsetTop, t = a + e.offsetHeight, s = (Math.floor(a / n) + 1) * n;
125
- if (t > s && e.offsetHeight <= n) {
126
- const r = document.createElement("div");
127
- r.style.height = s - a + 1 + "px", e.parentNode.insertBefore(r, e);
115
+ l.remove();
116
+ for (const g of d)
117
+ n.parentNode.insertBefore(g, n);
118
+ n.remove();
119
+ }
120
+ }
121
+ function U(t, e, a) {
122
+ const n = Array.from(t.rows);
123
+ if (n.length === 0) return !1;
124
+ const i = n[0].querySelector("th") !== null, o = i ? n[0] : null, s = i ? n.slice(1) : n, r = o ? o.offsetHeight : 0;
125
+ if (s.length < 2) return !1;
126
+ const l = a - r - 2;
127
+ if (l <= 0) return !1;
128
+ let d = 0, c = 0;
129
+ for (const h of s) {
130
+ if (c + h.offsetHeight > l) break;
131
+ c += h.offsetHeight, d++;
132
+ }
133
+ if (d === 0 || d === s.length) return !1;
134
+ const g = t.cloneNode(!1);
135
+ o && g.appendChild(o.cloneNode(!0));
136
+ for (let h = 0; h < d; h++)
137
+ g.appendChild(s[h].cloneNode(!0));
138
+ const m = t.cloneNode(!1);
139
+ o && m.appendChild(o.cloneNode(!0));
140
+ for (let h = d; h < s.length; h++)
141
+ m.appendChild(s[h].cloneNode(!0));
142
+ return e.insertBefore(g, t), e.insertBefore(m, t), t.remove(), !0;
143
+ }
144
+ function _(t, e, a) {
145
+ if (t.tagName === "TABLE" || t.tagName === "IMG") return !1;
146
+ const n = (t.textContent || "").split(/\s+/).filter(Boolean);
147
+ if (n.length < 2) return !1;
148
+ const i = t.tagName, o = t.getAttribute("style") || "", s = getComputedStyle(t).width, r = document.createElement(i);
149
+ if (r.setAttribute("style", o), Object.assign(r.style, {
150
+ position: "absolute",
151
+ visibility: "hidden",
152
+ width: s
153
+ }), e.appendChild(r), r.textContent = n[0], r.offsetHeight > a)
154
+ return r.remove(), !1;
155
+ let l = 1, d = n.length;
156
+ for (; l < d; ) {
157
+ const m = Math.ceil((l + d) / 2);
158
+ r.textContent = n.slice(0, m).join(" "), r.offsetHeight <= a ? l = m : d = m - 1;
159
+ }
160
+ if (r.remove(), l >= n.length) return !1;
161
+ const c = document.createElement(i);
162
+ c.setAttribute("style", o), c.textContent = n.slice(0, l).join(" ");
163
+ const g = document.createElement(i);
164
+ return g.setAttribute("style", o), g.textContent = n.slice(l).join(" "), e.insertBefore(c, t), e.insertBefore(g, t), t.remove(), !0;
165
+ }
166
+ function j(t, e) {
167
+ let a = 0;
168
+ for (; a < t.children.length; ) {
169
+ const n = t.children[a], i = n.offsetTop, o = i + n.offsetHeight, s = (Math.floor(i / e) + 1) * e;
170
+ if (o > s) {
171
+ const r = s - i;
172
+ if (n.tagName === "TABLE") {
173
+ if (U(
174
+ n,
175
+ t,
176
+ r
177
+ ))
178
+ continue;
179
+ } else if (_(n, t, r))
180
+ continue;
181
+ if (n.offsetHeight <= e) {
182
+ const l = document.createElement("div");
183
+ l.style.height = s - i + 1 + "px", n.parentNode.insertBefore(l, n), a++;
184
+ }
128
185
  }
186
+ a++;
129
187
  }
130
188
  }
131
- function k(i, n = {}) {
132
- const o = v(n), e = C(), a = A(i, o.pageWidth);
133
- W(a);
134
- const t = x(a, o);
135
- return P(a, t.pageContentPx), S(a, t.pageContentPx), M(a, t.pageContentPx), {
136
- clone: a,
137
- layout: t,
138
- options: o,
189
+ function J(t, e = {}) {
190
+ const a = M(e), n = N(), i = B(t, a.pageWidth);
191
+ E(i);
192
+ const o = x(i, a);
193
+ return T(i, o.pageContentPx), R(i, o.pageContentPx), j(i, o.pageContentPx), {
194
+ clone: i,
195
+ layout: o,
196
+ options: a,
139
197
  cleanup: () => {
140
- a.remove(), e();
198
+ i.remove(), n();
141
199
  }
142
200
  };
143
201
  }
144
- async function F(i, n, o = {}) {
145
- const { clone: e, layout: a, options: t, cleanup: s } = k(n, o);
202
+ async function Y(t, e, a = {}) {
203
+ const { clone: n, layout: i, options: o, cleanup: s } = J(e, a);
146
204
  try {
147
205
  await new Promise((r) => {
148
- i.html(e, {
206
+ t.html(n, {
149
207
  callback: () => r(),
150
- width: a.contentWidthMm,
151
- windowWidth: a.renderedWidth,
208
+ width: i.contentWidthMm,
209
+ windowWidth: i.renderedWidth,
152
210
  margin: [
153
- t.margin.top,
154
- t.margin.right,
155
- t.margin.bottom,
156
- t.margin.left
211
+ o.margin.top,
212
+ o.margin.right,
213
+ o.margin.bottom,
214
+ o.margin.left
157
215
  ]
158
216
  });
159
217
  });
160
218
  } finally {
161
219
  s();
162
220
  }
163
- return i;
221
+ return a.marginContent && await z(t, a.marginContent, a), t;
222
+ }
223
+ function k(t, e) {
224
+ switch (t) {
225
+ case "top":
226
+ return { x: 0, y: 0, width: e.pageWidth, height: e.margin.top };
227
+ case "bottom":
228
+ return {
229
+ x: 0,
230
+ y: e.pageHeight - e.margin.bottom,
231
+ width: e.pageWidth,
232
+ height: e.margin.bottom
233
+ };
234
+ case "left":
235
+ return { x: 0, y: 0, width: e.margin.left, height: e.pageHeight };
236
+ case "right":
237
+ return {
238
+ x: e.pageWidth - e.margin.right,
239
+ y: 0,
240
+ width: e.margin.right,
241
+ height: e.pageHeight
242
+ };
243
+ }
244
+ }
245
+ async function L(t, e, a, n) {
246
+ const i = document.createElement("div");
247
+ Object.assign(i.style, {
248
+ position: "fixed",
249
+ left: "-99999px",
250
+ top: "0",
251
+ width: e + "mm",
252
+ height: a + "mm",
253
+ overflow: "hidden"
254
+ }), i.appendChild(t), document.body.appendChild(i);
255
+ try {
256
+ return await W(i, {
257
+ scale: n,
258
+ backgroundColor: null
259
+ });
260
+ } finally {
261
+ i.remove();
262
+ }
263
+ }
264
+ const D = ["top", "right", "bottom", "left"];
265
+ async function F(t, e, a) {
266
+ const n = {};
267
+ for (const i of D) {
268
+ const o = t[i];
269
+ if (o && typeof o != "function") {
270
+ const s = k(i, e);
271
+ n[i] = await L(
272
+ o.cloneNode(!0),
273
+ s.width,
274
+ s.height,
275
+ a
276
+ );
277
+ }
278
+ }
279
+ return n;
280
+ }
281
+ function Q(t, e) {
282
+ return t == null ? e.margin : typeof t == "number" ? { top: t, right: t, bottom: t, left: t } : {
283
+ top: t.top ?? e.margin.top,
284
+ right: t.right ?? e.margin.right,
285
+ bottom: t.bottom ?? e.margin.bottom,
286
+ left: t.left ?? e.margin.left
287
+ };
288
+ }
289
+ function Z(t, e, a, n, i, o, s) {
290
+ const {
291
+ text: r,
292
+ color: l = "#000000",
293
+ fontSize: d = 2.5,
294
+ fontFamily: c = "Arial, sans-serif"
295
+ } = e, g = d * a, m = (e.gap ?? d * 0.5) * a;
296
+ t.save(), t.fillStyle = l, t.font = `${g}px ${c}`, t.textBaseline = "middle";
297
+ const h = t.measureText(r).width + m;
298
+ t.save(), t.beginPath(), t.rect(n, i - g, o, g * 2), t.clip();
299
+ for (let f = n; f < n + o; f += h)
300
+ t.fillText(r, f, i);
301
+ t.restore(), t.save(), t.beginPath(), t.rect(n, i + s - g, o, g * 2), t.clip();
302
+ for (let f = n; f < n + o; f += h)
303
+ t.fillText(r, f, i + s);
304
+ t.restore(), t.save(), t.translate(n, i + s), t.rotate(-Math.PI / 2), t.beginPath(), t.rect(0, -g, s, g * 2), t.clip();
305
+ for (let f = 0; f < s; f += h)
306
+ t.fillText(r, f, 0);
307
+ t.restore(), t.save(), t.translate(n + o, i), t.rotate(Math.PI / 2), t.beginPath(), t.rect(0, -g, s, g * 2), t.clip();
308
+ for (let f = 0; f < s; f += h)
309
+ t.fillText(r, f, 0);
310
+ t.restore(), t.restore();
311
+ }
312
+ function I(t, e) {
313
+ return Q(t.margin, e);
314
+ }
315
+ async function G(t, e, a, n, i, o, s, r) {
316
+ for (const l of D) {
317
+ const d = e[l];
318
+ if (!d) continue;
319
+ const c = k(l, n);
320
+ let g;
321
+ typeof d == "function" ? g = await L(
322
+ d(o, s),
323
+ c.width,
324
+ c.height,
325
+ r
326
+ ) : g = a[l], t.drawImage(
327
+ g,
328
+ 0,
329
+ 0,
330
+ g.width,
331
+ g.height,
332
+ Math.round(c.x * i),
333
+ Math.round(c.y * i),
334
+ Math.round(c.width * i),
335
+ Math.round(c.height * i)
336
+ );
337
+ }
338
+ if (e.contentBorder) {
339
+ const { color: l = "#000000", width: d = 0.3 } = e.contentBorder, c = I(e.contentBorder, n);
340
+ t.strokeStyle = l, t.lineWidth = d * i, t.strokeRect(
341
+ Math.round(c.left * i),
342
+ Math.round(c.top * i),
343
+ Math.round((n.pageWidth - c.left - c.right) * i),
344
+ Math.round((n.pageHeight - c.top - c.bottom) * i)
345
+ );
346
+ }
347
+ if (e.textBorder) {
348
+ const l = I(e.textBorder, n);
349
+ Z(
350
+ t,
351
+ e.textBorder,
352
+ i,
353
+ Math.round(l.left * i),
354
+ Math.round(l.top * i),
355
+ Math.round((n.pageWidth - l.left - l.right) * i),
356
+ Math.round((n.pageHeight - l.top - l.bottom) * i)
357
+ );
358
+ }
164
359
  }
165
- async function O(i, n = {}) {
166
- const { imageFormat: o = "JPEG", imageQuality: e = 1, scale: a = 2 } = n, t = v(n), s = C(), r = A(i, t.pageWidth);
167
- r.style.opacity = "1", r.style.left = "-99999px", W(r);
168
- const d = x(r, t);
169
- P(r, d.pageContentPx), S(r, d.pageContentPx), M(r, d.pageContentPx);
360
+ async function X(t, e = {}) {
361
+ const { imageFormat: a = "JPEG", imageQuality: n = 1, scale: i = 2 } = e, o = M(e), s = N(), r = B(t, o.pageWidth);
362
+ r.style.opacity = "1", r.style.left = "-99999px", E(r);
363
+ const l = x(r, o);
364
+ T(r, l.pageContentPx), R(r, l.pageContentPx), j(r, l.pageContentPx);
170
365
  try {
171
- const f = await j(r, {
172
- scale: a,
366
+ const d = await W(r, {
367
+ scale: i,
173
368
  backgroundColor: "#ffffff"
174
- }), { jsPDF: g } = await import("jspdf"), l = t.pageWidth - t.margin.left - t.margin.right, h = t.pageHeight - t.margin.top - t.margin.bottom, c = f.width, m = h / l * c, E = Math.ceil(f.height / m), H = t.pageWidth > t.pageHeight ? "l" : "p", w = new g({
175
- orientation: H,
369
+ }), { jsPDF: c } = await import("jspdf"), g = o.pageWidth - o.margin.left - o.margin.right, m = o.pageHeight - o.margin.top - o.margin.bottom, h = d.width, f = m / g * h, P = Math.ceil(d.height / f), v = o.pageWidth > o.pageHeight ? "l" : "p", C = new c({
370
+ orientation: v,
176
371
  unit: "mm",
177
- format: [t.pageWidth, t.pageHeight]
372
+ format: [o.pageWidth, o.pageHeight]
178
373
  });
179
- for (let u = 0; u < E; u++) {
374
+ for (let y = 0; y < P; y++) {
180
375
  const p = Math.min(
181
- m,
182
- f.height - u * m
183
- ), y = document.createElement("canvas");
184
- y.width = c, y.height = p;
185
- const b = y.getContext("2d");
186
- if (!b) throw new Error("Could not get canvas context");
187
- b.fillStyle = "#ffffff", b.fillRect(0, 0, c, p), b.drawImage(
188
376
  f,
377
+ d.height - y * f
378
+ ), w = document.createElement("canvas");
379
+ w.width = h, w.height = p;
380
+ const u = w.getContext("2d");
381
+ if (!u) throw new Error("Could not get canvas context");
382
+ u.fillStyle = "#ffffff", u.fillRect(0, 0, h, p), u.drawImage(
383
+ d,
189
384
  0,
190
- u * m,
191
- c,
385
+ y * f,
386
+ h,
192
387
  p,
193
388
  0,
194
389
  0,
195
- c,
390
+ h,
196
391
  p
197
392
  );
198
- const N = y.toDataURL(
199
- `image/${o.toLowerCase()}`,
200
- e
393
+ const A = w.toDataURL(
394
+ `image/${a.toLowerCase()}`,
395
+ n
201
396
  );
202
- u > 0 && w.addPage([t.pageWidth, t.pageHeight], H);
203
- const R = p / c * l;
204
- w.addImage(
205
- N,
206
- o,
207
- t.margin.left,
208
- t.margin.top,
209
- l,
210
- R,
397
+ y > 0 && C.addPage([o.pageWidth, o.pageHeight], v);
398
+ const b = p / h * g;
399
+ C.addImage(
400
+ A,
401
+ a,
402
+ o.margin.left,
403
+ o.margin.top,
404
+ g,
405
+ b,
211
406
  void 0,
212
407
  "FAST"
213
408
  );
214
409
  }
410
+ return e.marginContent && await z(C, e.marginContent, e), C;
411
+ } finally {
412
+ r.remove(), s();
413
+ }
414
+ }
415
+ async function K(t, e = {}) {
416
+ const { imageFormat: a = "PNG", imageQuality: n = 1, scale: i = 2 } = e, o = M(e), s = N(), r = B(t, o.pageWidth);
417
+ r.style.opacity = "1", r.style.left = "-99999px", E(r);
418
+ const l = x(r, o);
419
+ T(r, l.pageContentPx), R(r, l.pageContentPx), j(r, l.pageContentPx);
420
+ try {
421
+ const d = await W(r, {
422
+ scale: i,
423
+ backgroundColor: "#ffffff"
424
+ }), c = o.pageWidth - o.margin.left - o.margin.right, g = o.pageHeight - o.margin.top - o.margin.bottom, m = d.width, h = g / c * m, f = m / c, P = Math.round(o.pageWidth * f), v = Math.round(o.pageHeight * f), C = Math.round(o.margin.top * f), y = Math.round(o.margin.left * f), p = Math.ceil(d.height / h), w = [], { marginContent: u } = e, A = u ? await F(u, o, i) : {};
425
+ for (let b = 0; b < p; b++) {
426
+ const O = Math.min(
427
+ h,
428
+ d.height - b * h
429
+ ), S = document.createElement("canvas");
430
+ S.width = P, S.height = v;
431
+ const H = S.getContext("2d");
432
+ if (!H) throw new Error("Could not get canvas context");
433
+ H.fillStyle = "#ffffff", H.fillRect(0, 0, P, v), H.drawImage(
434
+ d,
435
+ 0,
436
+ b * h,
437
+ m,
438
+ O,
439
+ y,
440
+ C,
441
+ m,
442
+ O
443
+ ), u && await G(
444
+ H,
445
+ u,
446
+ A,
447
+ o,
448
+ f,
449
+ b + 1,
450
+ p,
451
+ i
452
+ ), w.push(
453
+ S.toDataURL(
454
+ `image/${a.toLowerCase()}`,
455
+ n
456
+ )
457
+ );
458
+ }
215
459
  return w;
216
460
  } finally {
217
461
  r.remove(), s();
218
462
  }
219
463
  }
464
+ async function tt(t, e, a = {}) {
465
+ const n = M(a), i = await K(t, a);
466
+ e.innerHTML = "", Object.assign(e.style, {
467
+ width: "fit-content",
468
+ height: n.pageHeight + "mm",
469
+ maxHeight: "100vh",
470
+ overflowY: "auto",
471
+ background: "#e0e0e0"
472
+ });
473
+ for (let o = 0; o < i.length; o++) {
474
+ const s = document.createElement("img");
475
+ s.src = i[o], s.alt = `Page ${o + 1}`, Object.assign(s.style, {
476
+ width: n.pageWidth + "mm",
477
+ maxWidth: "100%",
478
+ height: "auto",
479
+ boxSizing: "border-box",
480
+ display: "block",
481
+ border: "1px solid #bbb",
482
+ boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
483
+ marginBottom: "16px"
484
+ }), e.appendChild(s);
485
+ }
486
+ }
487
+ async function z(t, e, a = {}) {
488
+ const n = M(a), i = t.getNumberOfPages(), o = 2, s = o * (96 / 25.4), r = Math.round(n.pageWidth * s), l = Math.round(n.pageHeight * s), d = await F(e, n, o);
489
+ for (let c = 1; c <= i; c++) {
490
+ t.setPage(c);
491
+ const g = document.createElement("canvas");
492
+ g.width = r, g.height = l;
493
+ const m = g.getContext("2d");
494
+ m && (await G(
495
+ m,
496
+ e,
497
+ d,
498
+ n,
499
+ s,
500
+ c,
501
+ i,
502
+ o
503
+ ), t.addImage(
504
+ g.toDataURL("image/png"),
505
+ "PNG",
506
+ 0,
507
+ 0,
508
+ n.pageWidth,
509
+ n.pageHeight
510
+ ));
511
+ }
512
+ return t;
513
+ }
220
514
  export {
221
- B as PAGE_MARGINS,
222
- T as PAGE_SIZES,
515
+ $ as PAGE_MARGINS,
516
+ q as PAGE_SIZES,
517
+ z as addMarginContent,
223
518
  x as computeLayout,
224
- A as createPrintClone,
225
- M as insertPageBreakSpacers,
226
- W as normalizeTableAttributes,
227
- k as prepare,
228
- F as renderHTML,
229
- O as renderImagePDF,
230
- P as splitOversizedTables,
231
- S as splitOversizedText
519
+ B as createPrintClone,
520
+ j as insertPageBreakSpacers,
521
+ E as normalizeTableAttributes,
522
+ J as prepare,
523
+ tt as previewPageImages,
524
+ Y as renderHTML,
525
+ X as renderImagePDF,
526
+ K as renderPageImages,
527
+ T as splitOversizedTables,
528
+ R as splitOversizedText
232
529
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspdf-utils",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Utility helpers for jsPDF's doc.html() renderer with automatic page breaking, table splitting, and RTL support",
5
5
  "type": "module",
6
6
  "main": "dist/html-to-pdf.js",