jspdf-utils 0.1.6 → 0.1.7

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.
@@ -81,4 +81,15 @@ export interface ImagePDFOptions {
81
81
  * screenshot — no selectable or extractable text in the output.
82
82
  */
83
83
  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, };
84
+ /**
85
+ * Render an HTML element to an array of page images (data URLs).
86
+ * Each image represents a full page with margins, matching the
87
+ * visual output of renderImagePDF.
88
+ */
89
+ declare function renderPageImages(source: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<string[]>;
90
+ /**
91
+ * Render an HTML element as page images and inject them into a scrollable
92
+ * container. Each image is sized to match the page format dimensions.
93
+ */
94
+ declare function previewPageImages(source: HTMLElement, container: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<void>;
95
+ export { PAGE_SIZES, PAGE_MARGINS, computeLayout, createPrintClone, normalizeTableAttributes, splitOversizedTables, splitOversizedText, insertPageBreakSpacers, prepare, renderHTML, renderImagePDF, renderPageImages, previewPageImages, };
@@ -1,5 +1,5 @@
1
- import j from "html2canvas";
2
- const T = {
1
+ import T from "html2canvas";
2
+ const k = {
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
+ }, L = {
14
14
  a0: 40,
15
15
  a1: 35,
16
16
  a2: 30,
@@ -22,133 +22,133 @@ 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 = {
27
- top: s,
28
- right: s,
29
- bottom: s,
30
- left: s
25
+ function W(i = {}) {
26
+ const e = i.format ?? "a4", [o, n] = k[e], r = i.pageWidth ?? o, t = i.pageHeight ?? n, c = L[e], a = {
27
+ top: c,
28
+ right: c,
29
+ bottom: c,
30
+ left: c
31
31
  };
32
32
  return {
33
33
  unit: i.unit ?? "mm",
34
- format: n,
35
- pageWidth: a,
34
+ format: e,
35
+ pageWidth: r,
36
36
  pageHeight: t,
37
- margin: { ...r, ...i.margin }
37
+ margin: { ...a, ...i.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 M(i, e) {
41
+ const o = i.offsetWidth, n = e.pageWidth - e.margin.left - e.margin.right, r = n / o, c = (e.pageHeight - e.margin.top - e.margin.bottom) / r;
42
+ return { renderedWidth: o, scale: r, contentWidthMm: n, pageContentPx: c };
43
43
  }
44
- function A(i, n = 210) {
44
+ function A(i, e = 210) {
45
45
  const o = i.cloneNode(!0);
46
46
  return Object.assign(o.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
54
  }), document.body.appendChild(o), o;
55
55
  }
56
- function C() {
56
+ function S() {
57
57
  const i = document.createElement("style");
58
58
  return i.setAttribute("data-jspdf-utils", ""), i.textContent = "img { display: inline !important; }", document.head.appendChild(i), () => i.remove();
59
59
  }
60
- function W(i) {
61
- for (const n of i.querySelectorAll("table")) {
62
- const o = n.getAttribute("cellpadding");
60
+ function E(i) {
61
+ for (const e of i.querySelectorAll("table")) {
62
+ const o = e.getAttribute("cellpadding");
63
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");
64
+ for (const n of e.querySelectorAll("th, td"))
65
+ n.style.padding || (n.style.padding = o + "px");
66
+ e.removeAttribute("cellpadding");
67
67
  }
68
68
  }
69
69
  }
70
- function P(i, n) {
70
+ function R(i, e) {
71
71
  for (const o of Array.from(
72
72
  i.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 (o.offsetHeight <= e) continue;
75
+ const n = Array.from(o.rows);
76
+ if (n.length === 0) continue;
77
+ const r = n[0].querySelector("th") !== null, t = r ? n[0] : null, c = r ? n.slice(1) : n, a = t ? t.offsetHeight : 0, h = e - a - 2, d = [];
78
+ let l = [], g = 0;
79
+ for (const m of c) {
80
+ const s = m.offsetHeight;
81
+ g + s > h && l.length > 0 && (d.push(l), l = [], g = 0), l.push(m), g += s;
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
+ l.length > 0 && d.push(l);
84
+ for (const m of d) {
85
+ const s = o.cloneNode(!1);
86
+ t && s.appendChild(t.cloneNode(!0));
87
+ for (const f of m) s.appendChild(f.cloneNode(!0));
88
+ o.parentNode.insertBefore(s, o);
89
89
  }
90
90
  o.remove();
91
91
  }
92
92
  }
93
- function S(i, n) {
93
+ function N(i, e) {
94
94
  for (const o of Array.from(i.querySelectorAll(":scope > *"))) {
95
- const e = o;
96
- if (e.offsetHeight <= n || e.tagName === "TABLE")
95
+ const n = o;
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 r = n.tagName, t = n.getAttribute("style") || "", c = getComputedStyle(n).width, a = (n.textContent || "").split(/\s+/).filter(Boolean), h = document.createElement(r);
99
+ h.setAttribute("style", t), Object.assign(h.style, {
100
100
  position: "absolute",
101
101
  visibility: "hidden",
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;
102
+ width: c
103
+ }), i.appendChild(h);
104
+ const d = [];
105
+ let l = 0;
106
+ for (; l < a.length; ) {
107
+ let g = l + 1, m = a.length;
108
+ for (; g < m; ) {
109
+ const f = Math.ceil((g + m) / 2);
110
+ h.textContent = a.slice(l, f).join(" "), h.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 s = document.createElement(r);
113
+ s.setAttribute("style", t), s.textContent = a.slice(l, g).join(" "), d.push(s), l = g;
114
114
  }
115
- d.remove();
116
- for (const l of f)
117
- e.parentNode.insertBefore(l, e);
118
- e.remove();
115
+ h.remove();
116
+ for (const g of d)
117
+ n.parentNode.insertBefore(g, n);
118
+ n.remove();
119
119
  }
120
120
  }
121
- function M(i, n) {
121
+ function j(i, e) {
122
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);
123
+ for (const n of o) {
124
+ const r = n.offsetTop, t = r + n.offsetHeight, c = (Math.floor(r / e) + 1) * e;
125
+ if (t > c && n.offsetHeight <= e) {
126
+ const a = document.createElement("div");
127
+ a.style.height = c - r + 1 + "px", n.parentNode.insertBefore(a, n);
128
128
  }
129
129
  }
130
130
  }
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,
131
+ function B(i, e = {}) {
132
+ const o = W(e), n = S(), r = A(i, o.pageWidth);
133
+ E(r);
134
+ const t = M(r, o);
135
+ return R(r, t.pageContentPx), N(r, t.pageContentPx), j(r, t.pageContentPx), {
136
+ clone: r,
137
137
  layout: t,
138
138
  options: o,
139
139
  cleanup: () => {
140
- a.remove(), e();
140
+ r.remove(), n();
141
141
  }
142
142
  };
143
143
  }
144
- async function F(i, n, o = {}) {
145
- const { clone: e, layout: a, options: t, cleanup: s } = k(n, o);
144
+ async function D(i, e, o = {}) {
145
+ const { clone: n, layout: r, options: t, cleanup: c } = B(e, o);
146
146
  try {
147
- await new Promise((r) => {
148
- i.html(e, {
149
- callback: () => r(),
150
- width: a.contentWidthMm,
151
- windowWidth: a.renderedWidth,
147
+ await new Promise((a) => {
148
+ i.html(n, {
149
+ callback: () => a(),
150
+ width: r.contentWidthMm,
151
+ windowWidth: r.renderedWidth,
152
152
  margin: [
153
153
  t.margin.top,
154
154
  t.margin.right,
@@ -158,75 +158,140 @@ async function F(i, n, o = {}) {
158
158
  });
159
159
  });
160
160
  } finally {
161
- s();
161
+ c();
162
162
  }
163
163
  return i;
164
164
  }
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);
165
+ async function F(i, e = {}) {
166
+ const { imageFormat: o = "JPEG", imageQuality: n = 1, scale: r = 2 } = e, t = W(e), c = S(), a = A(i, t.pageWidth);
167
+ a.style.opacity = "1", a.style.left = "-99999px", E(a);
168
+ const h = M(a, t);
169
+ R(a, h.pageContentPx), N(a, h.pageContentPx), j(a, h.pageContentPx);
170
170
  try {
171
- const f = await j(r, {
172
- scale: a,
171
+ const d = await T(a, {
172
+ scale: r,
173
173
  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,
174
+ }), { jsPDF: l } = await import("jspdf"), g = t.pageWidth - t.margin.left - t.margin.right, m = t.pageHeight - t.margin.top - t.margin.bottom, s = d.width, f = m / g * s, P = Math.ceil(d.height / f), w = t.pageWidth > t.pageHeight ? "l" : "p", H = new l({
175
+ orientation: w,
176
176
  unit: "mm",
177
177
  format: [t.pageWidth, t.pageHeight]
178
178
  });
179
- for (let u = 0; u < E; u++) {
180
- 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(
179
+ for (let u = 0; u < P; u++) {
180
+ const y = Math.min(
188
181
  f,
182
+ d.height - u * f
183
+ ), b = document.createElement("canvas");
184
+ b.width = s, b.height = y;
185
+ const p = b.getContext("2d");
186
+ if (!p) throw new Error("Could not get canvas context");
187
+ p.fillStyle = "#ffffff", p.fillRect(0, 0, s, y), p.drawImage(
188
+ d,
189
189
  0,
190
- u * m,
191
- c,
192
- p,
190
+ u * f,
191
+ s,
192
+ y,
193
193
  0,
194
194
  0,
195
- c,
196
- p
195
+ s,
196
+ y
197
197
  );
198
- const N = y.toDataURL(
198
+ const v = b.toDataURL(
199
199
  `image/${o.toLowerCase()}`,
200
- e
200
+ n
201
201
  );
202
- u > 0 && w.addPage([t.pageWidth, t.pageHeight], H);
203
- const R = p / c * l;
204
- w.addImage(
205
- N,
202
+ u > 0 && H.addPage([t.pageWidth, t.pageHeight], w);
203
+ const x = y / s * g;
204
+ H.addImage(
205
+ v,
206
206
  o,
207
207
  t.margin.left,
208
208
  t.margin.top,
209
- l,
210
- R,
209
+ g,
210
+ x,
211
211
  void 0,
212
212
  "FAST"
213
213
  );
214
214
  }
215
- return w;
215
+ return H;
216
216
  } finally {
217
- r.remove(), s();
217
+ a.remove(), c();
218
+ }
219
+ }
220
+ async function I(i, e = {}) {
221
+ const { imageFormat: o = "PNG", imageQuality: n = 1, scale: r = 2 } = e, t = W(e), c = S(), a = A(i, t.pageWidth);
222
+ a.style.opacity = "1", a.style.left = "-99999px", E(a);
223
+ const h = M(a, t);
224
+ R(a, h.pageContentPx), N(a, h.pageContentPx), j(a, h.pageContentPx);
225
+ try {
226
+ const d = await T(a, {
227
+ scale: r,
228
+ backgroundColor: "#ffffff"
229
+ }), l = t.pageWidth - t.margin.left - t.margin.right, g = t.pageHeight - t.margin.top - t.margin.bottom, m = d.width, s = g / l * m, f = m / l, P = Math.round(t.pageWidth * f), w = Math.round(t.pageHeight * f), H = Math.round(t.margin.top * f), u = Math.round(t.margin.left * f), y = Math.ceil(d.height / s), b = [];
230
+ for (let p = 0; p < y; p++) {
231
+ const v = Math.min(
232
+ s,
233
+ d.height - p * s
234
+ ), x = document.createElement("canvas");
235
+ x.width = P, x.height = w;
236
+ const C = x.getContext("2d");
237
+ if (!C) throw new Error("Could not get canvas context");
238
+ C.fillStyle = "#ffffff", C.fillRect(0, 0, P, w), C.drawImage(
239
+ d,
240
+ 0,
241
+ p * s,
242
+ m,
243
+ v,
244
+ u,
245
+ H,
246
+ m,
247
+ v
248
+ ), b.push(
249
+ x.toDataURL(
250
+ `image/${o.toLowerCase()}`,
251
+ n
252
+ )
253
+ );
254
+ }
255
+ return b;
256
+ } finally {
257
+ a.remove(), c();
258
+ }
259
+ }
260
+ async function q(i, e, o = {}) {
261
+ const n = W(o), r = await I(i, o);
262
+ e.innerHTML = "", Object.assign(e.style, {
263
+ width: "fit-content",
264
+ height: n.pageHeight + "mm",
265
+ maxHeight: "100vh",
266
+ overflowY: "auto",
267
+ background: "#e0e0e0"
268
+ });
269
+ for (let t = 0; t < r.length; t++) {
270
+ const c = document.createElement("img");
271
+ c.src = r[t], c.alt = `Page ${t + 1}`, Object.assign(c.style, {
272
+ width: n.pageWidth + "mm",
273
+ maxWidth: "100%",
274
+ height: "auto",
275
+ boxSizing: "border-box",
276
+ display: "block",
277
+ border: "1px solid #bbb",
278
+ boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
279
+ marginBottom: "16px"
280
+ }), e.appendChild(c);
218
281
  }
219
282
  }
220
283
  export {
221
- B as PAGE_MARGINS,
222
- T as PAGE_SIZES,
223
- x as computeLayout,
284
+ L as PAGE_MARGINS,
285
+ k as PAGE_SIZES,
286
+ M as computeLayout,
224
287
  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
288
+ j as insertPageBreakSpacers,
289
+ E as normalizeTableAttributes,
290
+ B as prepare,
291
+ q as previewPageImages,
292
+ D as renderHTML,
293
+ F as renderImagePDF,
294
+ I as renderPageImages,
295
+ R as splitOversizedTables,
296
+ N as splitOversizedText
232
297
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspdf-utils",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
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",