@pixldocs/canvas-renderer 0.5.27 → 0.5.29

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.cjs CHANGED
@@ -2590,6 +2590,10 @@ async function _doLoadGoogleFont(fontFamily, weights) {
2590
2590
  return false;
2591
2591
  }
2592
2592
  }
2593
+ const getObjectId = (obj) => obj.__docuforgeId;
2594
+ const setObjectData = (obj, id) => {
2595
+ obj.__docuforgeId = id;
2596
+ };
2593
2597
  const FONTS_TO_PRELOAD = [
2594
2598
  "Open Sans",
2595
2599
  "Playfair Display",
@@ -2729,6 +2733,42 @@ const clearFabricCharCache = () => {
2729
2733
  };
2730
2734
  const clearFontCacheAndRerender = (canvas) => {
2731
2735
  clearFabricCharCache();
2736
+ const logUnderlineDebug = (stage, payload) => {
2737
+ try {
2738
+ console.log(`[canvas-renderer][underline-debug] ${stage} ${JSON.stringify(payload)}`);
2739
+ } catch {
2740
+ console.log("[canvas-renderer][underline-debug]", stage, payload);
2741
+ }
2742
+ };
2743
+ const collectUnderlineMetrics = (obj) => {
2744
+ var _a, _b;
2745
+ if (obj instanceof fabric__namespace.Textbox) {
2746
+ if (!obj.underline) return [];
2747
+ const lineWidths = obj.__lineWidths;
2748
+ return [{
2749
+ id: getObjectId(obj) ?? null,
2750
+ text: (obj.text || "").slice(0, 120),
2751
+ textLength: ((_a = obj.text) == null ? void 0 : _a.length) ?? 0,
2752
+ fontFamily: obj.fontFamily,
2753
+ fontSize: obj.fontSize,
2754
+ fontWeight: obj.fontWeight,
2755
+ width: obj.width ?? null,
2756
+ height: obj.height ?? null,
2757
+ scaleX: obj.scaleX,
2758
+ scaleY: obj.scaleY,
2759
+ lineCount: ((_b = obj.textLines) == null ? void 0 : _b.length) ?? 0,
2760
+ maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
2761
+ }];
2762
+ }
2763
+ if (obj instanceof fabric__namespace.Group) {
2764
+ return (obj._objects || []).flatMap((child) => collectUnderlineMetrics(child));
2765
+ }
2766
+ return [];
2767
+ };
2768
+ const beforeMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
2769
+ if (beforeMetrics.length > 0) {
2770
+ logUnderlineDebug("before-rerender", beforeMetrics);
2771
+ }
2732
2772
  const resetTextboxLayoutInternals = (obj) => {
2733
2773
  var _a;
2734
2774
  (_a = obj._clearCache) == null ? void 0 : _a.call(obj);
@@ -2743,7 +2783,7 @@ const clearFontCacheAndRerender = (canvas) => {
2743
2783
  obj.dirty = true;
2744
2784
  };
2745
2785
  const fixTextbox = (obj) => {
2746
- var _a, _b;
2786
+ var _a, _b, _c;
2747
2787
  if (obj instanceof fabric__namespace.Textbox) {
2748
2788
  const savedWidth = obj.width;
2749
2789
  const savedScaleX = obj.scaleX;
@@ -2756,15 +2796,35 @@ const clearFontCacheAndRerender = (canvas) => {
2756
2796
  obj.initDimensions();
2757
2797
  obj.set({ width: savedWidth, scaleX: savedScaleX, scaleY: savedScaleY, dirty: true });
2758
2798
  }
2759
- (_a = obj._clearCache) == null ? void 0 : _a.call(obj);
2799
+ if (obj.underline) {
2800
+ const lineWidths = obj.__lineWidths;
2801
+ logUnderlineDebug("textbox-rerender", {
2802
+ id: getObjectId(obj) ?? null,
2803
+ text: (obj.text || "").slice(0, 120),
2804
+ fontFamily: obj.fontFamily,
2805
+ fontSize: obj.fontSize,
2806
+ savedWidth,
2807
+ finalWidth: obj.width ?? null,
2808
+ finalHeight: obj.height ?? null,
2809
+ scaleX: obj.scaleX,
2810
+ scaleY: obj.scaleY,
2811
+ lineCount: ((_a = obj.textLines) == null ? void 0 : _a.length) ?? 0,
2812
+ maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
2813
+ });
2814
+ }
2815
+ (_b = obj._clearCache) == null ? void 0 : _b.call(obj);
2760
2816
  obj.setCoords();
2761
2817
  } else if (obj instanceof fabric__namespace.Group) {
2762
- (_b = obj._objects) == null ? void 0 : _b.forEach(fixTextbox);
2818
+ (_c = obj._objects) == null ? void 0 : _c.forEach(fixTextbox);
2763
2819
  obj.dirty = true;
2764
2820
  obj.setCoords();
2765
2821
  }
2766
2822
  };
2767
2823
  canvas.getObjects().forEach(fixTextbox);
2824
+ const afterMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
2825
+ if (afterMetrics.length > 0) {
2826
+ logUnderlineDebug("after-rerender", afterMetrics);
2827
+ }
2768
2828
  canvas.requestRenderAll();
2769
2829
  };
2770
2830
  const ensureFontLoaded = async (fontFamily) => {
@@ -2802,10 +2862,6 @@ const setupFontLoadingListener = (canvas, afterRerender) => {
2802
2862
  };
2803
2863
  };
2804
2864
  preloadAllFonts();
2805
- const getObjectId = (obj) => obj.__docuforgeId;
2806
- const setObjectData = (obj, id) => {
2807
- obj.__docuforgeId = id;
2808
- };
2809
2865
  const svgTextCache = /* @__PURE__ */ new Map();
2810
2866
  const htmlImageCache = /* @__PURE__ */ new Map();
2811
2867
  const MAX_CACHE_ENTRIES = 200;
@@ -11863,6 +11919,21 @@ async function ensureFontsForResolvedConfig(config) {
11863
11919
  });
11864
11920
  }
11865
11921
  }
11922
+ const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
11923
+ function countUnderlinedNodes(config) {
11924
+ var _a;
11925
+ if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return 0;
11926
+ let count = 0;
11927
+ const walk = (nodes) => {
11928
+ var _a2;
11929
+ for (const node of nodes || []) {
11930
+ if (node == null ? void 0 : node.underline) count += 1;
11931
+ if ((_a2 = node == null ? void 0 : node.children) == null ? void 0 : _a2.length) walk(node.children);
11932
+ }
11933
+ };
11934
+ for (const page of config.pages) walk(page.children || []);
11935
+ return count;
11936
+ }
11866
11937
  function PixldocsPreview(props) {
11867
11938
  const {
11868
11939
  pageIndex = 0,
@@ -11890,6 +11961,7 @@ function PixldocsPreview(props) {
11890
11961
  if (!isResolveMode) {
11891
11962
  setResolvedConfig(null);
11892
11963
  setCanvasSettled(false);
11964
+ console.log(PREVIEW_DEBUG_PREFIX, "config-mode active");
11893
11965
  return;
11894
11966
  }
11895
11967
  const p = props;
@@ -11898,6 +11970,12 @@ function PixldocsPreview(props) {
11898
11970
  setIsLoading(true);
11899
11971
  setFontsReady(false);
11900
11972
  setCanvasSettled(false);
11973
+ console.log(PREVIEW_DEBUG_PREFIX, "resolve-start", {
11974
+ templateId: p.templateId,
11975
+ formSchemaId: p.formSchemaId,
11976
+ themeId: p.themeId ?? null,
11977
+ pageIndex
11978
+ });
11901
11979
  resolveFromForm({
11902
11980
  templateId: p.templateId,
11903
11981
  formSchemaId: p.formSchemaId,
@@ -11906,15 +11984,22 @@ function PixldocsPreview(props) {
11906
11984
  supabaseUrl: p.supabaseUrl,
11907
11985
  supabaseAnonKey: p.supabaseAnonKey
11908
11986
  }).then((resolved) => {
11987
+ var _a, _b;
11909
11988
  if (!cancelled) {
11989
+ console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
11990
+ pages: ((_b = (_a = resolved.config) == null ? void 0 : _a.pages) == null ? void 0 : _b.length) ?? 0,
11991
+ underlinedNodes: countUnderlinedNodes(resolved.config)
11992
+ });
11910
11993
  setResolvedConfig(resolved.config);
11911
11994
  ensureFontsForResolvedConfig(resolved.config).then(() => {
11912
11995
  if (!cancelled) {
11996
+ console.log(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queued");
11913
11997
  setFontsReady(true);
11914
11998
  setIsLoading(false);
11915
11999
  }
11916
- }).catch(() => {
12000
+ }).catch((err) => {
11917
12001
  if (!cancelled) {
12002
+ console.warn(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queue failed", err);
11918
12003
  setFontsReady(true);
11919
12004
  setIsLoading(false);
11920
12005
  }
@@ -11923,6 +12008,7 @@ function PixldocsPreview(props) {
11923
12008
  }).catch((err) => {
11924
12009
  if (!cancelled) {
11925
12010
  setIsLoading(false);
12011
+ console.warn(PREVIEW_DEBUG_PREFIX, "resolve-error", err);
11926
12012
  onError == null ? void 0 : onError(err instanceof Error ? err : new Error(String(err)));
11927
12013
  }
11928
12014
  });
@@ -11939,18 +12025,28 @@ function PixldocsPreview(props) {
11939
12025
  ]);
11940
12026
  const config = isResolveMode ? resolvedConfig : props.config;
11941
12027
  react.useEffect(() => {
11942
- var _a, _b;
12028
+ var _a, _b, _c;
11943
12029
  if (!config) return;
11944
12030
  let cancelled = false;
11945
12031
  setCanvasSettled(false);
11946
12032
  setStabilizationPass(0);
12033
+ console.log(PREVIEW_DEBUG_PREFIX, "config-changed", {
12034
+ pageIndex,
12035
+ pages: ((_a = config.pages) == null ? void 0 : _a.length) ?? 0,
12036
+ underlinedNodes: countUnderlinedNodes(config),
12037
+ isResolveMode
12038
+ });
11947
12039
  const bump = () => {
11948
12040
  if (cancelled) return;
11949
12041
  clearMeasurementCache();
11950
12042
  clearFabricCharCache();
11951
- setFontsReadyVersion((v) => v + 1);
12043
+ setFontsReadyVersion((v) => {
12044
+ const next = v + 1;
12045
+ console.log(PREVIEW_DEBUG_PREFIX, "font-bump", { pageIndex, next, stabilizationPass });
12046
+ return next;
12047
+ });
11952
12048
  };
11953
- (_b = (_a = document.fonts) == null ? void 0 : _a.ready) == null ? void 0 : _b.then(bump);
12049
+ (_c = (_b = document.fonts) == null ? void 0 : _b.ready) == null ? void 0 : _c.then(bump);
11954
12050
  const timeoutId = window.setTimeout(bump, 350);
11955
12051
  return () => {
11956
12052
  cancelled = true;
@@ -11972,17 +12068,28 @@ function PixldocsPreview(props) {
11972
12068
  setFontsReady(false);
11973
12069
  setCanvasSettled(false);
11974
12070
  setStabilizationPass(0);
11975
- ensureFontsForResolvedConfig(config).then(() => setFontsReady(true)).catch(() => setFontsReady(true));
12071
+ ensureFontsForResolvedConfig(config).then(() => {
12072
+ console.log(PREVIEW_DEBUG_PREFIX, "config-mode fonts queued", {
12073
+ pageIndex,
12074
+ underlinedNodes: countUnderlinedNodes(config)
12075
+ });
12076
+ setFontsReady(true);
12077
+ }).catch((err) => {
12078
+ console.warn(PREVIEW_DEBUG_PREFIX, "config-mode fonts queue failed", err);
12079
+ setFontsReady(true);
12080
+ });
11976
12081
  }, [isResolveMode, config]);
11977
12082
  const handleCanvasReady = react.useCallback(() => {
11978
12083
  if (stabilizationPass === 0) {
12084
+ console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "stabilize-again" });
11979
12085
  setCanvasSettled(false);
11980
12086
  setStabilizationPass(1);
11981
12087
  return;
11982
12088
  }
12089
+ console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "settled" });
11983
12090
  setCanvasSettled(true);
11984
12091
  onReady == null ? void 0 : onReady();
11985
- }, [onReady, stabilizationPass]);
12092
+ }, [onReady, pageIndex, stabilizationPass]);
11986
12093
  if (isLoading) {
11987
12094
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
11988
12095
  }