@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.
@@ -9627,6 +9627,63 @@ function renderSmartElementToDataUri(type, props, width, height) {
9627
9627
  if (!svg) return null;
9628
9628
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
9629
9629
  }
9630
+ function runFontReloadAndReflow(opts) {
9631
+ const { canvas, pageTree, pageBoundsOptions, preserveGlobalFontCache, persistTextboxSize, preResnapSync } = opts;
9632
+ if (!canvas) return;
9633
+ try {
9634
+ clearFontCacheAndRerender(canvas, { clearGlobalCharCache: !preserveGlobalFontCache });
9635
+ } catch {
9636
+ }
9637
+ try {
9638
+ clearMeasurementCache();
9639
+ } catch {
9640
+ }
9641
+ if (!preserveGlobalFontCache) {
9642
+ try {
9643
+ clearFabricCharCache();
9644
+ } catch {
9645
+ }
9646
+ }
9647
+ if (persistTextboxSize && pageTree.length) {
9648
+ const elements = flattenChildren(pageTree);
9649
+ canvas.getObjects().forEach((obj) => {
9650
+ if (!(obj instanceof fabric__namespace.Textbox)) return;
9651
+ const id = getObjectId(obj);
9652
+ if (!id) return;
9653
+ const el = elements.find((e) => e.id === id);
9654
+ if (!el) return;
9655
+ persistTextboxSize(id, { width: obj.width ?? 0, height: obj.height ?? 0 }, el);
9656
+ });
9657
+ }
9658
+ if (preResnapSync) {
9659
+ try {
9660
+ preResnapSync();
9661
+ } catch (e) {
9662
+ console.warn("[canvasReflow] preResnapSync failed:", e);
9663
+ }
9664
+ }
9665
+ if (!pageTree.length) return;
9666
+ try {
9667
+ canvas.getObjects().forEach((obj) => {
9668
+ const id = getObjectId(obj);
9669
+ if (!id) return;
9670
+ const node = findNodeById(pageTree, id);
9671
+ if (!node) return;
9672
+ const abs = getAbsoluteBounds(node, pageTree, pageBoundsOptions);
9673
+ const targetLeft = obj.originX === "center" ? abs.left + abs.width / 2 : obj.originX === "right" ? abs.left + abs.width : abs.left;
9674
+ const targetTop = obj.originY === "center" ? abs.top + abs.height / 2 : obj.originY === "bottom" ? abs.top + abs.height : abs.top;
9675
+ const curLeft = obj.left ?? 0;
9676
+ const curTop = obj.top ?? 0;
9677
+ if (Math.abs(curLeft - targetLeft) > 0.1 || Math.abs(curTop - targetTop) > 0.1) {
9678
+ obj.set({ left: targetLeft, top: targetTop });
9679
+ obj.setCoords();
9680
+ }
9681
+ });
9682
+ canvas.requestRenderAll();
9683
+ } catch (e) {
9684
+ console.warn("[canvasReflow] resnap failed:", e);
9685
+ }
9686
+ }
9630
9687
  const EVT_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBoundsChanged";
9631
9688
  function subscribeShowOriginalTextBounds(cb) {
9632
9689
  const handler = (e) => cb(!!e.detail);
@@ -13410,61 +13467,38 @@ const PageCanvas = react.forwardRef(
13410
13467
  var _a2;
13411
13468
  const fc = fabricRef.current;
13412
13469
  if (!fc || cancelled) return;
13413
- clearFontCacheAndRerender(fc, { clearGlobalCharCache: !preserveGlobalFontCache });
13414
13470
  const state = useEditorStore.getState();
13415
- const page = state.canvas.pages.find((p) => p.id === pageId);
13416
- if (page) {
13417
- const elements2 = flattenChildren(page.children);
13418
- fc.getObjects().forEach((obj) => {
13419
- if (obj instanceof fabric__namespace.Textbox) {
13420
- const id = getObjectId(obj);
13421
- if (!id) return;
13422
- const w = obj.width ?? 0;
13423
- const h = obj.height ?? 0;
13424
- const el = elements2.find((e) => e.id === id);
13425
- if (!el) return;
13426
- const storeW = el.width ?? 0;
13427
- const storeH = el.height ?? 0;
13428
- const updates = {};
13429
- const shouldKeepFixedSize = el.overflowPolicy === "auto-shrink";
13430
- if (!shouldKeepFixedSize && w > 0 && typeof storeW === "number" && Math.abs(w - storeW) > 0.1) updates.width = w;
13431
- if (shouldKeepFixedSize) {
13432
- if (h > 0 && typeof storeH === "number" && h < storeH - 0.5) updates.height = h;
13433
- } else {
13434
- if (h > 0 && (typeof storeH !== "number" || Math.abs(h - storeH) > 0.1)) updates.height = h;
13435
- }
13436
- if (Object.keys(updates).length > 0) {
13437
- state.updateElement(id, updates, { recordHistory: false, skipLayoutRecalc: true });
13438
- }
13471
+ const repositionTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
13472
+ runFontReloadAndReflow({
13473
+ canvas: fc,
13474
+ pageTree: repositionTree,
13475
+ pageBoundsOptions,
13476
+ preserveGlobalFontCache,
13477
+ // Persist measured Textbox sizes back to the editor store. The
13478
+ // headless path passes no callback (it has no store to persist into).
13479
+ persistTextboxSize: (id, measured, el) => {
13480
+ const storeW = el.width ?? 0;
13481
+ const storeH = el.height ?? 0;
13482
+ const shouldKeepFixedSize = el.overflowPolicy === "auto-shrink";
13483
+ const updates = {};
13484
+ if (!shouldKeepFixedSize && measured.width > 0 && typeof storeW === "number" && Math.abs(measured.width - storeW) > 0.1) {
13485
+ updates.width = measured.width;
13439
13486
  }
13440
- });
13441
- }
13442
- try {
13443
- if ((isPreviewMode || isExportMode) && doSyncRef.current) {
13444
- doSyncRef.current();
13445
- }
13446
- 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) ?? [];
13447
- if (repositionTree.length) {
13448
- fc.getObjects().forEach((obj) => {
13449
- const id = getObjectId(obj);
13450
- if (!id) return;
13451
- const node = findNodeById(repositionTree, id);
13452
- if (!node) return;
13453
- const abs = getAbsoluteBounds(node, repositionTree, pageBoundsOptions);
13454
- const targetLeft = obj.originX === "center" ? abs.left + abs.width / 2 : obj.originX === "right" ? abs.left + abs.width : abs.left;
13455
- const targetTop = obj.originY === "center" ? abs.top + abs.height / 2 : obj.originY === "bottom" ? abs.top + abs.height : abs.top;
13456
- const curLeft = obj.left ?? 0;
13457
- const curTop = obj.top ?? 0;
13458
- if (Math.abs(curLeft - targetLeft) > 0.1 || Math.abs(curTop - targetTop) > 0.1) {
13459
- obj.set({ left: targetLeft, top: targetTop });
13460
- obj.setCoords();
13461
- }
13462
- });
13463
- fc.requestRenderAll();
13464
- }
13465
- } catch (e) {
13466
- console.warn("[PageCanvas] post-ready reposition failed:", e);
13467
- }
13487
+ if (shouldKeepFixedSize) {
13488
+ if (measured.height > 0 && typeof storeH === "number" && measured.height < storeH - 0.5) updates.height = measured.height;
13489
+ } else {
13490
+ if (measured.height > 0 && (typeof storeH !== "number" || Math.abs(measured.height - storeH) > 0.1)) updates.height = measured.height;
13491
+ }
13492
+ if (Object.keys(updates).length > 0) {
13493
+ state.updateElement(id, updates, { recordHistory: false, skipLayoutRecalc: true });
13494
+ }
13495
+ },
13496
+ // Rebuild section/background groups before resnapping top-level objects.
13497
+ preResnapSync: (isPreviewMode || isExportMode) && doSyncRef.current ? () => {
13498
+ var _a3;
13499
+ return (_a3 = doSyncRef.current) == null ? void 0 : _a3.call(doSyncRef);
13500
+ } : void 0
13501
+ });
13468
13502
  };
13469
13503
  const raf1 = requestAnimationFrame(() => {
13470
13504
  requestAnimationFrame(() => {
@@ -19947,6 +19981,54 @@ async function getTemplateForm(options) {
19947
19981
  initialSectionState
19948
19982
  };
19949
19983
  }
19984
+ async function resolveForRender(input) {
19985
+ var _a2;
19986
+ const {
19987
+ templateConfig,
19988
+ templateId,
19989
+ formSchemaId,
19990
+ sectionState,
19991
+ flatFormData,
19992
+ themeId,
19993
+ watermark,
19994
+ prefetched,
19995
+ supabaseUrl,
19996
+ supabaseAnonKey
19997
+ } = input;
19998
+ if (templateConfig) {
19999
+ return {
20000
+ config: templateConfig,
20001
+ templateName: templateConfig.name || "Untitled",
20002
+ templateId
20003
+ };
20004
+ }
20005
+ if (!templateId) {
20006
+ throw new Error("[resolveForRender] templateId is required when templateConfig is not provided");
20007
+ }
20008
+ const hasSectionState = !!sectionState && Object.keys(sectionState).length > 0;
20009
+ if (formSchemaId || hasSectionState || ((_a2 = prefetched == null ? void 0 : prefetched.templateRow) == null ? void 0 : _a2.config)) {
20010
+ return resolveFromForm({
20011
+ templateId,
20012
+ formSchemaId,
20013
+ // CRITICAL: only forward sectionState when it is *actually* V2 state.
20014
+ // Forwarding flatFormData here would make resolveFromForm think it has
20015
+ // V2 data and skip the flat-key apply path — the exact bug that left
20016
+ // dynamic text stale on staging /use-package PDFs.
20017
+ sectionState: hasSectionState ? sectionState : void 0,
20018
+ flatFormData,
20019
+ themeId,
20020
+ supabaseUrl,
20021
+ supabaseAnonKey,
20022
+ prefetched
20023
+ });
20024
+ }
20025
+ return resolveTemplateData({
20026
+ templateId,
20027
+ formData: flatFormData ?? {},
20028
+ supabaseUrl,
20029
+ supabaseAnonKey
20030
+ });
20031
+ }
19950
20032
  const OVERLAY_ID_PREFIX = "__pb_";
19951
20033
  function getNumber(v, fallback = 0) {
19952
20034
  return typeof v === "number" && Number.isFinite(v) ? v : fallback;
@@ -21022,9 +21104,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
21022
21104
  }
21023
21105
  return svgString;
21024
21106
  }
21025
- const resolvedPackageVersion = "0.5.230";
21107
+ const resolvedPackageVersion = "0.5.232";
21026
21108
  const PACKAGE_VERSION = resolvedPackageVersion;
21027
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.230";
21109
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.232";
21028
21110
  const roundParityValue = (value) => {
21029
21111
  if (typeof value !== "number") return value;
21030
21112
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -21768,7 +21850,7 @@ class PixldocsRenderer {
21768
21850
  await this.waitForCanvasScene(container, cloned, i);
21769
21851
  }
21770
21852
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
21771
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DKKc9K-b.cjs"));
21853
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-HZtiPy3x.cjs"));
21772
21854
  const prepared = preparePagesForExport(
21773
21855
  cloned.pages,
21774
21856
  canvasWidth,
@@ -24088,7 +24170,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
24088
24170
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
24089
24171
  sanitizeSvgTreeForPdf(svgToDraw);
24090
24172
  try {
24091
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DKKc9K-b.cjs"));
24173
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-HZtiPy3x.cjs"));
24092
24174
  try {
24093
24175
  await logTextMeasurementDiagnostic(svgToDraw);
24094
24176
  } catch {
@@ -24477,6 +24559,7 @@ exports.parseTextMarkdown = parseTextMarkdown;
24477
24559
  exports.renderSmartElementToSvg = renderSmartElementToSvg;
24478
24560
  exports.resolveBlurElementExactIdsFromFlatFormKeys = resolveBlurElementExactIdsFromFlatFormKeys;
24479
24561
  exports.resolveFontWeight = resolveFontWeight;
24562
+ exports.resolveForRender = resolveForRender;
24480
24563
  exports.resolveFromForm = resolveFromForm;
24481
24564
  exports.resolveTemplateData = resolveTemplateData;
24482
24565
  exports.rewriteSvgFontsForJsPDF = rewriteSvgFontsForJsPDF;
@@ -24484,4 +24567,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
24484
24567
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
24485
24568
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
24486
24569
  exports.warmTemplateFromForm = warmTemplateFromForm;
24487
- //# sourceMappingURL=index-D_6iVwwl.cjs.map
24570
+ //# sourceMappingURL=index-BqnHjSp9.cjs.map