@pixldocs/canvas-renderer 0.5.456 → 0.5.458
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/dist/{index-D7XRqqRF.cjs → index-CScn1p9A.cjs} +162 -90
- package/dist/{index-D7XRqqRF.cjs.map → index-CScn1p9A.cjs.map} +1 -1
- package/dist/{index-DbfhlD78.js → index-DgUgxzD1.js} +162 -90
- package/dist/{index-DbfhlD78.js.map → index-DgUgxzD1.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-CAeuEsjr.js → vectorPdfExport-DTC5MXqp.js} +4 -4
- package/dist/{vectorPdfExport-CAeuEsjr.js.map → vectorPdfExport-DTC5MXqp.js.map} +1 -1
- package/dist/{vectorPdfExport-Cyok7Rsu.cjs → vectorPdfExport-DySc4jWC.cjs} +4 -4
- package/dist/{vectorPdfExport-Cyok7Rsu.cjs.map → vectorPdfExport-DySc4jWC.cjs.map} +1 -1
- package/package.json +1 -1
|
@@ -21110,6 +21110,13 @@ function setInTree(nodes, elementId, targetProperty, value) {
|
|
|
21110
21110
|
delete node.cropPanY;
|
|
21111
21111
|
delete node.cropZoom;
|
|
21112
21112
|
}
|
|
21113
|
+
if (nextSrc === "") {
|
|
21114
|
+
node.visible = false;
|
|
21115
|
+
node.opacity = 0;
|
|
21116
|
+
} else {
|
|
21117
|
+
node.visible = true;
|
|
21118
|
+
if (node.opacity === 0) delete node.opacity;
|
|
21119
|
+
}
|
|
21113
21120
|
} else {
|
|
21114
21121
|
const gradSibling = gradientSiblingForTarget(targetProperty);
|
|
21115
21122
|
if (gradSibling) {
|
|
@@ -25229,6 +25236,89 @@ const previewBlur = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
|
|
|
25229
25236
|
injectPreviewBlur,
|
|
25230
25237
|
resolveBlurElementExactIdsFromFlatFormKeys
|
|
25231
25238
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
25239
|
+
function collectImageUrls(config) {
|
|
25240
|
+
const urls = [];
|
|
25241
|
+
const walk = (nodes) => {
|
|
25242
|
+
for (const node of nodes) {
|
|
25243
|
+
if (!node || node.visible === false) continue;
|
|
25244
|
+
const src = typeof node.src === "string" ? node.src.trim() : "";
|
|
25245
|
+
const imageUrl = typeof node.imageUrl === "string" ? node.imageUrl.trim() : "";
|
|
25246
|
+
if (node.type === "image") {
|
|
25247
|
+
const url = src || imageUrl;
|
|
25248
|
+
if (url) urls.push(url);
|
|
25249
|
+
}
|
|
25250
|
+
if (Array.isArray(node.children) && node.children.length > 0) {
|
|
25251
|
+
walk(node.children);
|
|
25252
|
+
}
|
|
25253
|
+
}
|
|
25254
|
+
};
|
|
25255
|
+
for (const page of config.pages || []) {
|
|
25256
|
+
walk(page.children || []);
|
|
25257
|
+
}
|
|
25258
|
+
return urls;
|
|
25259
|
+
}
|
|
25260
|
+
function normalizeAssetUrl(rawUrl, imageProxyUrl) {
|
|
25261
|
+
if (!rawUrl) return null;
|
|
25262
|
+
if (rawUrl.startsWith("data:") || rawUrl.startsWith("blob:")) return null;
|
|
25263
|
+
if (rawUrl.startsWith("/") && !rawUrl.startsWith("//")) {
|
|
25264
|
+
if (typeof window !== "undefined") return new URL(rawUrl, window.location.origin).toString();
|
|
25265
|
+
return null;
|
|
25266
|
+
}
|
|
25267
|
+
try {
|
|
25268
|
+
const h = new URL(rawUrl).hostname.toLowerCase();
|
|
25269
|
+
if (h === "localhost" || h === "127.0.0.1" || h === "0.0.0.0" || h.endsWith(".local") || /^(10\.|192\.168\.|169\.254\.)/.test(h)) {
|
|
25270
|
+
if (typeof window !== "undefined" && new URL(rawUrl).origin === window.location.origin) {
|
|
25271
|
+
return rawUrl;
|
|
25272
|
+
}
|
|
25273
|
+
return null;
|
|
25274
|
+
}
|
|
25275
|
+
} catch {
|
|
25276
|
+
return null;
|
|
25277
|
+
}
|
|
25278
|
+
const supabaseUrl = typeof globalThis.__VITE_SUPABASE_URL === "string" ? globalThis.__VITE_SUPABASE_URL : "";
|
|
25279
|
+
if (supabaseUrl && rawUrl.includes(supabaseUrl)) {
|
|
25280
|
+
const signedMatch = rawUrl.match(/\/storage\/v1\/object\/sign\/([^?]+)/);
|
|
25281
|
+
if (signedMatch) return `${supabaseUrl}/storage/v1/object/public/${signedMatch[1]}`;
|
|
25282
|
+
if (rawUrl.includes("/storage/v1/object/public/")) return rawUrl;
|
|
25283
|
+
}
|
|
25284
|
+
const proxyBase = imageProxyUrl ? imageProxyUrl.replace(/\/image-proxy(?:\?.*)?$/, "") : exports.API_URL;
|
|
25285
|
+
if (proxyBase) {
|
|
25286
|
+
return `${proxyBase}/image-proxy?url=${encodeURIComponent(rawUrl)}`;
|
|
25287
|
+
}
|
|
25288
|
+
return rawUrl;
|
|
25289
|
+
}
|
|
25290
|
+
const CONCURRENCY = 6;
|
|
25291
|
+
async function prefetchUrls(urls, signal) {
|
|
25292
|
+
const unique = [...new Set(urls)];
|
|
25293
|
+
if (unique.length === 0) return;
|
|
25294
|
+
let i = 0;
|
|
25295
|
+
const next = async () => {
|
|
25296
|
+
while (i < unique.length) {
|
|
25297
|
+
if (signal == null ? void 0 : signal.aborted) return;
|
|
25298
|
+
const url = unique[i++];
|
|
25299
|
+
try {
|
|
25300
|
+
await fetch(url, { signal, mode: "cors", credentials: "omit" });
|
|
25301
|
+
} catch {
|
|
25302
|
+
}
|
|
25303
|
+
}
|
|
25304
|
+
};
|
|
25305
|
+
const workers = Array.from({ length: Math.min(CONCURRENCY, unique.length) }, () => next());
|
|
25306
|
+
await Promise.all(workers);
|
|
25307
|
+
}
|
|
25308
|
+
async function warmResolvedTemplateForPreview(config, options) {
|
|
25309
|
+
const { signal, imageProxyUrl } = options ?? {};
|
|
25310
|
+
await ensureFontsForResolvedConfig(config);
|
|
25311
|
+
if (signal == null ? void 0 : signal.aborted) return;
|
|
25312
|
+
const rawUrls = collectImageUrls(config);
|
|
25313
|
+
const resolvedUrls = rawUrls.map((u) => normalizeAssetUrl(u, imageProxyUrl)).filter((u) => u !== null);
|
|
25314
|
+
await prefetchUrls(resolvedUrls, signal);
|
|
25315
|
+
}
|
|
25316
|
+
async function warmTemplateFromForm(options) {
|
|
25317
|
+
const { signal, imageProxyUrl, ...resolveOpts } = options;
|
|
25318
|
+
const resolved = await resolveFromForm(resolveOpts);
|
|
25319
|
+
if (signal == null ? void 0 : signal.aborted) return;
|
|
25320
|
+
await warmResolvedTemplateForPreview(resolved.config, { signal, imageProxyUrl });
|
|
25321
|
+
}
|
|
25232
25322
|
const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
|
|
25233
25323
|
function computeFontSignature(config) {
|
|
25234
25324
|
var _a2;
|
|
@@ -25244,6 +25334,39 @@ function computeFontSignature(config) {
|
|
|
25244
25334
|
for (const page of config.pages) walk(page.children || []);
|
|
25245
25335
|
return Array.from(fams).sort().join("|");
|
|
25246
25336
|
}
|
|
25337
|
+
function computeImageSignature(config) {
|
|
25338
|
+
var _a2;
|
|
25339
|
+
if (!((_a2 = config == null ? void 0 : config.pages) == null ? void 0 : _a2.length)) return "";
|
|
25340
|
+
try {
|
|
25341
|
+
const urls = collectImageUrls(config);
|
|
25342
|
+
return urls.length === 0 ? "" : urls.slice().sort().join("|");
|
|
25343
|
+
} catch {
|
|
25344
|
+
return "";
|
|
25345
|
+
}
|
|
25346
|
+
}
|
|
25347
|
+
function preloadImageUrl(url, proxyBase) {
|
|
25348
|
+
return new Promise((resolve) => {
|
|
25349
|
+
if (!url || url.startsWith("data:") || url.startsWith("blob:")) return resolve();
|
|
25350
|
+
let done = false;
|
|
25351
|
+
const finish = () => {
|
|
25352
|
+
if (!done) {
|
|
25353
|
+
done = true;
|
|
25354
|
+
resolve();
|
|
25355
|
+
}
|
|
25356
|
+
};
|
|
25357
|
+
const isHttp = /^https?:/i.test(url);
|
|
25358
|
+
const target = isHttp && proxyBase && !url.includes("/image-proxy?") ? `${proxyBase.replace(/\/+$/, "")}?url=${encodeURIComponent(url)}` : url;
|
|
25359
|
+
const img = new Image();
|
|
25360
|
+
try {
|
|
25361
|
+
img.crossOrigin = "anonymous";
|
|
25362
|
+
} catch {
|
|
25363
|
+
}
|
|
25364
|
+
img.onload = finish;
|
|
25365
|
+
img.onerror = finish;
|
|
25366
|
+
img.src = target;
|
|
25367
|
+
setTimeout(finish, 6e3);
|
|
25368
|
+
});
|
|
25369
|
+
}
|
|
25247
25370
|
function countUnderlinedNodes(config) {
|
|
25248
25371
|
var _a2;
|
|
25249
25372
|
if (!((_a2 = config == null ? void 0 : config.pages) == null ? void 0 : _a2.length)) return 0;
|
|
@@ -25406,6 +25529,38 @@ function PixldocsPreview(props) {
|
|
|
25406
25529
|
const config = isResolveMode ? resolvedConfig : props.config;
|
|
25407
25530
|
const previewKey = react.useMemo(() => `${pageIndex}`, [pageIndex]);
|
|
25408
25531
|
const fontSignature = react.useMemo(() => computeFontSignature(config), [config]);
|
|
25532
|
+
const imageSignature = react.useMemo(() => computeImageSignature(config), [config]);
|
|
25533
|
+
const [imagesReady, setImagesReady] = react.useState(true);
|
|
25534
|
+
const firstImageRef = react.useMemo(() => ({ first: true }), []);
|
|
25535
|
+
react.useEffect(() => {
|
|
25536
|
+
if (!config) {
|
|
25537
|
+
setImagesReady(true);
|
|
25538
|
+
return;
|
|
25539
|
+
}
|
|
25540
|
+
if (firstImageRef.first) {
|
|
25541
|
+
firstImageRef.first = false;
|
|
25542
|
+
setImagesReady(true);
|
|
25543
|
+
return;
|
|
25544
|
+
}
|
|
25545
|
+
let urls = [];
|
|
25546
|
+
try {
|
|
25547
|
+
urls = collectImageUrls(config);
|
|
25548
|
+
} catch {
|
|
25549
|
+
urls = [];
|
|
25550
|
+
}
|
|
25551
|
+
if (urls.length === 0) {
|
|
25552
|
+
setImagesReady(true);
|
|
25553
|
+
return;
|
|
25554
|
+
}
|
|
25555
|
+
setImagesReady(false);
|
|
25556
|
+
let cancelled = false;
|
|
25557
|
+
Promise.all(urls.map((u) => preloadImageUrl(u, imageProxyUrl))).then(() => {
|
|
25558
|
+
if (!cancelled) setImagesReady(true);
|
|
25559
|
+
});
|
|
25560
|
+
return () => {
|
|
25561
|
+
cancelled = true;
|
|
25562
|
+
};
|
|
25563
|
+
}, [imageSignature, imageProxyUrl]);
|
|
25409
25564
|
react.useEffect(() => {
|
|
25410
25565
|
if (isResolveMode) return;
|
|
25411
25566
|
if (!config) {
|
|
@@ -25488,7 +25643,7 @@ function PixldocsPreview(props) {
|
|
|
25488
25643
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
25489
25644
|
"div",
|
|
25490
25645
|
{
|
|
25491
|
-
style: hasOverlays ? { visibility: canvasSettled ? "visible" : "hidden", position: "relative", width: canvasW * zoom, height: canvasH * zoom } : { visibility: canvasSettled ? "visible" : "hidden" },
|
|
25646
|
+
style: hasOverlays ? { visibility: canvasSettled && imagesReady ? "visible" : "hidden", position: "relative", width: canvasW * zoom, height: canvasH * zoom } : { visibility: canvasSettled && imagesReady ? "visible" : "hidden" },
|
|
25492
25647
|
children: [
|
|
25493
25648
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25494
25649
|
PreviewCanvas,
|
|
@@ -25534,7 +25689,7 @@ function PixldocsPreview(props) {
|
|
|
25534
25689
|
]
|
|
25535
25690
|
}
|
|
25536
25691
|
),
|
|
25537
|
-
!canvasSettled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: loadingFallback ?? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
25692
|
+
(!canvasSettled || !imagesReady) && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: loadingFallback ?? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
25538
25693
|
] });
|
|
25539
25694
|
}
|
|
25540
25695
|
function normalizeSvgDimensions(svg, targetWidth, targetHeight) {
|
|
@@ -26055,9 +26210,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
26055
26210
|
}
|
|
26056
26211
|
return svgString;
|
|
26057
26212
|
}
|
|
26058
|
-
const resolvedPackageVersion = "0.5.
|
|
26213
|
+
const resolvedPackageVersion = "0.5.458";
|
|
26059
26214
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
26060
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
26215
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.458";
|
|
26061
26216
|
const roundParityValue = (value) => {
|
|
26062
26217
|
if (typeof value !== "number") return value;
|
|
26063
26218
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -26871,7 +27026,7 @@ class PixldocsRenderer {
|
|
|
26871
27026
|
await this.waitForCanvasScene(container, cloned, i);
|
|
26872
27027
|
}
|
|
26873
27028
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
26874
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
27029
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DySc4jWC.cjs"));
|
|
26875
27030
|
const prepared = preparePagesForExport(
|
|
26876
27031
|
cloned.pages,
|
|
26877
27032
|
canvasWidth,
|
|
@@ -29191,7 +29346,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
29191
29346
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
29192
29347
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
29193
29348
|
try {
|
|
29194
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
29349
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DySc4jWC.cjs"));
|
|
29195
29350
|
try {
|
|
29196
29351
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
29197
29352
|
} catch {
|
|
@@ -29439,89 +29594,6 @@ async function getPublishedTemplate(options) {
|
|
|
29439
29594
|
const rows = await res.json();
|
|
29440
29595
|
return rows[0] ?? null;
|
|
29441
29596
|
}
|
|
29442
|
-
function collectImageUrls(config) {
|
|
29443
|
-
const urls = [];
|
|
29444
|
-
const walk = (nodes) => {
|
|
29445
|
-
for (const node of nodes) {
|
|
29446
|
-
if (!node || node.visible === false) continue;
|
|
29447
|
-
const src = typeof node.src === "string" ? node.src.trim() : "";
|
|
29448
|
-
const imageUrl = typeof node.imageUrl === "string" ? node.imageUrl.trim() : "";
|
|
29449
|
-
if (node.type === "image") {
|
|
29450
|
-
const url = src || imageUrl;
|
|
29451
|
-
if (url) urls.push(url);
|
|
29452
|
-
}
|
|
29453
|
-
if (Array.isArray(node.children) && node.children.length > 0) {
|
|
29454
|
-
walk(node.children);
|
|
29455
|
-
}
|
|
29456
|
-
}
|
|
29457
|
-
};
|
|
29458
|
-
for (const page of config.pages || []) {
|
|
29459
|
-
walk(page.children || []);
|
|
29460
|
-
}
|
|
29461
|
-
return urls;
|
|
29462
|
-
}
|
|
29463
|
-
function normalizeAssetUrl(rawUrl, imageProxyUrl) {
|
|
29464
|
-
if (!rawUrl) return null;
|
|
29465
|
-
if (rawUrl.startsWith("data:") || rawUrl.startsWith("blob:")) return null;
|
|
29466
|
-
if (rawUrl.startsWith("/") && !rawUrl.startsWith("//")) {
|
|
29467
|
-
if (typeof window !== "undefined") return new URL(rawUrl, window.location.origin).toString();
|
|
29468
|
-
return null;
|
|
29469
|
-
}
|
|
29470
|
-
try {
|
|
29471
|
-
const h = new URL(rawUrl).hostname.toLowerCase();
|
|
29472
|
-
if (h === "localhost" || h === "127.0.0.1" || h === "0.0.0.0" || h.endsWith(".local") || /^(10\.|192\.168\.|169\.254\.)/.test(h)) {
|
|
29473
|
-
if (typeof window !== "undefined" && new URL(rawUrl).origin === window.location.origin) {
|
|
29474
|
-
return rawUrl;
|
|
29475
|
-
}
|
|
29476
|
-
return null;
|
|
29477
|
-
}
|
|
29478
|
-
} catch {
|
|
29479
|
-
return null;
|
|
29480
|
-
}
|
|
29481
|
-
const supabaseUrl = typeof globalThis.__VITE_SUPABASE_URL === "string" ? globalThis.__VITE_SUPABASE_URL : "";
|
|
29482
|
-
if (supabaseUrl && rawUrl.includes(supabaseUrl)) {
|
|
29483
|
-
const signedMatch = rawUrl.match(/\/storage\/v1\/object\/sign\/([^?]+)/);
|
|
29484
|
-
if (signedMatch) return `${supabaseUrl}/storage/v1/object/public/${signedMatch[1]}`;
|
|
29485
|
-
if (rawUrl.includes("/storage/v1/object/public/")) return rawUrl;
|
|
29486
|
-
}
|
|
29487
|
-
const proxyBase = imageProxyUrl ? imageProxyUrl.replace(/\/image-proxy(?:\?.*)?$/, "") : exports.API_URL;
|
|
29488
|
-
if (proxyBase) {
|
|
29489
|
-
return `${proxyBase}/image-proxy?url=${encodeURIComponent(rawUrl)}`;
|
|
29490
|
-
}
|
|
29491
|
-
return rawUrl;
|
|
29492
|
-
}
|
|
29493
|
-
const CONCURRENCY = 6;
|
|
29494
|
-
async function prefetchUrls(urls, signal) {
|
|
29495
|
-
const unique = [...new Set(urls)];
|
|
29496
|
-
if (unique.length === 0) return;
|
|
29497
|
-
let i = 0;
|
|
29498
|
-
const next = async () => {
|
|
29499
|
-
while (i < unique.length) {
|
|
29500
|
-
if (signal == null ? void 0 : signal.aborted) return;
|
|
29501
|
-
const url = unique[i++];
|
|
29502
|
-
try {
|
|
29503
|
-
await fetch(url, { signal, mode: "cors", credentials: "omit" });
|
|
29504
|
-
} catch {
|
|
29505
|
-
}
|
|
29506
|
-
}
|
|
29507
|
-
};
|
|
29508
|
-
const workers = Array.from({ length: Math.min(CONCURRENCY, unique.length) }, () => next());
|
|
29509
|
-
await Promise.all(workers);
|
|
29510
|
-
}
|
|
29511
|
-
async function warmResolvedTemplateForPreview(config, options) {
|
|
29512
|
-
const { signal, imageProxyUrl } = options ?? {};
|
|
29513
|
-
await ensureFontsForResolvedConfig(config);
|
|
29514
|
-
if (signal == null ? void 0 : signal.aborted) return;
|
|
29515
|
-
const rawUrls = collectImageUrls(config);
|
|
29516
|
-
const resolvedUrls = rawUrls.map((u) => normalizeAssetUrl(u, imageProxyUrl)).filter((u) => u !== null);
|
|
29517
|
-
await prefetchUrls(resolvedUrls, signal);
|
|
29518
|
-
}
|
|
29519
|
-
async function warmTemplateFromForm(options) {
|
|
29520
|
-
const { signal, imageProxyUrl, ...resolveOpts } = options;
|
|
29521
|
-
const resolved = await resolveFromForm(resolveOpts);
|
|
29522
|
-
if (signal == null ? void 0 : signal.aborted) return;
|
|
29523
|
-
await warmResolvedTemplateForPreview(resolved.config, { signal, imageProxyUrl });
|
|
29524
|
-
}
|
|
29525
29597
|
function setAutoShrinkDebug(enabled) {
|
|
29526
29598
|
if (typeof window !== "undefined") {
|
|
29527
29599
|
window.__pixldocsDebugAutoShrink = !!enabled;
|
|
@@ -29588,4 +29660,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
29588
29660
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
29589
29661
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
29590
29662
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
29591
|
-
//# sourceMappingURL=index-
|
|
29663
|
+
//# sourceMappingURL=index-CScn1p9A.cjs.map
|