@jxsuite/studio 3.0.0 → 4.0.0

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.
Files changed (173) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/Overlay.dev-723bv0df.js +23 -0
  3. package/dist/chunks/{cf-settings-zj2cj1ar.js → cf-settings-45fgyx8y.js} +6 -5
  4. package/dist/chunks/{components-z6cnkyy1.js → components-zmx10t62.js} +6 -5
  5. package/dist/chunks/content-source-t88vb2dr.js +49 -0
  6. package/dist/chunks/{convert-to-repeater-6vvx96n2.js → convert-to-repeater-dhw1nrz9.js} +27 -19
  7. package/dist/chunks/entry-commands-6z6bhxg0.js +46 -0
  8. package/dist/chunks/{extension-sections-kwzvpemr.js → extension-sections-3ydgjbdy.js} +32 -24
  9. package/dist/chunks/file-ops-rskmhxyq.js +48 -0
  10. package/dist/chunks/files-0cratsr0.js +92 -0
  11. package/dist/chunks/{format-host-8fr3545e.js → format-host-tgcmfs4p.js} +3 -3
  12. package/dist/chunks/fs-events-hrrg328g.js +21 -0
  13. package/dist/chunks/{git-panel-g01d93vc.js → git-panel-0yywyk76.js} +21 -16
  14. package/dist/chunks/{jx-validate-jj9rnt4n.js → jx-validate-8q2g05x1.js} +6 -4
  15. package/dist/chunks/layers-panel-z3tqe5cd.js +67 -0
  16. package/dist/chunks/layers-q75tj2mf.js +45 -0
  17. package/dist/chunks/lit-html-j055mkh8.js +22 -0
  18. package/dist/chunks/monaco-buffer-dqw0xxpx.js +25 -0
  19. package/dist/chunks/{monaco-setup-a5wkmbgh.js → monaco-setup-rws7k4br.js} +4 -4
  20. package/dist/chunks/notify-yjm79n4s.js +30 -0
  21. package/dist/chunks/parse-24d0gay3.js +19 -0
  22. package/dist/chunks/platform-ba1j1gbh.js +16 -0
  23. package/dist/chunks/publish-panel-54jvhskq.js +28 -0
  24. package/dist/chunks/quick-search-cgfmjwq5.js +65 -0
  25. package/dist/chunks/references-3qx8fkyp.js +29 -0
  26. package/dist/chunks/right-panel-cqp8bc4v.js +46 -0
  27. package/dist/chunks/sp-overlay.dev-yztmtrs1.js +18 -0
  28. package/dist/chunks/sp-popover.dev-n2etmqdp.js +9 -0
  29. package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +15 -0
  30. package/dist/chunks/sp-tooltip.dev-xcvpnqr0.js +15 -0
  31. package/dist/chunks/{sp-tray.dev-64v4pxw8.js → sp-tray.dev-tkbscm06.js} +5 -5
  32. package/dist/chunks/{studio-8ezdegcx.js → studio-1hbqnt19.js} +36 -32
  33. package/dist/chunks/{studio-r5xbtctf.js → studio-2zkz8evn.js} +446 -2451
  34. package/dist/chunks/{studio-pkp61mh8.js → studio-4pqqxbrt.js} +23 -15
  35. package/dist/chunks/{studio-kvfx9z2c.js → studio-4rzyrtjz.js} +70 -31
  36. package/dist/chunks/{studio-3dkcd4c5.js → studio-5q69gfag.js} +60 -56
  37. package/dist/chunks/{studio-rh1cnamv.js → studio-5rywrkxz.js} +563 -133
  38. package/dist/chunks/{studio-6kv3apa9.js → studio-68n67094.js} +25 -9
  39. package/dist/chunks/{studio-0rqqhrdy.js → studio-7nte2hj4.js} +2 -2
  40. package/dist/chunks/{studio-xntfdy1x.js → studio-8swrjbny.js} +31 -18
  41. package/dist/chunks/studio-92ab2jqe.js +282 -0
  42. package/dist/chunks/{studio-sas7mt3k.js → studio-9ab8gqsm.js} +2 -2
  43. package/dist/chunks/{studio-ry1vz5sv.js → studio-9c4k4vhv.js} +15 -13
  44. package/dist/chunks/studio-9n4mrmnb.js +184 -0
  45. package/dist/chunks/{studio-tr20m8g8.js → studio-9r6j5ev1.js} +37 -2
  46. package/dist/chunks/{studio-2x9zbxmx.js → studio-ahjfdy6e.js} +9 -7
  47. package/dist/chunks/{studio-s519zc99.js → studio-bgxt93ga.js} +3 -3
  48. package/dist/chunks/{studio-dc8s8heb.js → studio-cb12yz9w.js} +8528 -8780
  49. package/dist/chunks/studio-cft9r4r7.js +119 -0
  50. package/dist/chunks/{studio-hcxzyk3x.js → studio-eenfkt4e.js} +6 -6
  51. package/dist/chunks/studio-eesa1myv.js +498 -0
  52. package/dist/chunks/{studio-ay8wcr2b.js → studio-eqq1w638.js} +7 -9
  53. package/dist/chunks/{studio-7p35254k.js → studio-ex8zyp98.js} +30 -26
  54. package/dist/chunks/studio-gv8vvshc.js +118 -0
  55. package/dist/chunks/studio-hbtp0eh1.js +1315 -0
  56. package/dist/chunks/{studio-a0yp7syn.js → studio-htsf0w6m.js} +29 -114
  57. package/dist/chunks/{studio-j595e748.js → studio-kjjsjak4.js} +139 -63
  58. package/dist/chunks/{studio-5x5774ak.js → studio-kryvsw6j.js} +3 -3
  59. package/dist/chunks/{studio-kfpek536.js → studio-kyh9avvv.js} +2 -2
  60. package/dist/chunks/{studio-g5gdqnyd.js → studio-kyk2v92a.js} +14 -14
  61. package/dist/chunks/{studio-twsafr1e.js → studio-m3hwn7y1.js} +3 -3
  62. package/dist/chunks/{studio-tzx3xmvx.js → studio-mmv72a27.js} +8 -8
  63. package/dist/chunks/{studio-vhk5fmfv.js → studio-n8b9wqwy.js} +5 -5
  64. package/dist/chunks/{studio-cjm7fdjf.js → studio-p4ngc046.js} +8 -104
  65. package/dist/chunks/{studio-p5dja96s.js → studio-p8j86wag.js} +2 -2
  66. package/dist/chunks/{studio-6z5eyjwn.js → studio-pdfjntbk.js} +66 -129
  67. package/dist/chunks/studio-q43a5y9h.js +394 -0
  68. package/dist/chunks/studio-q7v10cg2.js +106 -0
  69. package/dist/chunks/{studio-2w11grav.js → studio-qq6jym04.js} +3 -3
  70. package/dist/chunks/studio-r1r7afxx.js +1066 -0
  71. package/dist/chunks/{studio-3fk1ac9z.js → studio-rdx8jcxy.js} +4 -4
  72. package/dist/chunks/{studio-4mqb9a0j.js → studio-rn9ta2mz.js} +4 -4
  73. package/dist/chunks/studio-sf7zjgv1.js +91 -0
  74. package/dist/chunks/studio-t7qb9db8.js +665 -0
  75. package/dist/chunks/studio-tmc5emrw.js +8 -0
  76. package/dist/chunks/{studio-wdt9y92a.js → studio-txwkm6p9.js} +2 -2
  77. package/dist/chunks/{studio-k4jvjcfx.js → studio-v38hmvx1.js} +7 -7
  78. package/dist/chunks/{studio-7ejemhej.js → studio-vadzgkrz.js} +6 -6
  79. package/dist/chunks/studio-wcy8trfx.js +263 -0
  80. package/dist/chunks/{studio-5efrtn1m.js → studio-wx5609xd.js} +21 -17
  81. package/dist/chunks/{studio-qpfq7xhm.js → studio-xrapxwwc.js} +22 -285
  82. package/dist/chunks/{studio-hj2se583.js → studio-yxrkyv8a.js} +41 -31
  83. package/dist/chunks/{studio-xm3dbxvn.js → studio-zczps70q.js} +2 -2
  84. package/dist/chunks/workspace-xpres40v.js +89 -0
  85. package/dist/iframe-entry.js +108 -24
  86. package/dist/studio.js +2362 -1695
  87. package/package.json +16 -15
  88. package/src/browse/library-pane.ts +57 -3
  89. package/src/canvas/canvas-render.ts +23 -1
  90. package/src/canvas/iframe-patch.ts +47 -21
  91. package/src/canvas/iframe-render.ts +22 -6
  92. package/src/commands/app-commands.ts +4 -0
  93. package/src/commands/command-args.ts +29 -0
  94. package/src/commands/context.ts +15 -1
  95. package/src/commands/defaults.ts +29 -1
  96. package/src/commands/levels.ts +16 -0
  97. package/src/commands/live-context.ts +3 -0
  98. package/src/content/collection-match.ts +267 -0
  99. package/src/content/entry-commands.ts +38 -29
  100. package/src/content/entry-fields.ts +6 -0
  101. package/src/editor/shortcuts.ts +5 -0
  102. package/src/files/file-ops.ts +10 -42
  103. package/src/files/files.ts +485 -59
  104. package/src/files/fs-events.ts +9 -0
  105. package/src/files/gitignore.ts +432 -0
  106. package/src/files/serialize-document.ts +60 -0
  107. package/src/format/convert-file.ts +511 -0
  108. package/src/format/format-choices.ts +199 -0
  109. package/src/grid/grid-view.ts +16 -2
  110. package/src/media/media-open.ts +58 -0
  111. package/src/media/media-pane.ts +310 -0
  112. package/src/new-project/import-tab.ts +332 -160
  113. package/src/new-project/new-project-modal.ts +27 -34
  114. package/src/packages/ensure-deps.ts +14 -7
  115. package/src/packages/jxsuite-update.ts +11 -11
  116. package/src/page-params.ts +10 -46
  117. package/src/panels/activity-bar.ts +45 -16
  118. package/src/panels/ai-chat/attached-context.ts +6 -1
  119. package/src/panels/ai-chat/chat-view.ts +255 -13
  120. package/src/panels/ai-chat/composer.ts +21 -97
  121. package/src/panels/ai-panel.ts +116 -2
  122. package/src/panels/navigator-panels.ts +7 -6
  123. package/src/panels/settings-menu.ts +799 -0
  124. package/src/panels/toolbar.ts +135 -15
  125. package/src/platforms/cloud.ts +20 -0
  126. package/src/platforms/devserver.ts +67 -33
  127. package/src/preview/preview-overlay.ts +226 -0
  128. package/src/services/ai-ask.ts +247 -0
  129. package/src/services/ai-import-tools.ts +494 -0
  130. package/src/services/ai-project-tools.ts +20 -26
  131. package/src/services/ai-system-prompt.ts +88 -2
  132. package/src/services/ai-turn-signal.ts +70 -0
  133. package/src/services/connection.ts +74 -0
  134. package/src/services/context-manager.ts +89 -0
  135. package/src/services/document-assistant.ts +45 -4
  136. package/src/services/import-client.ts +33 -6
  137. package/src/services/import-run.ts +158 -0
  138. package/src/services/import-seed.ts +120 -0
  139. package/src/services/jx-validate.ts +58 -6
  140. package/src/services/project-adoption.ts +71 -0
  141. package/src/services/references.ts +0 -0
  142. package/src/services/settings/definitions.ts +17 -0
  143. package/src/services/tool-executor.ts +34 -2
  144. package/src/settings/contexts-section.ts +45 -3
  145. package/src/settings/dependencies-editor.ts +43 -23
  146. package/src/settings/general-settings.ts +30 -12
  147. package/src/settings/preferences-dialog.ts +18 -41
  148. package/src/settings/preferences-sections.ts +57 -0
  149. package/src/settings/settings-document.ts +65 -9
  150. package/src/studio.ts +33 -6
  151. package/src/tabs/transact.ts +42 -19
  152. package/src/types.ts +103 -5
  153. package/src/ui/ai-model-picker.ts +162 -0
  154. package/src/ui/choice-field.ts +72 -0
  155. package/src/ui/layers.ts +83 -5
  156. package/src/utils/studio-utils.ts +22 -52
  157. package/styles/forced-colors.css +7 -0
  158. package/styles/overlays.css +256 -0
  159. package/styles/panels.css +13 -1
  160. package/styles/shell.css +111 -0
  161. package/dist/chunks/Overlay.dev-d2ajy6sj.js +0 -23
  162. package/dist/chunks/content-source-7fy9qrm0.js +0 -40
  163. package/dist/chunks/files-xcybanxe.js +0 -70
  164. package/dist/chunks/layers-panel-27essgkc.js +0 -60
  165. package/dist/chunks/publish-panel-09sy2bab.js +0 -22
  166. package/dist/chunks/quick-search-sefb61v8.js +0 -55
  167. package/dist/chunks/right-panel-9r32jd5j.js +0 -39
  168. package/dist/chunks/sp-overlay.dev-s18hymn9.js +0 -18
  169. package/dist/chunks/sp-popover.dev-dj9x7e7a.js +0 -9
  170. package/dist/chunks/sp-progress-circle.dev-0zxcyz3r.js +0 -15
  171. package/dist/chunks/sp-tooltip.dev-5c6d1kjz.js +0 -15
  172. package/dist/chunks/studio-c31yb4t6.js +0 -55
  173. package/src/canvas/site-style-css.ts +0 -117
@@ -2688,6 +2688,32 @@ function evaluateTemplate(str, state) {
2688
2688
  const fn = new Function("state", "$map", "item", "index", `return \`${str}\``);
2689
2689
  return fn(state, $map, $map?.item, $map?.index);
2690
2690
  }
2691
+ function isSingleExpression(str) {
2692
+ if (!str.startsWith("${") || !str.endsWith("}")) {
2693
+ return false;
2694
+ }
2695
+ let depth = 0;
2696
+ for (let i = 1;i < str.length; i += 1) {
2697
+ const c = str[i];
2698
+ if (c === "{") {
2699
+ depth += 1;
2700
+ } else if (c === "}") {
2701
+ depth -= 1;
2702
+ if (depth === 0) {
2703
+ return i === str.length - 1;
2704
+ }
2705
+ }
2706
+ }
2707
+ return false;
2708
+ }
2709
+ function evaluateAttrTemplate(str, state) {
2710
+ if (!isSingleExpression(str)) {
2711
+ return evaluateTemplate(str, state);
2712
+ }
2713
+ const $map = state?.$map;
2714
+ const fn = new Function("state", "$map", "item", "index", `return (${str.slice(2, -1)})`);
2715
+ return fn(state, $map, $map?.item, $map?.index);
2716
+ }
2691
2717
  var _moduleCache = new Map;
2692
2718
  async function resolveFunction(def2, state, key, base) {
2693
2719
  if (def2.body && def2.$src) {
@@ -3084,16 +3110,33 @@ function reapplyStyle(el, styleDef, mediaQueries = {}, state = {}) {
3084
3110
  delete el.dataset.jx;
3085
3111
  applyStyle(el, styleDef ?? {}, mediaQueries, state);
3086
3112
  }
3113
+ var ENUMERATED_ATTRS = new Set(["contenteditable", "draggable", "spellcheck"]);
3114
+ function booleanAttrValue(name, value) {
3115
+ const lower = name.toLowerCase();
3116
+ if (lower.startsWith("aria-") || ENUMERATED_ATTRS.has(lower)) {
3117
+ return String(value);
3118
+ }
3119
+ return value ? "" : null;
3120
+ }
3087
3121
  function applyAttributes(el, attrs, state) {
3088
3122
  for (const [k, v] of Object.entries(attrs)) {
3089
3123
  const attr = canvasAttrName(el, k);
3090
3124
  const write = (resolved) => {
3125
+ if (typeof resolved === "boolean") {
3126
+ const text = booleanAttrValue(attr, resolved);
3127
+ if (text === null) {
3128
+ el.removeAttribute(attr);
3129
+ } else {
3130
+ el.setAttribute(attr, text);
3131
+ }
3132
+ return;
3133
+ }
3091
3134
  el.setAttribute(attr, canvasAssetValue(el.tagName, k, String(resolved ?? "")));
3092
3135
  };
3093
3136
  if (isRefObj(v)) {
3094
3137
  effect(() => write(resolveRef(v.$ref, state)));
3095
3138
  } else if (isTemplateString(v)) {
3096
- effect(() => write(evaluateTemplate(v, state)));
3139
+ effect(() => write(evaluateAttrTemplate(v, state)));
3097
3140
  } else {
3098
3141
  write(v);
3099
3142
  }
@@ -4128,7 +4171,7 @@ function parseJxPath(serialized) {
4128
4171
  return JSON.parse(serialized);
4129
4172
  }
4130
4173
 
4131
- // src/canvas/site-style-css.ts
4174
+ // ../site/src/site-style.ts
4132
4175
  var SITE_STYLE_ID = "jx-site-style";
4133
4176
  function toDecls(props, transpose) {
4134
4177
  return Object.entries(props).map(([key, value]) => `${camelToKebab(key)}: ${transpose(String(value))}`).join("; ");
@@ -4252,7 +4295,7 @@ var EDIT_PLACEHOLDER_CSS = `
4252
4295
  font-size: 0;
4253
4296
  overflow: hidden;
4254
4297
  }
4255
- .empty-text-placeholder:not([contenteditable])::after {
4298
+ .empty-text-placeholder:is(:empty, :has(> br:only-child)):not([data-jx-active-block]):not([contenteditable])::after {
4256
4299
  content: "Click here to add text...";
4257
4300
  color: color-mix(in srgb, #808080 40%, transparent);
4258
4301
  font-style: italic;
@@ -4278,7 +4321,7 @@ var EDIT_PLACEHOLDER_CSS = `
4278
4321
  pointer-events: none;
4279
4322
  white-space: nowrap;
4280
4323
  }
4281
- [data-jx-active-block]:empty::after {
4324
+ [data-jx-active-block]:is(:empty, :has(> br:only-child))::after {
4282
4325
  content: "Type / for commands";
4283
4326
  color: color-mix(in srgb, #808080 40%, transparent);
4284
4327
  font-style: italic;
@@ -7397,6 +7440,42 @@ function startIframeSlashBridge(channel, doc) {
7397
7440
 
7398
7441
  // src/commands/levels.ts
7399
7442
  var KEY_SCOPES = ["global", "canvas", "caret", "grid", "code", "dock", "palette"];
7443
+ var PLACEMENT_MATRIX = {
7444
+ "commandbar/primary": {
7445
+ admits: ["application", "document"],
7446
+ note: "document only for Save / Undo / Redo / Open in Browser, by frequency; ≤5 total"
7447
+ },
7448
+ "commandbar/overflow": {
7449
+ admits: ["application", "project", "document"],
7450
+ note: "never selection — the Command Bar is not a selection surface"
7451
+ },
7452
+ "statusbar/project": { admits: ["project"], note: "the status bar's left field" },
7453
+ "statusbar/document": { admits: ["document"], note: "the status bar's centre field" },
7454
+ "statusbar/selection": { admits: ["selection"], note: "the status bar's right field" },
7455
+ "context/element": { admits: ["selection"], note: "the canvas element menu acts on a selection" },
7456
+ "context/file": { admits: ["project"], note: "a file row addresses the project's file set" },
7457
+ "context/layer": { admits: ["selection"], note: "an outline row IS a selection" },
7458
+ "context/tab": { admits: ["document"], note: "a tab addresses one document" },
7459
+ "context/pane": { admits: ["document"], note: "a pane hosts one document" },
7460
+ blockbar: { admits: ["selection"], note: "the floating bar owns selection-scoped verbs" },
7461
+ "blockbar/format": {
7462
+ admits: ["selection"],
7463
+ note: "the bar's inline-format cluster — a range inside the selection is still the selection"
7464
+ },
7465
+ "outline/row": { admits: ["selection"], note: "row actions act on the row's node" },
7466
+ "settings/menu": {
7467
+ admits: ["application", "project"],
7468
+ note: "the rail foot's gear menu — the settings family. It is a MENU, not a pinned slot, so it " + "may host two levels for the reason commandbar/overflow does: a menu prints each row's own " + "name, chord and gate, and draws a divider where the level changes. The rail's PINNED " + "groups stay single-level, in PANEL_PLACEMENT_MATRIX"
7469
+ },
7470
+ palette: {
7471
+ admits: ["application", "project", "document", "selection"],
7472
+ note: "the level-agnostic surface; it groups rows by level"
7473
+ },
7474
+ never: {
7475
+ admits: ["application", "project", "document", "selection"],
7476
+ note: "keyboard- and API-only; no rendered surface to be misplaced in"
7477
+ }
7478
+ };
7400
7479
 
7401
7480
  // src/commands/keymap.ts
7402
7481
  var MODIFIER_ORDER = ["mod", "ctrl", "alt", "shift"];
@@ -7683,11 +7762,18 @@ function applyIframePatch(shadowDoc, forwardOps, container, ctx, echoPaths) {
7683
7762
  const echoed = new Set(echoPaths.map((p) => serializeJxPath(p)));
7684
7763
  for (const op of forwardOps) {
7685
7764
  if (op.op === "set-key" && echoed.has(serializeJxPath(op.path))) {
7765
+ syncEchoedPlaceholder(shadowDoc, op.path, container);
7686
7766
  continue;
7687
7767
  }
7688
7768
  applyOpToDom(shadowDoc, op, container, ctx);
7689
7769
  }
7690
7770
  }
7771
+ function syncEchoedPlaceholder(doc, path, container) {
7772
+ const el = findElement(container, path);
7773
+ if (el) {
7774
+ syncPlaceholderClass(el, getNodeAtPath(doc, path));
7775
+ }
7776
+ }
7691
7777
  function requireCtx(ctx) {
7692
7778
  if (!ctx) {
7693
7779
  throw new Error("iframe-patch-no-render-ctx");
@@ -7738,7 +7824,7 @@ function insertChild(doc, parentPath, index, container, ctx) {
7738
7824
  const newEl = renderSubtreeIframe(doc, [...parentPath, "children", index], ctx);
7739
7825
  remapChildPaths(container, parentPath, index, 1);
7740
7826
  insertAt(parentEl, newEl, domChildReference(parentEl, parentNode, index));
7741
- syncContainerPlaceholder(parentEl, parentNode);
7827
+ syncPlaceholderClass(parentEl, parentNode);
7742
7828
  }
7743
7829
  function replaceSubtree(doc, docPath, container, ctx) {
7744
7830
  const oldEl = requireElement(container, docPath);
@@ -7753,7 +7839,7 @@ function removeChild(doc, parentPath, index, container) {
7753
7839
  el.remove();
7754
7840
  remapChildPaths(container, parentPath, index + 1, -1);
7755
7841
  if (parentEl) {
7756
- syncContainerPlaceholder(parentEl, getNodeAtPath(doc, parentPath));
7842
+ syncPlaceholderClass(parentEl, getNodeAtPath(doc, parentPath));
7757
7843
  }
7758
7844
  }
7759
7845
  function moveChild(doc, fromParentPath, fromIndex, toParentPath, toIndex, container) {
@@ -7769,17 +7855,17 @@ function moveChild(doc, fromParentPath, fromIndex, toParentPath, toIndex, contai
7769
7855
  const toParentNode = getNodeAtPath(doc, toPrefix);
7770
7856
  insertAt(toParentEl, el, domChildReference(toParentEl, toParentNode, toIndex));
7771
7857
  if (fromParentEl) {
7772
- syncContainerPlaceholder(fromParentEl, getNodeAtPath(doc, elementPath(fromParentEl) ?? fromParentPath));
7858
+ syncPlaceholderClass(fromParentEl, getNodeAtPath(doc, elementPath(fromParentEl) ?? fromParentPath));
7773
7859
  }
7774
- syncContainerPlaceholder(toParentEl, toParentNode);
7860
+ syncPlaceholderClass(toParentEl, toParentNode);
7775
7861
  }
7776
- function syncContainerPlaceholder(parentEl, parentNode) {
7862
+ function syncPlaceholderClass(el, node) {
7777
7863
  for (const cls of EMPTY_PLACEHOLDER_CLASSES) {
7778
- parentEl.classList.remove(cls);
7864
+ el.classList.remove(cls);
7779
7865
  }
7780
- const placeholder = parentNode ? computeEmptyPlaceholderClass(parentNode) : null;
7866
+ const placeholder = node ? computeEmptyPlaceholderClass(node) : null;
7781
7867
  if (placeholder) {
7782
- parentEl.classList.add(placeholder);
7868
+ el.classList.add(placeholder);
7783
7869
  }
7784
7870
  }
7785
7871
  function insertAt(parentEl, node, ref2) {
@@ -7837,22 +7923,20 @@ function patchText(doc, path, container) {
7837
7923
  const el = requireElement(container, path);
7838
7924
  const node = getNodeAtPath(doc, path);
7839
7925
  el.textContent = textDisplayValue(node);
7840
- for (const cls of EMPTY_PLACEHOLDER_CLASSES) {
7841
- el.classList.remove(cls);
7842
- }
7843
- const placeholder = node ? computeEmptyPlaceholderClass(node) : null;
7844
- if (placeholder) {
7845
- el.classList.add(placeholder);
7846
- }
7926
+ syncPlaceholderClass(el, node);
7847
7927
  }
7848
7928
  function requireElement(container, path) {
7929
+ const el = findElement(container, path);
7930
+ if (!el) {
7931
+ throw new Error(`iframe-patch-element-not-found:${serializeJxPath(path)}`);
7932
+ }
7933
+ return el;
7934
+ }
7935
+ function findElement(container, path) {
7849
7936
  const serialized = serializeJxPath(path);
7850
7937
  const esc = serialized.replaceAll("\\", String.raw`\\`).replaceAll("'", String.raw`\'`);
7851
7938
  const el = container.querySelector(`[data-jx-path='${esc}']`);
7852
- if (!(el instanceof HTMLElement)) {
7853
- throw new Error(`iframe-patch-element-not-found:${serialized}`);
7854
- }
7855
- return el;
7939
+ return el instanceof HTMLElement ? el : null;
7856
7940
  }
7857
7941
  function editModeStyle(style) {
7858
7942
  if (!style || typeof style !== "object") {
@@ -8580,5 +8664,5 @@ export {
8580
8664
  startCanvasIframe
8581
8665
  };
8582
8666
 
8583
- //# debugId=39CA18389F1F06A664756E2164756E21
8667
+ //# debugId=1D7D4718E26F550F64756E2164756E21
8584
8668
  //# sourceMappingURL=iframe-entry.js.map