@pixldocs/canvas-renderer 0.5.189 → 0.5.191
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.
- package/README.md +52 -6
- package/dist/{index-CmrxeQ_K.cjs → index-BJR7zaam.cjs} +205 -13
- package/dist/{index-CmrxeQ_K.cjs.map → index-BJR7zaam.cjs.map} +1 -1
- package/dist/{index-lQXXPpb8.js → index-C3kuDISv.js} +205 -13
- package/dist/{index-lQXXPpb8.js.map → index-C3kuDISv.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +38 -0
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-Ch-qwcNJ.js → vectorPdfExport-CrTGqxx6.js} +7 -7
- package/dist/{vectorPdfExport-Ch-qwcNJ.js.map → vectorPdfExport-CrTGqxx6.js.map} +1 -1
- package/dist/{vectorPdfExport-BAAJU0RL.cjs → vectorPdfExport-D_2mdcwO.cjs} +7 -7
- package/dist/{vectorPdfExport-BAAJU0RL.cjs.map → vectorPdfExport-D_2mdcwO.cjs.map} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -483,7 +483,7 @@ const blurFieldIds = ['text-reference-name', 'text-phone', 'text-address'];
|
|
|
483
483
|
the resolved config before handing it to the imperative renderer, so the
|
|
484
484
|
blur is baked into the exported pixels.
|
|
485
485
|
|
|
486
|
-
### Biodata teaser previews — blur by flat form key (v0.5.187+, hardened in v0.5.189)
|
|
486
|
+
### Biodata teaser previews — blur by flat form key (v0.5.187+, hardened in v0.5.189, pagination-safe in v0.5.190)
|
|
487
487
|
|
|
488
488
|
Form-driven apps (BioMaker, the pixldocs.com Use page, etc.) already
|
|
489
489
|
speak the **flat form-key** language produced by `applyFormDataToConfig`
|
|
@@ -530,11 +530,17 @@ Notes:
|
|
|
530
530
|
with or without the wrapper `field_` prefix). **As of v0.5.189**
|
|
531
531
|
every resolved id is then verified against the actual rendered page
|
|
532
532
|
tree (`config.pages[*]`) — stale or alias map entries that don't
|
|
533
|
-
match a real element are dropped silently.
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
533
|
+
match a real element are dropped silently.
|
|
534
|
+
- **As of v0.5.190** `applyContentBoundsPagination` rewrites
|
|
535
|
+
`__cloneIdMap` after pagination so flat keys for overflow rows that
|
|
536
|
+
moved to continuation pages still resolve to ids that exist on the
|
|
537
|
+
tree (clones inherit `__sourceId` from the original element). If the
|
|
538
|
+
map is still stale for any reason, the resolver also falls back to
|
|
539
|
+
walking the page tree and matching `__sourceId` / `__baseNodeId`
|
|
540
|
+
against the raw resolved ids — the same strategy the theming pipeline
|
|
541
|
+
uses to track paginated clones. End result: frosted blur for row N
|
|
542
|
+
appears on whichever page row N actually renders on, even when
|
|
543
|
+
content-bounds pagination moved it.
|
|
538
544
|
- Pass `pageIndex` in `blurFlatFormKeyOptions` to scope verification
|
|
539
545
|
to a single page — clones that landed on a different page will not
|
|
540
546
|
contribute overlays to this page. This is the recommended pattern
|
|
@@ -606,3 +612,43 @@ function — there is now exactly one resolver shared across the entire
|
|
|
606
612
|
stack. Anything that blurs correctly in one place blurs identically in
|
|
607
613
|
the other; visual/UX bugs introduced in one pipeline cannot diverge
|
|
608
614
|
silently from the other.
|
|
615
|
+
|
|
616
|
+
## Reliable PDF photo embedding across browsers (v0.5.191+)
|
|
617
|
+
|
|
618
|
+
Form-driven apps that embed **user-uploaded photos** (biodatas, resumes,
|
|
619
|
+
ID cards…) historically hit a Safari/iOS bug where the downloaded PDF
|
|
620
|
+
rendered without the photos even though the on-screen preview was fine.
|
|
621
|
+
The svg2pdf fast path internally re-rasterises `data:image/*` sources
|
|
622
|
+
through a tainted offscreen canvas roundtrip, which Safari silently drops
|
|
623
|
+
for large camera-roll JPEGs.
|
|
624
|
+
|
|
625
|
+
v0.5.191 fixes this with two new options:
|
|
626
|
+
|
|
627
|
+
```ts
|
|
628
|
+
const renderer = new PixldocsRenderer({
|
|
629
|
+
supabaseUrl, supabaseAnonKey,
|
|
630
|
+
// Force the per-element Fabric → jsPDF.addImage path on every export.
|
|
631
|
+
// Recommended for biodata-style flows that always have user photos.
|
|
632
|
+
forcePerElementPdf: true, // true | false | 'auto' (default)
|
|
633
|
+
// Down-scale any data:image/* whose longest edge > 2048 to JPEG-0.85
|
|
634
|
+
// before mounting into Fabric. Prevents Safari from silently dropping
|
|
635
|
+
// multi-megapixel camera-roll JPEGs in jsPDF.addImage.
|
|
636
|
+
maxImageEdgePx: 2048, // 0 to disable
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const pdf = await renderer.renderPdfFromForm({
|
|
640
|
+
templateId, formSchemaId, sectionState, title,
|
|
641
|
+
// Per-call overrides also accepted:
|
|
642
|
+
// forcePerElementPdf: 'auto',
|
|
643
|
+
// maxImageEdgePx: 2400,
|
|
644
|
+
});
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
**Defaults:** `forcePerElementPdf: 'auto'` enables the safe path only when
|
|
648
|
+
the resolved config contains a `data:image/(jpeg|png|webp)` source **and**
|
|
649
|
+
the host is Safari / iOS (incl. iPadOS desktop spoof). Editors and
|
|
650
|
+
non-Safari hosts keep the vector fast path unchanged.
|
|
651
|
+
|
|
652
|
+
Hosts that previously monkey-patched `captureFabricCanvasSvgForPdf` to
|
|
653
|
+
throw (the unofficial BioMaker workaround) can delete that patch after
|
|
654
|
+
upgrading.
|
|
@@ -13327,6 +13327,7 @@ function isStaticOnNewPage(node) {
|
|
|
13327
13327
|
function cloneNodeWithNewIds(node) {
|
|
13328
13328
|
const base = node.__baseNodeId;
|
|
13329
13329
|
const source = node.__sourceId;
|
|
13330
|
+
const effectiveSource = source ?? node.id;
|
|
13330
13331
|
if (isGroup(node)) {
|
|
13331
13332
|
const g = node;
|
|
13332
13333
|
const cloned2 = {
|
|
@@ -13335,14 +13336,14 @@ function cloneNodeWithNewIds(node) {
|
|
|
13335
13336
|
children: (g.children ?? []).map(cloneNodeWithNewIds)
|
|
13336
13337
|
};
|
|
13337
13338
|
if (base != null) cloned2.__baseNodeId = base;
|
|
13338
|
-
|
|
13339
|
+
cloned2.__sourceId = effectiveSource;
|
|
13339
13340
|
return cloned2;
|
|
13340
13341
|
}
|
|
13341
13342
|
const el = node;
|
|
13342
13343
|
const prefix = el.type === "text" ? "text" : el.type === "image" ? "img" : el.type === "shape" ? "shape" : "line";
|
|
13343
13344
|
const cloned = { ...el, id: generateId(prefix) };
|
|
13344
13345
|
if (base != null) cloned.__baseNodeId = base;
|
|
13345
|
-
|
|
13346
|
+
cloned.__sourceId = effectiveSource;
|
|
13346
13347
|
return cloned;
|
|
13347
13348
|
}
|
|
13348
13349
|
function cloneNodeWithStableIds(node, baseId2, path) {
|
|
@@ -13648,7 +13649,51 @@ function applyContentBoundsPagination(config) {
|
|
|
13648
13649
|
resultPages.push(...paginated);
|
|
13649
13650
|
}
|
|
13650
13651
|
if (!mutated) return config;
|
|
13651
|
-
|
|
13652
|
+
const next = { ...config, pages: resultPages };
|
|
13653
|
+
remapCloneIdMapAfterPagination(next);
|
|
13654
|
+
return next;
|
|
13655
|
+
}
|
|
13656
|
+
function remapCloneIdMapAfterPagination(config) {
|
|
13657
|
+
const cloneIdMap = config.__cloneIdMap;
|
|
13658
|
+
if (!cloneIdMap || typeof cloneIdMap !== "object") return;
|
|
13659
|
+
const allIds = /* @__PURE__ */ new Set();
|
|
13660
|
+
const sourceToNew = /* @__PURE__ */ new Map();
|
|
13661
|
+
const walk = (node) => {
|
|
13662
|
+
if (!node || typeof node !== "object") return;
|
|
13663
|
+
const n = node;
|
|
13664
|
+
if (typeof n.id === "string") {
|
|
13665
|
+
allIds.add(n.id);
|
|
13666
|
+
const src = n.__sourceId;
|
|
13667
|
+
if (typeof src === "string" && src !== n.id) {
|
|
13668
|
+
const arr = sourceToNew.get(src);
|
|
13669
|
+
if (arr) arr.push(n.id);
|
|
13670
|
+
else sourceToNew.set(src, [n.id]);
|
|
13671
|
+
}
|
|
13672
|
+
}
|
|
13673
|
+
const children = n.children;
|
|
13674
|
+
if (Array.isArray(children)) for (const c of children) walk(c);
|
|
13675
|
+
};
|
|
13676
|
+
for (const page of config.pages ?? []) {
|
|
13677
|
+
const ch = page.children;
|
|
13678
|
+
if (Array.isArray(ch)) for (const c of ch) walk(c);
|
|
13679
|
+
}
|
|
13680
|
+
const updated = {};
|
|
13681
|
+
for (const [key, val] of Object.entries(cloneIdMap)) {
|
|
13682
|
+
const oldIds = Array.isArray(val) ? val : [val];
|
|
13683
|
+
const newIds = [];
|
|
13684
|
+
for (const oid of oldIds) {
|
|
13685
|
+
if (typeof oid !== "string") continue;
|
|
13686
|
+
if (allIds.has(oid)) newIds.push(oid);
|
|
13687
|
+
const clones = sourceToNew.get(oid);
|
|
13688
|
+
if (clones) {
|
|
13689
|
+
for (const c of clones) if (allIds.has(c)) newIds.push(c);
|
|
13690
|
+
}
|
|
13691
|
+
}
|
|
13692
|
+
if (newIds.length === 0) continue;
|
|
13693
|
+
const uniq = Array.from(new Set(newIds));
|
|
13694
|
+
updated[key] = uniq.length === 1 ? uniq[0] : uniq;
|
|
13695
|
+
}
|
|
13696
|
+
config.__cloneIdMap = updated;
|
|
13652
13697
|
}
|
|
13653
13698
|
const __vite_import_meta_env__ = {};
|
|
13654
13699
|
const FONT_WEIGHT_LABELS = {
|
|
@@ -16274,6 +16319,32 @@ function collectPageTreeElementIds(config, pageIndex = "all") {
|
|
|
16274
16319
|
}
|
|
16275
16320
|
return out;
|
|
16276
16321
|
}
|
|
16322
|
+
function collectIdsBySourceMatch(config, targetIds, pageIndex = "all") {
|
|
16323
|
+
const targets = /* @__PURE__ */ new Set();
|
|
16324
|
+
for (const t of targetIds) if (typeof t === "string" && t) targets.add(t);
|
|
16325
|
+
if (targets.size === 0) return [];
|
|
16326
|
+
const pages = config == null ? void 0 : config.pages;
|
|
16327
|
+
if (!Array.isArray(pages)) return [];
|
|
16328
|
+
const visitPages = pageIndex === "all" ? pages : pages[pageIndex] != null ? [pages[pageIndex]] : [];
|
|
16329
|
+
const out = /* @__PURE__ */ new Set();
|
|
16330
|
+
const walk = (node) => {
|
|
16331
|
+
if (!node || typeof node !== "object") return;
|
|
16332
|
+
const src = typeof node.__sourceId === "string" ? node.__sourceId : void 0;
|
|
16333
|
+
const base = typeof node.__baseNodeId === "string" ? node.__baseNodeId : void 0;
|
|
16334
|
+
if (typeof node.id === "string") {
|
|
16335
|
+
if (targets.has(node.id)) out.add(node.id);
|
|
16336
|
+
else if (src && targets.has(src)) out.add(node.id);
|
|
16337
|
+
else if (base && targets.has(base)) out.add(node.id);
|
|
16338
|
+
}
|
|
16339
|
+
const children = node.children || node.elements;
|
|
16340
|
+
if (Array.isArray(children)) for (const c of children) walk(c);
|
|
16341
|
+
};
|
|
16342
|
+
for (const page of visitPages) {
|
|
16343
|
+
const children = (page == null ? void 0 : page.children) || (page == null ? void 0 : page.elements);
|
|
16344
|
+
if (Array.isArray(children)) for (const c of children) walk(c);
|
|
16345
|
+
}
|
|
16346
|
+
return Array.from(out);
|
|
16347
|
+
}
|
|
16277
16348
|
function resolveBlurElementExactIdsFromFlatFormKeys(config, flatFormKeys, options) {
|
|
16278
16349
|
const cloneIdMap = (config == null ? void 0 : config.__cloneIdMap) || {};
|
|
16279
16350
|
if (!cloneIdMap || typeof cloneIdMap !== "object") return [];
|
|
@@ -16307,7 +16378,8 @@ function resolveBlurElementExactIdsFromFlatFormKeys(config, flatFormKeys, option
|
|
|
16307
16378
|
if (treeIds.size === 0) return Array.from(out);
|
|
16308
16379
|
const verified = [];
|
|
16309
16380
|
for (const id of out) if (treeIds.has(id)) verified.push(id);
|
|
16310
|
-
return verified;
|
|
16381
|
+
if (verified.length > 0) return verified;
|
|
16382
|
+
return collectIdsBySourceMatch(config, out, (options == null ? void 0 : options.pageIndex) ?? "all");
|
|
16311
16383
|
}
|
|
16312
16384
|
function buildTeaserBlurFlatKeys(sectionState, sections, options) {
|
|
16313
16385
|
const afterRow = Math.max(0, options.afterRow | 0);
|
|
@@ -16835,9 +16907,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
16835
16907
|
}
|
|
16836
16908
|
return svgString;
|
|
16837
16909
|
}
|
|
16838
|
-
const resolvedPackageVersion = "0.5.
|
|
16910
|
+
const resolvedPackageVersion = "0.5.191";
|
|
16839
16911
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
16840
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
16912
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.191";
|
|
16841
16913
|
const roundParityValue = (value) => {
|
|
16842
16914
|
if (typeof value !== "number") return value;
|
|
16843
16915
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16864,6 +16936,96 @@ function isFabricTextboxLike(obj) {
|
|
|
16864
16936
|
function isFabricGroupLike(obj) {
|
|
16865
16937
|
return !!obj && (obj instanceof fabric__namespace.Group || obj.type === "group" || Array.isArray(obj._objects) && typeof obj.getObjects === "function");
|
|
16866
16938
|
}
|
|
16939
|
+
function configHasUserDataImage(config) {
|
|
16940
|
+
let found = false;
|
|
16941
|
+
const isRasterDataUrl = (u) => typeof u === "string" && /^data:image\/(jpeg|jpg|png|webp)[;,]/i.test(u);
|
|
16942
|
+
const walk = (nodes) => {
|
|
16943
|
+
if (found || !Array.isArray(nodes)) return;
|
|
16944
|
+
for (const node of nodes) {
|
|
16945
|
+
if (!node || typeof node !== "object") continue;
|
|
16946
|
+
if (node.type === "image" && (isRasterDataUrl(node.src) || isRasterDataUrl(node.imageUrl))) {
|
|
16947
|
+
found = true;
|
|
16948
|
+
return;
|
|
16949
|
+
}
|
|
16950
|
+
if (Array.isArray(node.children)) walk(node.children);
|
|
16951
|
+
}
|
|
16952
|
+
};
|
|
16953
|
+
for (const page of config.pages ?? []) {
|
|
16954
|
+
walk((page == null ? void 0 : page.children) ?? []);
|
|
16955
|
+
if (found) break;
|
|
16956
|
+
}
|
|
16957
|
+
return found;
|
|
16958
|
+
}
|
|
16959
|
+
function detectSafariOrIos() {
|
|
16960
|
+
try {
|
|
16961
|
+
if (typeof navigator === "undefined") return false;
|
|
16962
|
+
const ua = navigator.userAgent || "";
|
|
16963
|
+
const vendor = navigator.vendor || "";
|
|
16964
|
+
const isIOS = /iPad|iPhone|iPod/.test(ua) || // iPadOS 13+ reports as Mac with touch
|
|
16965
|
+
/Macintosh/.test(ua) && typeof navigator.maxTouchPoints === "number" && navigator.maxTouchPoints > 1;
|
|
16966
|
+
const isSafariDesktop = /Safari/.test(ua) && /Apple/.test(vendor) && !/Chrome|CriOS|Chromium|Edg|FxiOS/.test(ua);
|
|
16967
|
+
return isIOS || isSafariDesktop;
|
|
16968
|
+
} catch {
|
|
16969
|
+
return false;
|
|
16970
|
+
}
|
|
16971
|
+
}
|
|
16972
|
+
async function downscaleConfigRasterImages(config, maxEdgePx) {
|
|
16973
|
+
if (!maxEdgePx || maxEdgePx <= 0) return 0;
|
|
16974
|
+
if (typeof document === "undefined") return 0;
|
|
16975
|
+
const targets = [];
|
|
16976
|
+
const isRasterDataUrl = (u) => typeof u === "string" && /^data:image\/(jpeg|jpg|png|webp)[;,]/i.test(u);
|
|
16977
|
+
const walk = (nodes) => {
|
|
16978
|
+
if (!Array.isArray(nodes)) return;
|
|
16979
|
+
for (const node of nodes) {
|
|
16980
|
+
if (!node || typeof node !== "object") continue;
|
|
16981
|
+
if (node.type === "image") {
|
|
16982
|
+
if (isRasterDataUrl(node.src)) targets.push({ node, field: "src" });
|
|
16983
|
+
else if (isRasterDataUrl(node.imageUrl)) targets.push({ node, field: "imageUrl" });
|
|
16984
|
+
}
|
|
16985
|
+
if (Array.isArray(node.children)) walk(node.children);
|
|
16986
|
+
}
|
|
16987
|
+
};
|
|
16988
|
+
for (const page of config.pages ?? []) walk((page == null ? void 0 : page.children) ?? []);
|
|
16989
|
+
if (targets.length === 0) return 0;
|
|
16990
|
+
const shrinkOne = async (dataUrl) => {
|
|
16991
|
+
try {
|
|
16992
|
+
const img = await new Promise((resolve, reject) => {
|
|
16993
|
+
const el = new Image();
|
|
16994
|
+
el.onload = () => resolve(el);
|
|
16995
|
+
el.onerror = (e) => reject(e);
|
|
16996
|
+
el.decoding = "sync";
|
|
16997
|
+
el.src = dataUrl;
|
|
16998
|
+
});
|
|
16999
|
+
const w = img.naturalWidth, h = img.naturalHeight;
|
|
17000
|
+
if (!w || !h) return null;
|
|
17001
|
+
const longest = Math.max(w, h);
|
|
17002
|
+
if (longest <= maxEdgePx) return null;
|
|
17003
|
+
const scale = maxEdgePx / longest;
|
|
17004
|
+
const tw = Math.max(1, Math.round(w * scale));
|
|
17005
|
+
const th = Math.max(1, Math.round(h * scale));
|
|
17006
|
+
const canvas = document.createElement("canvas");
|
|
17007
|
+
canvas.width = tw;
|
|
17008
|
+
canvas.height = th;
|
|
17009
|
+
const ctx = canvas.getContext("2d");
|
|
17010
|
+
if (!ctx) return null;
|
|
17011
|
+
ctx.fillStyle = "#ffffff";
|
|
17012
|
+
ctx.fillRect(0, 0, tw, th);
|
|
17013
|
+
ctx.drawImage(img, 0, 0, tw, th);
|
|
17014
|
+
return canvas.toDataURL("image/jpeg", 0.85);
|
|
17015
|
+
} catch {
|
|
17016
|
+
return null;
|
|
17017
|
+
}
|
|
17018
|
+
};
|
|
17019
|
+
let shrunk = 0;
|
|
17020
|
+
for (const { node, field } of targets) {
|
|
17021
|
+
const next = await shrinkOne(String(node[field]));
|
|
17022
|
+
if (next) {
|
|
17023
|
+
node[field] = next;
|
|
17024
|
+
shrunk++;
|
|
17025
|
+
}
|
|
17026
|
+
}
|
|
17027
|
+
return shrunk;
|
|
17028
|
+
}
|
|
16867
17029
|
let __underlineFixInstalled = false;
|
|
16868
17030
|
function installUnderlineFix(fab) {
|
|
16869
17031
|
var _a;
|
|
@@ -17216,7 +17378,9 @@ class PixldocsRenderer {
|
|
|
17216
17378
|
async renderPdf(templateConfig, options) {
|
|
17217
17379
|
return this.renderPdfViaClientExport(templateConfig, {
|
|
17218
17380
|
title: options == null ? void 0 : options.title,
|
|
17219
|
-
textMode: options == null ? void 0 : options.textMode
|
|
17381
|
+
textMode: options == null ? void 0 : options.textMode,
|
|
17382
|
+
forcePerElementPdf: options == null ? void 0 : options.forcePerElementPdf,
|
|
17383
|
+
maxImageEdgePx: options == null ? void 0 : options.maxImageEdgePx
|
|
17220
17384
|
});
|
|
17221
17385
|
}
|
|
17222
17386
|
/**
|
|
@@ -17224,7 +17388,7 @@ class PixldocsRenderer {
|
|
|
17224
17388
|
* This is the primary PDF export API — mirrors renderFromForm() but returns a PDF.
|
|
17225
17389
|
*/
|
|
17226
17390
|
async renderPdfFromForm(options) {
|
|
17227
|
-
const { templateId, formSchemaId, sectionState, themeId, watermark, watermarkOptions, prefetched, title, fontBaseUrl, textMode } = options;
|
|
17391
|
+
const { templateId, formSchemaId, sectionState, themeId, watermark, watermarkOptions, prefetched, title, fontBaseUrl, textMode, forcePerElementPdf, maxImageEdgePx } = options;
|
|
17228
17392
|
const resolved = await resolveFromForm({
|
|
17229
17393
|
templateId,
|
|
17230
17394
|
formSchemaId,
|
|
@@ -17245,7 +17409,9 @@ class PixldocsRenderer {
|
|
|
17245
17409
|
return this.renderPdfViaClientExport(configToRender, {
|
|
17246
17410
|
title: title ?? resolved.config.name,
|
|
17247
17411
|
watermark: shouldWatermark,
|
|
17248
|
-
textMode
|
|
17412
|
+
textMode,
|
|
17413
|
+
forcePerElementPdf,
|
|
17414
|
+
maxImageEdgePx
|
|
17249
17415
|
});
|
|
17250
17416
|
}
|
|
17251
17417
|
async renderById(templateId, formData, options) {
|
|
@@ -17286,6 +17452,31 @@ class PixldocsRenderer {
|
|
|
17286
17452
|
const { setPackageApiUrl: setPackageApiUrl2 } = await Promise.resolve().then(() => appApi);
|
|
17287
17453
|
setPackageApiUrl2(this.config.imageProxyUrl);
|
|
17288
17454
|
const cloned = JSON.parse(JSON.stringify(templateConfig));
|
|
17455
|
+
const callForce = options.forcePerElementPdf;
|
|
17456
|
+
const cfgForce = this.config.forcePerElementPdf;
|
|
17457
|
+
const forceMode = callForce !== void 0 ? callForce : cfgForce !== void 0 ? cfgForce : "auto";
|
|
17458
|
+
const hasUserDataImage = configHasUserDataImage(cloned);
|
|
17459
|
+
const isSafariLike = detectSafariOrIos();
|
|
17460
|
+
const shouldForcePerElement = forceMode === true ? true : forceMode === false ? false : hasUserDataImage && isSafariLike;
|
|
17461
|
+
const maxEdgeOpt = options.maxImageEdgePx ?? this.config.maxImageEdgePx;
|
|
17462
|
+
const effectiveMaxEdge = typeof maxEdgeOpt === "number" ? Math.max(0, maxEdgeOpt | 0) : shouldForcePerElement ? 2048 : 0;
|
|
17463
|
+
if (effectiveMaxEdge > 0) {
|
|
17464
|
+
try {
|
|
17465
|
+
const downscaled = await downscaleConfigRasterImages(cloned, effectiveMaxEdge);
|
|
17466
|
+
if (downscaled > 0) {
|
|
17467
|
+
console.log(`[canvas-renderer][pdf-unified] downscaled ${downscaled} raster image(s) to <=${effectiveMaxEdge}px edge`);
|
|
17468
|
+
}
|
|
17469
|
+
} catch (e) {
|
|
17470
|
+
console.warn("[canvas-renderer][pdf-unified] image downscale pass failed (continuing with originals):", e);
|
|
17471
|
+
}
|
|
17472
|
+
}
|
|
17473
|
+
console.log("[canvas-renderer][pdf-unified] export switches", {
|
|
17474
|
+
forceMode,
|
|
17475
|
+
hasUserDataImage,
|
|
17476
|
+
isSafariLike,
|
|
17477
|
+
shouldForcePerElement,
|
|
17478
|
+
effectiveMaxEdge
|
|
17479
|
+
});
|
|
17289
17480
|
const stampPrefix = `__pixldocs_pdf_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
17290
17481
|
const pageIds = cloned.pages.map((p, i) => {
|
|
17291
17482
|
const id = `${stampPrefix}_p${i}`;
|
|
@@ -17345,7 +17536,7 @@ class PixldocsRenderer {
|
|
|
17345
17536
|
await this.waitForCanvasScene(container, cloned, i);
|
|
17346
17537
|
}
|
|
17347
17538
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
17348
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
17539
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-D_2mdcwO.cjs"));
|
|
17349
17540
|
const prepared = preparePagesForExport(
|
|
17350
17541
|
cloned.pages,
|
|
17351
17542
|
canvasWidth,
|
|
@@ -17355,7 +17546,8 @@ class PixldocsRenderer {
|
|
|
17355
17546
|
title: options.title,
|
|
17356
17547
|
watermark: !!options.watermark,
|
|
17357
17548
|
returnBlob: true,
|
|
17358
|
-
pdfTextMode: options.textMode ?? (cloned == null ? void 0 : cloned.pdfTextMode) ?? ((_a = cloned.canvas) == null ? void 0 : _a.n) ?? "auto"
|
|
17549
|
+
pdfTextMode: options.textMode ?? (cloned == null ? void 0 : cloned.pdfTextMode) ?? ((_a = cloned.canvas) == null ? void 0 : _a.n) ?? "auto",
|
|
17550
|
+
skipLiveCanvasSvgFastPath: shouldForcePerElement
|
|
17359
17551
|
});
|
|
17360
17552
|
if (!result || typeof result === "undefined") {
|
|
17361
17553
|
throw new Error("exportMultiPagePdf returned no blob (returnBlob path failed)");
|
|
@@ -19490,7 +19682,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
19490
19682
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
19491
19683
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
19492
19684
|
try {
|
|
19493
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
19685
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-D_2mdcwO.cjs"));
|
|
19494
19686
|
try {
|
|
19495
19687
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
19496
19688
|
} catch {
|
|
@@ -19887,4 +20079,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
19887
20079
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
19888
20080
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
19889
20081
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
19890
|
-
//# sourceMappingURL=index-
|
|
20082
|
+
//# sourceMappingURL=index-BJR7zaam.cjs.map
|