@pixldocs/canvas-renderer 0.5.230 → 0.5.232

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.
@@ -9609,6 +9609,63 @@ function renderSmartElementToDataUri(type, props, width, height) {
9609
9609
  if (!svg) return null;
9610
9610
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
9611
9611
  }
9612
+ function runFontReloadAndReflow(opts) {
9613
+ const { canvas, pageTree, pageBoundsOptions, preserveGlobalFontCache, persistTextboxSize, preResnapSync } = opts;
9614
+ if (!canvas) return;
9615
+ try {
9616
+ clearFontCacheAndRerender(canvas, { clearGlobalCharCache: !preserveGlobalFontCache });
9617
+ } catch {
9618
+ }
9619
+ try {
9620
+ clearMeasurementCache();
9621
+ } catch {
9622
+ }
9623
+ if (!preserveGlobalFontCache) {
9624
+ try {
9625
+ clearFabricCharCache();
9626
+ } catch {
9627
+ }
9628
+ }
9629
+ if (persistTextboxSize && pageTree.length) {
9630
+ const elements = flattenChildren(pageTree);
9631
+ canvas.getObjects().forEach((obj) => {
9632
+ if (!(obj instanceof fabric.Textbox)) return;
9633
+ const id = getObjectId(obj);
9634
+ if (!id) return;
9635
+ const el = elements.find((e) => e.id === id);
9636
+ if (!el) return;
9637
+ persistTextboxSize(id, { width: obj.width ?? 0, height: obj.height ?? 0 }, el);
9638
+ });
9639
+ }
9640
+ if (preResnapSync) {
9641
+ try {
9642
+ preResnapSync();
9643
+ } catch (e) {
9644
+ console.warn("[canvasReflow] preResnapSync failed:", e);
9645
+ }
9646
+ }
9647
+ if (!pageTree.length) return;
9648
+ try {
9649
+ canvas.getObjects().forEach((obj) => {
9650
+ const id = getObjectId(obj);
9651
+ if (!id) return;
9652
+ const node = findNodeById(pageTree, id);
9653
+ if (!node) return;
9654
+ const abs = getAbsoluteBounds(node, pageTree, pageBoundsOptions);
9655
+ const targetLeft = obj.originX === "center" ? abs.left + abs.width / 2 : obj.originX === "right" ? abs.left + abs.width : abs.left;
9656
+ const targetTop = obj.originY === "center" ? abs.top + abs.height / 2 : obj.originY === "bottom" ? abs.top + abs.height : abs.top;
9657
+ const curLeft = obj.left ?? 0;
9658
+ const curTop = obj.top ?? 0;
9659
+ if (Math.abs(curLeft - targetLeft) > 0.1 || Math.abs(curTop - targetTop) > 0.1) {
9660
+ obj.set({ left: targetLeft, top: targetTop });
9661
+ obj.setCoords();
9662
+ }
9663
+ });
9664
+ canvas.requestRenderAll();
9665
+ } catch (e) {
9666
+ console.warn("[canvasReflow] resnap failed:", e);
9667
+ }
9668
+ }
9612
9669
  const EVT_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBoundsChanged";
9613
9670
  function subscribeShowOriginalTextBounds(cb) {
9614
9671
  const handler = (e) => cb(!!e.detail);
@@ -13392,61 +13449,38 @@ const PageCanvas = forwardRef(
13392
13449
  var _a2;
13393
13450
  const fc = fabricRef.current;
13394
13451
  if (!fc || cancelled) return;
13395
- clearFontCacheAndRerender(fc, { clearGlobalCharCache: !preserveGlobalFontCache });
13396
13452
  const state = useEditorStore.getState();
13397
- const page = state.canvas.pages.find((p) => p.id === pageId);
13398
- if (page) {
13399
- const elements2 = flattenChildren(page.children);
13400
- fc.getObjects().forEach((obj) => {
13401
- if (obj instanceof fabric.Textbox) {
13402
- const id = getObjectId(obj);
13403
- if (!id) return;
13404
- const w = obj.width ?? 0;
13405
- const h = obj.height ?? 0;
13406
- const el = elements2.find((e) => e.id === id);
13407
- if (!el) return;
13408
- const storeW = el.width ?? 0;
13409
- const storeH = el.height ?? 0;
13410
- const updates = {};
13411
- const shouldKeepFixedSize = el.overflowPolicy === "auto-shrink";
13412
- if (!shouldKeepFixedSize && w > 0 && typeof storeW === "number" && Math.abs(w - storeW) > 0.1) updates.width = w;
13413
- if (shouldKeepFixedSize) {
13414
- if (h > 0 && typeof storeH === "number" && h < storeH - 0.5) updates.height = h;
13415
- } else {
13416
- if (h > 0 && (typeof storeH !== "number" || Math.abs(h - storeH) > 0.1)) updates.height = h;
13417
- }
13418
- if (Object.keys(updates).length > 0) {
13419
- state.updateElement(id, updates, { recordHistory: false, skipLayoutRecalc: true });
13420
- }
13453
+ const repositionTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
13454
+ runFontReloadAndReflow({
13455
+ canvas: fc,
13456
+ pageTree: repositionTree,
13457
+ pageBoundsOptions,
13458
+ preserveGlobalFontCache,
13459
+ // Persist measured Textbox sizes back to the editor store. The
13460
+ // headless path passes no callback (it has no store to persist into).
13461
+ persistTextboxSize: (id, measured, el) => {
13462
+ const storeW = el.width ?? 0;
13463
+ const storeH = el.height ?? 0;
13464
+ const shouldKeepFixedSize = el.overflowPolicy === "auto-shrink";
13465
+ const updates = {};
13466
+ if (!shouldKeepFixedSize && measured.width > 0 && typeof storeW === "number" && Math.abs(measured.width - storeW) > 0.1) {
13467
+ updates.width = measured.width;
13421
13468
  }
13422
- });
13423
- }
13424
- try {
13425
- if ((isPreviewMode || isExportMode) && doSyncRef.current) {
13426
- doSyncRef.current();
13427
- }
13428
- const repositionTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
13429
- if (repositionTree.length) {
13430
- fc.getObjects().forEach((obj) => {
13431
- const id = getObjectId(obj);
13432
- if (!id) return;
13433
- const node = findNodeById(repositionTree, id);
13434
- if (!node) return;
13435
- const abs = getAbsoluteBounds(node, repositionTree, pageBoundsOptions);
13436
- const targetLeft = obj.originX === "center" ? abs.left + abs.width / 2 : obj.originX === "right" ? abs.left + abs.width : abs.left;
13437
- const targetTop = obj.originY === "center" ? abs.top + abs.height / 2 : obj.originY === "bottom" ? abs.top + abs.height : abs.top;
13438
- const curLeft = obj.left ?? 0;
13439
- const curTop = obj.top ?? 0;
13440
- if (Math.abs(curLeft - targetLeft) > 0.1 || Math.abs(curTop - targetTop) > 0.1) {
13441
- obj.set({ left: targetLeft, top: targetTop });
13442
- obj.setCoords();
13443
- }
13444
- });
13445
- fc.requestRenderAll();
13446
- }
13447
- } catch (e) {
13448
- console.warn("[PageCanvas] post-ready reposition failed:", e);
13449
- }
13469
+ if (shouldKeepFixedSize) {
13470
+ if (measured.height > 0 && typeof storeH === "number" && measured.height < storeH - 0.5) updates.height = measured.height;
13471
+ } else {
13472
+ if (measured.height > 0 && (typeof storeH !== "number" || Math.abs(measured.height - storeH) > 0.1)) updates.height = measured.height;
13473
+ }
13474
+ if (Object.keys(updates).length > 0) {
13475
+ state.updateElement(id, updates, { recordHistory: false, skipLayoutRecalc: true });
13476
+ }
13477
+ },
13478
+ // Rebuild section/background groups before resnapping top-level objects.
13479
+ preResnapSync: (isPreviewMode || isExportMode) && doSyncRef.current ? () => {
13480
+ var _a3;
13481
+ return (_a3 = doSyncRef.current) == null ? void 0 : _a3.call(doSyncRef);
13482
+ } : void 0
13483
+ });
13450
13484
  };
13451
13485
  const raf1 = requestAnimationFrame(() => {
13452
13486
  requestAnimationFrame(() => {
@@ -19929,6 +19963,54 @@ async function getTemplateForm(options) {
19929
19963
  initialSectionState
19930
19964
  };
19931
19965
  }
19966
+ async function resolveForRender(input) {
19967
+ var _a2;
19968
+ const {
19969
+ templateConfig,
19970
+ templateId,
19971
+ formSchemaId,
19972
+ sectionState,
19973
+ flatFormData,
19974
+ themeId,
19975
+ watermark,
19976
+ prefetched,
19977
+ supabaseUrl,
19978
+ supabaseAnonKey
19979
+ } = input;
19980
+ if (templateConfig) {
19981
+ return {
19982
+ config: templateConfig,
19983
+ templateName: templateConfig.name || "Untitled",
19984
+ templateId
19985
+ };
19986
+ }
19987
+ if (!templateId) {
19988
+ throw new Error("[resolveForRender] templateId is required when templateConfig is not provided");
19989
+ }
19990
+ const hasSectionState = !!sectionState && Object.keys(sectionState).length > 0;
19991
+ if (formSchemaId || hasSectionState || ((_a2 = prefetched == null ? void 0 : prefetched.templateRow) == null ? void 0 : _a2.config)) {
19992
+ return resolveFromForm({
19993
+ templateId,
19994
+ formSchemaId,
19995
+ // CRITICAL: only forward sectionState when it is *actually* V2 state.
19996
+ // Forwarding flatFormData here would make resolveFromForm think it has
19997
+ // V2 data and skip the flat-key apply path — the exact bug that left
19998
+ // dynamic text stale on staging /use-package PDFs.
19999
+ sectionState: hasSectionState ? sectionState : void 0,
20000
+ flatFormData,
20001
+ themeId,
20002
+ supabaseUrl,
20003
+ supabaseAnonKey,
20004
+ prefetched
20005
+ });
20006
+ }
20007
+ return resolveTemplateData({
20008
+ templateId,
20009
+ formData: flatFormData ?? {},
20010
+ supabaseUrl,
20011
+ supabaseAnonKey
20012
+ });
20013
+ }
19932
20014
  const OVERLAY_ID_PREFIX = "__pb_";
19933
20015
  function getNumber(v, fallback = 0) {
19934
20016
  return typeof v === "number" && Number.isFinite(v) ? v : fallback;
@@ -21004,9 +21086,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
21004
21086
  }
21005
21087
  return svgString;
21006
21088
  }
21007
- const resolvedPackageVersion = "0.5.230";
21089
+ const resolvedPackageVersion = "0.5.232";
21008
21090
  const PACKAGE_VERSION = resolvedPackageVersion;
21009
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.230";
21091
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.232";
21010
21092
  const roundParityValue = (value) => {
21011
21093
  if (typeof value !== "number") return value;
21012
21094
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -21750,7 +21832,7 @@ class PixldocsRenderer {
21750
21832
  await this.waitForCanvasScene(container, cloned, i);
21751
21833
  }
21752
21834
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
21753
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-Bmd1La7S.js");
21835
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BcNEn5nI.js");
21754
21836
  const prepared = preparePagesForExport(
21755
21837
  cloned.pages,
21756
21838
  canvasWidth,
@@ -24070,7 +24152,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
24070
24152
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
24071
24153
  sanitizeSvgTreeForPdf(svgToDraw);
24072
24154
  try {
24073
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-Bmd1La7S.js");
24155
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BcNEn5nI.js");
24074
24156
  try {
24075
24157
  await logTextMeasurementDiagnostic(svgToDraw);
24076
24158
  } catch {
@@ -24407,7 +24489,7 @@ function setAutoShrinkDebug(enabled) {
24407
24489
  }
24408
24490
  }
24409
24491
  export {
24410
- resolveFromForm as $,
24492
+ resolveForRender as $,
24411
24493
  API_URL as A,
24412
24494
  collectFontsFromConfig as B,
24413
24495
  collectImageUrls as C,
@@ -24436,13 +24518,14 @@ export {
24436
24518
  resolveBlurElementExactIdsFromFlatFormKeys as Z,
24437
24519
  resolveFontWeight as _,
24438
24520
  getAbsoluteBounds as a,
24439
- resolveTemplateData as a0,
24440
- rewriteSvgFontsForJsPDF as a1,
24441
- setAutoShrinkDebug as a2,
24442
- setBundledAssetPrefixes as a3,
24443
- warmResolvedTemplateForPreview as a4,
24444
- warmTemplateFromForm as a5,
24445
- canvasImageLoader as a6,
24521
+ resolveFromForm as a0,
24522
+ resolveTemplateData as a1,
24523
+ rewriteSvgFontsForJsPDF as a2,
24524
+ setAutoShrinkDebug as a3,
24525
+ setBundledAssetPrefixes as a4,
24526
+ warmResolvedTemplateForPreview as a5,
24527
+ warmTemplateFromForm as a6,
24528
+ canvasImageLoader as a7,
24446
24529
  getProxiedImageUrl as b,
24447
24530
  captureFabricCanvasSvgForPdf as c,
24448
24531
  getImageProxyFetchOptions as d,
@@ -24469,4 +24552,4 @@ export {
24469
24552
  buildTeaserBlurFlatKeys as y,
24470
24553
  collectFontDescriptorsFromConfig as z
24471
24554
  };
24472
- //# sourceMappingURL=index-BagYpNB5.js.map
24555
+ //# sourceMappingURL=index-DlrTh8y7.js.map