superdoc 2.23.1-next.1 → 2.23.1-next.11

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.
@@ -1,6 +1,6 @@
1
1
  import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
2
2
  import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
3
- import { c as createImageFilePicker, d as DOM_CLASS_NAMES, f as closeInteractionHistory, g as recordInteraction, h as isWorkflowRecordingEnabled, i as registerFirstPartyCommandMutation, l as resolveImageSrc, m as getWorkflowRecording, n as executeFirstPartyCommandAsync, o as applyV2CommentInvalidationFromMutation, p as createInteractionHistory, r as readFirstPartyPageNumbers, s as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-B8N_IUG2.es.js";
3
+ import { c as createImageFilePicker, d as DOM_CLASS_NAMES, f as closeInteractionHistory, g as recordInteraction, h as isWorkflowRecordingEnabled, i as registerFirstPartyCommandMutation, l as resolveImageSrc, m as getWorkflowRecording, n as executeFirstPartyCommandAsync, o as applyV2CommentInvalidationFromMutation, p as createInteractionHistory, r as readFirstPartyPageNumbers, s as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-DFNXiKvQ.es.js";
4
4
  import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
5
5
  import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
6
6
  import { $ as watch$1, A as onActivated, B as resolveDirective, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toRef, H as shallowRef$1, I as reactive, J as useAttrs, K as toRefs, L as ref, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelText, R as renderList, S as isReactive$1, T as mergeProps, U as toDisplayString, V as resolveDynamicComponent, W as toRaw$2, X as vModelCheckbox, Y as useSlots, Z as vModelSelect, _ as getCurrentInstance, a as computed$1, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as withCtx, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withKeys, o as createApp, p as createVNode, q as unref, r as Teleport, rt as withModifiers, s as createBlock, t as _plugin_vue_export_helper_default, tt as withDirectives, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as renderSlot } from "./chunks/_plugin-vue_export-helper-DHiJKCsy.es.js";
@@ -302,7 +302,7 @@ var awarenessStatesToArray = (context, states) => {
302
302
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
303
303
  function getSuperdocVersion() {
304
304
  try {
305
- return "2.23.1-next.1";
305
+ return "2.23.1-next.11";
306
306
  } catch {
307
307
  return "unknown";
308
308
  }
@@ -12200,7 +12200,7 @@ function useUiFontFamily() {
12200
12200
  }
12201
12201
  //#endregion
12202
12202
  //#region src/components/CommentsLayer/CommentsDropdown.vue
12203
- var _hoisted_1$32 = { class: "comments-dropdown" };
12203
+ var _hoisted_1$31 = { class: "comments-dropdown" };
12204
12204
  var _hoisted_2$25 = ["onClick"];
12205
12205
  var _hoisted_3$21 = {
12206
12206
  key: 0,
@@ -12331,7 +12331,7 @@ var CommentsDropdown_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12331
12331
  window.removeEventListener("scroll", updateMenuPosition, true);
12332
12332
  });
12333
12333
  return (_ctx, _cache) => {
12334
- return openBlock(), createElementBlock("div", _hoisted_1$32, [createElementVNode("div", {
12334
+ return openBlock(), createElementBlock("div", _hoisted_1$31, [createElementVNode("div", {
12335
12335
  ref_key: "triggerRef",
12336
12336
  ref: triggerRef,
12337
12337
  class: "comments-dropdown__trigger",
@@ -12360,7 +12360,7 @@ var CommentsDropdown_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12360
12360
  }, [["__scopeId", "data-v-7eced80a"]]);
12361
12361
  //#endregion
12362
12362
  //#region src/components/CommentsLayer/InternalDropdown.vue
12363
- var _hoisted_1$31 = { class: "sd-comment-option" };
12363
+ var _hoisted_1$30 = { class: "sd-comment-option" };
12364
12364
  var _hoisted_2$24 = ["innerHTML"];
12365
12365
  var _hoisted_3$20 = { class: "sd-option-state" };
12366
12366
  var _hoisted_4$12 = ["innerHTML"];
@@ -12431,7 +12431,7 @@ var InternalDropdown_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12431
12431
  disabled: __props.isDisabled,
12432
12432
  "content-style": { fontFamily: unref(uiFontFamily) }
12433
12433
  }, {
12434
- default: withCtx(() => [createElementVNode("div", _hoisted_1$31, [
12434
+ default: withCtx(() => [createElementVNode("div", _hoisted_1$30, [
12435
12435
  createElementVNode("div", {
12436
12436
  class: "sd-active-icon",
12437
12437
  innerHTML: activeIcon.value
@@ -12596,7 +12596,7 @@ var isAllowed = (permission, role, isInternal, context = {}) => {
12596
12596
  };
12597
12597
  //#endregion
12598
12598
  //#region src/components/general/Avatar.vue
12599
- var _hoisted_1$30 = { class: "user-container" };
12599
+ var _hoisted_1$29 = { class: "user-container" };
12600
12600
  var _hoisted_2$23 = ["src"];
12601
12601
  var _hoisted_3$19 = {
12602
12602
  key: 1,
@@ -12619,7 +12619,7 @@ var Avatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12619
12619
  return email?.substring(0, 1)?.toUpperCase() || null;
12620
12620
  };
12621
12621
  return (_ctx, _cache) => {
12622
- return openBlock(), createElementBlock("div", _hoisted_1$30, [__props.user.image ? (openBlock(), createElementBlock("img", {
12622
+ return openBlock(), createElementBlock("div", _hoisted_1$29, [__props.user.image ? (openBlock(), createElementBlock("img", {
12623
12623
  key: 0,
12624
12624
  class: "user-bg",
12625
12625
  src: __props.user.image.startsWith("http") ? __props.user.image : `data:image/png;base64,${__props.user.image}`
@@ -12629,7 +12629,7 @@ var Avatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12629
12629
  }, [["__scopeId", "data-v-c95b2073"]]);
12630
12630
  //#endregion
12631
12631
  //#region src/components/CommentsLayer/CommentHeader.vue
12632
- var _hoisted_1$29 = { class: "card-section comment-header" };
12632
+ var _hoisted_1$28 = { class: "card-section comment-header" };
12633
12633
  var _hoisted_2$22 = { class: "comment-header-left" };
12634
12634
  var _hoisted_3$18 = { class: "user-info" };
12635
12635
  var _hoisted_4$11 = { class: "user-name" };
@@ -12889,7 +12889,7 @@ var CommentHeader_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12889
12889
  return user;
12890
12890
  });
12891
12891
  return (_ctx, _cache) => {
12892
- return openBlock(), createElementBlock("div", _hoisted_1$29, [createElementVNode("div", _hoisted_2$22, [createVNode(Avatar_default, {
12892
+ return openBlock(), createElementBlock("div", _hoisted_1$28, [createElementVNode("div", _hoisted_2$22, [createVNode(Avatar_default, {
12893
12893
  user: getCurrentUser.value,
12894
12894
  class: "avatar"
12895
12895
  }, null, 8, ["user"]), createElementVNode("div", _hoisted_3$18, [createElementVNode("div", _hoisted_4$11, [createTextVNode(toDisplayString(getCurrentUser.value.name), 1), isImported.value ? (openBlock(), createElementBlock("span", _hoisted_5$9, "IMPORTED")) : createCommentVNode("", true)]), props.comment.createdTime ? (openBlock(), createElementBlock("div", _hoisted_6$8, toDisplayString(unref(formatDate)(props.comment.createdTime)), 1)) : createCommentVNode("", true)])]), createElementVNode("div", { class: normalizeClass(["overflow-menu", { "is-visible": props.isActive }]) }, [
@@ -12940,7 +12940,7 @@ var CommentHeader_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
12940
12940
  }, [["__scopeId", "data-v-f2f11c96"]]);
12941
12941
  //#endregion
12942
12942
  //#region src/components/CommentsLayer/CommentInput.vue
12943
- var _hoisted_1$28 = { class: "input-section" };
12943
+ var _hoisted_1$27 = { class: "input-section" };
12944
12944
  var _hoisted_2$21 = { class: "comment-composer" };
12945
12945
  var _hoisted_3$17 = [
12946
12946
  "aria-expanded",
@@ -13114,7 +13114,7 @@ var CommentInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13114
13114
  watch$1(currentCommentText, scheduleInputHeightSync);
13115
13115
  __expose({ focus });
13116
13116
  return (_ctx, _cache) => {
13117
- return openBlock(), createElementBlock("div", _hoisted_1$28, [__props.includeHeader ? (openBlock(), createBlock(CommentHeader_default, {
13117
+ return openBlock(), createElementBlock("div", _hoisted_1$27, [__props.includeHeader ? (openBlock(), createBlock(CommentHeader_default, {
13118
13118
  key: 0,
13119
13119
  config: __props.config,
13120
13120
  comment: __props.comment,
@@ -13159,8 +13159,116 @@ var CommentInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13159
13159
  }
13160
13160
  }, [["__scopeId", "data-v-0720a671"]]);
13161
13161
  //#endregion
13162
+ //#region src/internal/toolbar/built-in/url-safety.js
13163
+ /**
13164
+ * Minimal href sanitizer for the built-in link popover.
13165
+ *
13166
+ * The v1 toolbar used the shared `@superdoc/url-validation` package, which is not
13167
+ * a resolvable runtime dependency of the published `superdoc` ES build. This
13168
+ * keeps the same fail-closed posture (only known-safe schemes pass) without
13169
+ * pulling in that package: dangerous schemes (`javascript:`, `data:`,
13170
+ * `vbscript:`) return `null`, mirroring the v1 contract that callers treat a
13171
+ * `null` result as an invalid URL.
13172
+ */
13173
+ var SAFE_SCHEME = /^(https?|mailto|tel):/i;
13174
+ var DANGEROUS_SCHEME = /^(javascript|data|vbscript):/i;
13175
+ var HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
13176
+ /**
13177
+ * Validate and normalize an href. Returns `{ href }` for safe values, or `null`.
13178
+ * @param {string} value
13179
+ * @returns {{ href: string }|null}
13180
+ */
13181
+ function sanitizeHref(value) {
13182
+ if (typeof value !== "string") return null;
13183
+ const trimmed = value.trim();
13184
+ if (!trimmed) return null;
13185
+ if (trimmed.startsWith("#")) return { href: trimmed };
13186
+ if (DANGEROUS_SCHEME.test(trimmed)) return null;
13187
+ if (HAS_SCHEME.test(trimmed)) return SAFE_SCHEME.test(trimmed) ? { href: trimmed } : null;
13188
+ return { href: trimmed };
13189
+ }
13190
+ //#endregion
13191
+ //#region src/components/CommentsLayer/comment-urls.js
13192
+ function isAbsoluteWebUrl(value) {
13193
+ if (!/^https?:\/\/[^\s/?#\\]+/i.test(value) || /[\s\\]/u.test(value)) return false;
13194
+ try {
13195
+ const url = new URL(value);
13196
+ return (url.protocol === "https:" || url.protocol === "http:") && Boolean(url.hostname);
13197
+ } catch {
13198
+ return false;
13199
+ }
13200
+ }
13201
+ function trimUrlPunctuation(value) {
13202
+ const closingDelimiter = {
13203
+ "(": ")",
13204
+ "[": "]",
13205
+ "{": "}"
13206
+ };
13207
+ const balance = {
13208
+ ")": 0,
13209
+ "]": 0,
13210
+ "}": 0
13211
+ };
13212
+ for (const character of value) {
13213
+ const close = closingDelimiter[character];
13214
+ if (close) balance[close] += 1;
13215
+ else if (Object.hasOwn(balance, character)) balance[character] -= 1;
13216
+ }
13217
+ let end = value.length;
13218
+ while (end > 0) {
13219
+ const character = value[end - 1];
13220
+ if (".,!?;:".includes(character)) end -= 1;
13221
+ else if (balance[character] < 0) {
13222
+ balance[character] += 1;
13223
+ end -= 1;
13224
+ } else break;
13225
+ }
13226
+ return value.slice(0, end);
13227
+ }
13228
+ function configureLink(link, href) {
13229
+ link.setAttribute("href", href);
13230
+ link.setAttribute("target", "_blank");
13231
+ link.setAttribute("rel", "noopener noreferrer");
13232
+ }
13233
+ /** Render links without rewriting stored comment HTML or its rich-text structure. */
13234
+ function renderCommentHtml(value) {
13235
+ if (typeof value !== "string") return "";
13236
+ if (typeof document === "undefined") return value;
13237
+ const template = document.createElement("template");
13238
+ template.innerHTML = value;
13239
+ for (const link of template.content.querySelectorAll("a")) {
13240
+ const safe = sanitizeHref(link.getAttribute("href"));
13241
+ if (safe && (isAbsoluteWebUrl(safe.href) || /^(mailto|tel):\S+$/i.test(safe.href))) configureLink(link, safe.href);
13242
+ else link.replaceWith(...link.childNodes);
13243
+ }
13244
+ const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_TEXT);
13245
+ const textNodes = [];
13246
+ while (walker.nextNode()) textNodes.push(walker.currentNode);
13247
+ for (const node of textNodes) {
13248
+ if (node.parentElement?.closest("a, script, style, textarea, code, pre")) continue;
13249
+ const text = node.textContent;
13250
+ const fragment = document.createDocumentFragment();
13251
+ let end = 0;
13252
+ for (const match of text.matchAll(/(^|[\s([{])(https?:\/\/[^\s<>"']+)/gi)) {
13253
+ const href = trimUrlPunctuation(match[2]);
13254
+ if (!isAbsoluteWebUrl(href)) continue;
13255
+ const start = match.index + match[1].length;
13256
+ fragment.append(document.createTextNode(text.slice(end, start)));
13257
+ const link = document.createElement("a");
13258
+ configureLink(link, href);
13259
+ link.textContent = href;
13260
+ fragment.append(link);
13261
+ end = start + href.length;
13262
+ }
13263
+ if (end === 0) continue;
13264
+ fragment.append(document.createTextNode(text.slice(end)));
13265
+ node.replaceWith(fragment);
13266
+ }
13267
+ return template.innerHTML;
13268
+ }
13269
+ //#endregion
13162
13270
  //#region src/components/CommentsLayer/CommentDialog.vue
13163
- var _hoisted_1$27 = [
13271
+ var _hoisted_1$26 = [
13164
13272
  "aria-label",
13165
13273
  "data-comment-instance-id",
13166
13274
  "data-comment-thread-id",
@@ -13540,6 +13648,12 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13540
13648
  return a.createdTime - b.createdTime;
13541
13649
  });
13542
13650
  });
13651
+ const renderedCommentTexts = computed$1(() => new Map(comments.value.map((comment) => [comment.commentId, renderCommentHtml(comment.commentText)])));
13652
+ const handleDialogClick = (event) => {
13653
+ if (event.target instanceof Element && event.target.closest(".comment a[href]")) return;
13654
+ event.preventDefault();
13655
+ return setFocus();
13656
+ };
13543
13657
  const dialogAccessibleLabel = computed$1(() => {
13544
13658
  if (props.comment.trackedChangeLabel) return props.comment.trackedChangeLabel;
13545
13659
  if (props.comment.trackedChange) return "Tracked change discussion";
@@ -14168,7 +14282,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14168
14282
  "is-active": isDialogActive.value || isPendingNewComment.value,
14169
14283
  "is-resolved": props.comment.resolvedTime
14170
14284
  }]),
14171
- onClick: withModifiers(setFocus, ["stop", "prevent"]),
14285
+ onClick: withModifiers(handleDialogClick, ["stop"]),
14172
14286
  style: normalizeStyle(getSidebarCommentStyle.value),
14173
14287
  ref_key: "commentDialogElement",
14174
14288
  ref: commentDialogElement,
@@ -14305,7 +14419,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14305
14419
  class: normalizeClass(["comment", index === 0 ? bodyOverflowClass.value : void 0]),
14306
14420
  ref_for: true,
14307
14421
  ref: index === 0 ? setParentBodyRef : void 0,
14308
- innerHTML: comment.commentText
14422
+ innerHTML: renderedCommentTexts.value.get(comment.commentId)
14309
14423
  }, null, 10, _hoisted_38)) : unref(isDebugging) && !isEditingThisComment.value(comment) ? (openBlock(), createElementBlock("div", _hoisted_39, toDisplayString(unref(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : (openBlock(), createElementBlock("div", _hoisted_40, [createElementVNode("div", _hoisted_41, [createVNode(CommentInput_default, {
14310
14424
  ref_for: true,
14311
14425
  ref: setEditCommentInputRef(comment.commentId),
@@ -14378,13 +14492,13 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14378
14492
  disabled: !hasTextContent.value || isV2WriteDisabled.value || isSubmittingReply.value,
14379
14493
  "data-disabled-reason": v2ReplyDisabledReason.value
14380
14494
  }, " Reply ", 10, _hoisted_53)])]))], 64)) : createCommentVNode("", true)
14381
- ], 64))], 14, _hoisted_1$27)), [[_directive_click_outside, handleClickOutside]]);
14495
+ ], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
14382
14496
  };
14383
14497
  }
14384
- }, [["__scopeId", "data-v-dcbcc0d4"]]);
14498
+ }, [["__scopeId", "data-v-c189ab35"]]);
14385
14499
  //#endregion
14386
14500
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14387
- var _hoisted_1$26 = [
14501
+ var _hoisted_1$25 = [
14388
14502
  "tabindex",
14389
14503
  "aria-posinset",
14390
14504
  "aria-setsize",
@@ -14522,13 +14636,13 @@ var ReviewDirectoryListItem_default = /*#__PURE__*/ _plugin_vue_export_helper_de
14522
14636
  "floating-page-index",
14523
14637
  "floating-position-entry",
14524
14638
  "is-floating-instance-active"
14525
- ])) : createCommentVNode("", true)], 44, _hoisted_1$26);
14639
+ ])) : createCommentVNode("", true)], 44, _hoisted_1$25);
14526
14640
  };
14527
14641
  }
14528
14642
  }, [["__scopeId", "data-v-29650a06"]]);
14529
14643
  //#endregion
14530
14644
  //#region src/components/CommentsLayer/commentsList/commentsList.vue
14531
- var _hoisted_1$25 = ["aria-busy"];
14645
+ var _hoisted_1$24 = ["aria-busy"];
14532
14646
  var _hoisted_2$19 = { key: 0 };
14533
14647
  var _hoisted_3$15 = { key: 1 };
14534
14648
  var REPEATED_HEADER_FOOTER_STORY_TYPE = "headerFooterPart";
@@ -14689,7 +14803,7 @@ var commentsList_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14689
14803
  "total",
14690
14804
  "tab-index"
14691
14805
  ]);
14692
- }), 128))])) : createCommentVNode("", true)], 8, _hoisted_1$25);
14806
+ }), 128))])) : createCommentVNode("", true)], 8, _hoisted_1$24);
14693
14807
  };
14694
14808
  }
14695
14809
  }, [["__scopeId", "data-v-89244745"]]);
@@ -15158,7 +15272,7 @@ var resolveRemovedReviewCardContinuityTarget = ({ previousIds, currentIds, remov
15158
15272
  };
15159
15273
  //#endregion
15160
15274
  //#region src/components/CommentsLayer/FloatingComments.vue
15161
- var _hoisted_1$24 = [
15275
+ var _hoisted_1$23 = [
15162
15276
  "data-comment-id",
15163
15277
  "data-comment-instance-id",
15164
15278
  "data-comment-thread-id",
@@ -16028,14 +16142,14 @@ var FloatingComments_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
16028
16142
  "floating-page-index",
16029
16143
  "floating-position-entry",
16030
16144
  "is-floating-instance-active"
16031
- ])) : createCommentVNode("", true)], 14, _hoisted_1$24);
16145
+ ])) : createCommentVNode("", true)], 14, _hoisted_1$23);
16032
16146
  }), 128))], 4)], 36);
16033
16147
  };
16034
16148
  }
16035
16149
  }, [["__scopeId", "data-v-15b59a51"]]);
16036
16150
  //#endregion
16037
16151
  //#region src/components/CommentsLayer/PdfCommentsLayer.vue
16038
- var _hoisted_1$23 = {
16152
+ var _hoisted_1$22 = {
16039
16153
  class: "superdoc__pdf-comments-layer pdf-comments-layer",
16040
16154
  "aria-hidden": "false"
16041
16155
  };
@@ -16141,7 +16255,7 @@ var PdfCommentsLayer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
16141
16255
  emit("anchor-activate", anchor.commentId);
16142
16256
  };
16143
16257
  return (_ctx, _cache) => {
16144
- return openBlock(), createElementBlock("div", _hoisted_1$23, [(openBlock(true), createElementBlock(Fragment, null, renderList(pdfCommentAnchors.value, (anchor) => {
16258
+ return openBlock(), createElementBlock("div", _hoisted_1$22, [(openBlock(true), createElementBlock(Fragment, null, renderList(pdfCommentAnchors.value, (anchor) => {
16145
16259
  return openBlock(), createElementBlock("div", {
16146
16260
  key: anchor.commentId,
16147
16261
  class: "sd-comment-anchor sd-highlight",
@@ -16310,7 +16424,7 @@ var useWhiteboard = ({ proxy, layers, documents, modules }) => {
16310
16424
  };
16311
16425
  //#endregion
16312
16426
  //#region src/components/Whiteboard/WhiteboardPage.vue
16313
- var _hoisted_1$22 = ["data-page-index"];
16427
+ var _hoisted_1$21 = ["data-page-index"];
16314
16428
  var WhiteboardPage_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
16315
16429
  __name: "WhiteboardPage",
16316
16430
  props: {
@@ -16442,7 +16556,7 @@ var WhiteboardPage_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
16442
16556
  height: (__props.pageSize?.height ?? __props.page.size?.height) + "px",
16443
16557
  transform: `translate(${__props.pageOffset?.left ?? 0}px, ${__props.pageOffset?.top ?? 0}px)`
16444
16558
  })
16445
- }, null, 44, _hoisted_1$22);
16559
+ }, null, 44, _hoisted_1$21);
16446
16560
  };
16447
16561
  }
16448
16562
  }, [["__scopeId", "data-v-c876c9b5"]]);
@@ -16517,7 +16631,7 @@ var WhiteboardLayer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
16517
16631
  }, [["__scopeId", "data-v-54546c3d"]]);
16518
16632
  //#endregion
16519
16633
  //#region src/components/HtmlViewer/HtmlViewer.vue
16520
- var _hoisted_1$21 = { class: "superdoc-html-viewer" };
16634
+ var _hoisted_1$20 = { class: "superdoc-html-viewer" };
16521
16635
  var _hoisted_2$17 = { class: "superdoc-html-viewer__document" };
16522
16636
  var _hoisted_3$14 = ["innerHTML"];
16523
16637
  var HtmlViewer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
@@ -16567,7 +16681,7 @@ var HtmlViewer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
16567
16681
  initViewer();
16568
16682
  });
16569
16683
  return (_ctx, _cache) => {
16570
- return openBlock(), createElementBlock("div", _hoisted_1$21, [createElementVNode("div", _hoisted_2$17, [createElementVNode("div", {
16684
+ return openBlock(), createElementBlock("div", _hoisted_1$20, [createElementVNode("div", _hoisted_2$17, [createElementVNode("div", {
16571
16685
  class: "superdoc-html-viewer__content",
16572
16686
  innerHTML: documentContent.value,
16573
16687
  onMouseup: handleSelectionChange
@@ -18607,35 +18721,6 @@ function shouldHandleFindShortcut(event, { focusInside, owner }) {
18607
18721
  return (!active || active === document.body || active === document.documentElement) && ownsAmbientFindShortcut(owner);
18608
18722
  }
18609
18723
  //#endregion
18610
- //#region src/internal/toolbar/built-in/url-safety.js
18611
- /**
18612
- * Minimal href sanitizer for the built-in link popover.
18613
- *
18614
- * The v1 toolbar used the shared `@superdoc/url-validation` package, which is not
18615
- * a resolvable runtime dependency of the published `superdoc` ES build. This
18616
- * keeps the same fail-closed posture (only known-safe schemes pass) without
18617
- * pulling in that package: dangerous schemes (`javascript:`, `data:`,
18618
- * `vbscript:`) return `null`, mirroring the v1 contract that callers treat a
18619
- * `null` result as an invalid URL.
18620
- */
18621
- var SAFE_SCHEME = /^(https?|mailto|tel):/i;
18622
- var DANGEROUS_SCHEME = /^(javascript|data|vbscript):/i;
18623
- var HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
18624
- /**
18625
- * Validate and normalize an href. Returns `{ href }` for safe values, or `null`.
18626
- * @param {string} value
18627
- * @returns {{ href: string }|null}
18628
- */
18629
- function sanitizeHref(value) {
18630
- if (typeof value !== "string") return null;
18631
- const trimmed = value.trim();
18632
- if (!trimmed) return null;
18633
- if (trimmed.startsWith("#")) return { href: trimmed };
18634
- if (DANGEROUS_SCHEME.test(trimmed)) return null;
18635
- if (HAS_SCHEME.test(trimmed)) return SAFE_SCHEME.test(trimmed) ? { href: trimmed } : null;
18636
- return { href: trimmed };
18637
- }
18638
- //#endregion
18639
18724
  //#region ../../shared/common/icons/bold-solid.svg?raw
18640
18725
  var bold_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M0 64C0 46.3 14.3 32 32 32l48 0 16 0 128 0c70.7 0 128 57.3 128 128c0 31.3-11.3 60.1-30 82.3c37.1 22.4 62 63.1 62 109.7c0 70.7-57.3 128-128 128L96 480l-16 0-48 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l16 0 0-160L48 96 32 96C14.3 96 0 81.7 0 64zM224 224c35.3 0 64-28.7 64-64s-28.7-64-64-64L112 96l0 128 112 0zM112 288l0 128 144 0c35.3 0 64-28.7 64-64s-28.7-64-64-64l-32 0-112 0z\"/></svg>";
18641
18726
  //#endregion
@@ -18858,7 +18943,7 @@ var toolbarIcons = {
18858
18943
  };
18859
18944
  //#endregion
18860
18945
  //#region src/internal/toolbar/built-in/LinkInput.vue
18861
- var _hoisted_1$20 = {
18946
+ var _hoisted_1$19 = {
18862
18947
  key: 0,
18863
18948
  class: "link-title"
18864
18949
  };
@@ -19101,7 +19186,7 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
19101
19186
  if (props.goToAnchor) props.goToAnchor(anchorUrl);
19102
19187
  };
19103
19188
  return (_ctx, _cache) => {
19104
- return openBlock(), createElementBlock("div", { class: normalizeClass(["link-input-ctn", { "high-contrast": unref(isHighContrastMode) }]) }, [isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$20, "Page anchor")) : isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_2$16, "Link details")) : isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_3$13, "Edit link")) : (openBlock(), createElementBlock("div", _hoisted_4$8, "Add link")), __props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_5$6, [
19189
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["link-input-ctn", { "high-contrast": unref(isHighContrastMode) }]) }, [isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$19, "Page anchor")) : isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_2$16, "Link details")) : isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_3$13, "Edit link")) : (openBlock(), createElementBlock("div", _hoisted_4$8, "Add link")), __props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_5$6, [
19105
19190
  createElementVNode("div", _hoisted_6$5, [_cache[5] || (_cache[5] = createElementVNode("div", { class: "input-icon text-input-icon" }, "T", -1)), withDirectives(createElementVNode("input", {
19106
19191
  type: "text",
19107
19192
  name: "text",
@@ -20745,6 +20830,9 @@ function createV2EditorRuntimeAdapter(options) {
20745
20830
  setTrackedChangesRenderOptions(options) {
20746
20831
  host.setTrackedChangesRenderOptions(options);
20747
20832
  },
20833
+ setShowFormattingMarks(show) {
20834
+ host.setShowFormattingMarks(show);
20835
+ },
20748
20836
  getLegacyEditorProjection: () => getLegacyEditorProjection?.() ?? DEFAULT_V2_LEGACY_PROJECTION,
20749
20837
  focus,
20750
20838
  dispose,
@@ -21471,7 +21559,7 @@ var FOCUSABLE_SELECTOR = [
21471
21559
  ].join(", ");
21472
21560
  //#endregion
21473
21561
  //#region src/components/surfaces/SurfaceDialog.vue
21474
- var _hoisted_1$19 = ["aria-labelledby", "aria-label"];
21562
+ var _hoisted_1$18 = ["aria-labelledby", "aria-label"];
21475
21563
  var _hoisted_2$15 = ["id"];
21476
21564
  var _hoisted_3$12 = { class: "sd-surface-dialog__content" };
21477
21565
  var SurfaceDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
@@ -21619,13 +21707,13 @@ var SurfaceDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
21619
21707
  "render",
21620
21708
  "resolve",
21621
21709
  "close"
21622
- ])) : __props.surface.component ? (openBlock(), createBlock(resolveDynamicComponent(__props.surface.component), normalizeProps(mergeProps({ key: 1 }, mergedComponentProps.value)), null, 16)) : createCommentVNode("", true)])], 12, _hoisted_1$19)], 32);
21710
+ ])) : __props.surface.component ? (openBlock(), createBlock(resolveDynamicComponent(__props.surface.component), normalizeProps(mergeProps({ key: 1 }, mergedComponentProps.value)), null, 16)) : createCommentVNode("", true)])], 12, _hoisted_1$18)], 32);
21623
21711
  };
21624
21712
  }
21625
21713
  }, [["__scopeId", "data-v-582b6534"]]);
21626
21714
  //#endregion
21627
21715
  //#region src/components/surfaces/SurfaceFloating.vue
21628
- var _hoisted_1$18 = ["aria-labelledby", "aria-label"];
21716
+ var _hoisted_1$17 = ["aria-labelledby", "aria-label"];
21629
21717
  var _hoisted_2$14 = ["id"];
21630
21718
  var _hoisted_3$11 = { class: "sd-surface-floating__content" };
21631
21719
  var SurfaceFloating_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
@@ -21773,7 +21861,7 @@ var SurfaceFloating_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
21773
21861
  "render",
21774
21862
  "resolve",
21775
21863
  "close"
21776
- ])) : __props.surface.component ? (openBlock(), createBlock(resolveDynamicComponent(__props.surface.component), normalizeProps(mergeProps({ key: 1 }, mergedComponentProps.value)), null, 16)) : createCommentVNode("", true)])], 14, _hoisted_1$18);
21864
+ ])) : __props.surface.component ? (openBlock(), createBlock(resolveDynamicComponent(__props.surface.component), normalizeProps(mergeProps({ key: 1 }, mergedComponentProps.value)), null, 16)) : createCommentVNode("", true)])], 14, _hoisted_1$17);
21777
21865
  };
21778
21866
  }
21779
21867
  }, [["__scopeId", "data-v-cd2be5db"]]);
@@ -22001,7 +22089,7 @@ var SurfaceHost_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22001
22089
  }, [["__scopeId", "data-v-dad99b67"]]);
22002
22090
  //#endregion
22003
22091
  //#region src/SuperDoc.vue
22004
- var _hoisted_1$17 = ["innerHTML"];
22092
+ var _hoisted_1$16 = ["innerHTML"];
22005
22093
  var _hoisted_2$13 = { class: "superdoc__document document" };
22006
22094
  var _hoisted_3$10 = { class: "floating-comments" };
22007
22095
  var TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT = "superdoc:v2-tracked-change-carriers-restamped";
@@ -24449,7 +24537,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
24449
24537
  }, [createElementVNode("div", {
24450
24538
  class: "superdoc__tools-icon",
24451
24539
  innerHTML: unref(superdocIcons).comment
24452
- }, null, 8, _hoisted_1$17)], 32)], 4)) : createCommentVNode("", true), createElementVNode("div", _hoisted_2$13, [
24540
+ }, null, 8, _hoisted_1$16)], 32)], 4)) : createCommentVNode("", true), createElementVNode("div", _hoisted_2$13, [
24453
24541
  isCommentsEnabled.value ? (openBlock(), createElementBlock("div", {
24454
24542
  key: 0,
24455
24543
  class: "superdoc__selection-layer selection-layer",
@@ -39145,7 +39233,7 @@ var throttle = (func, wait, options) => {
39145
39233
  };
39146
39234
  //#endregion
39147
39235
  //#region src/internal/toolbar/built-in/ToolbarButtonIcon.vue
39148
- var _hoisted_1$16 = { class: "sd-toolbar-icon" };
39236
+ var _hoisted_1$15 = { class: "sd-toolbar-icon" };
39149
39237
  var _hoisted_2$12 = ["innerHTML"];
39150
39238
  var ToolbarButtonIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
39151
39239
  __name: "ToolbarButtonIcon",
@@ -39173,7 +39261,7 @@ var ToolbarButtonIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(
39173
39261
  return ["color", "highlight"].includes(props.name);
39174
39262
  });
39175
39263
  return (_ctx, _cache) => {
39176
- return openBlock(), createElementBlock("div", _hoisted_1$16, [createElementVNode("div", {
39264
+ return openBlock(), createElementBlock("div", _hoisted_1$15, [createElementVNode("div", {
39177
39265
  class: normalizeClass(["sd-toolbar-icon__icon", [`sd-toolbar-icon__icon--${props.name}`]]),
39178
39266
  innerHTML: __props.icon
39179
39267
  }, null, 10, _hoisted_2$12), hasColorBar.value ? (openBlock(), createElementBlock("div", {
@@ -39186,7 +39274,7 @@ var ToolbarButtonIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(
39186
39274
  }, [["__scopeId", "data-v-65ecd5b1"]]);
39187
39275
  //#endregion
39188
39276
  //#region src/internal/toolbar/built-in/ToolbarButton.vue
39189
- var _hoisted_1$15 = [
39277
+ var _hoisted_1$14 = [
39190
39278
  "role",
39191
39279
  "aria-label",
39192
39280
  "aria-disabled"
@@ -39480,13 +39568,13 @@ var ToolbarButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
39480
39568
  }, null, 12, _hoisted_10$1)) : createCommentVNode("", true)
39481
39569
  ], 64)),
39482
39570
  createElementVNode("div", _hoisted_11$1, toDisplayString(`${unref(attributes).ariaLabel} ${unref(active) ? "selected" : "unset"}`), 1)
39483
- ], 10, _hoisted_2$11)], 46, _hoisted_1$15);
39571
+ ], 10, _hoisted_2$11)], 46, _hoisted_1$14);
39484
39572
  };
39485
39573
  }
39486
39574
  }, [["__scopeId", "data-v-96796456"]]);
39487
39575
  //#endregion
39488
39576
  //#region src/internal/toolbar/built-in/ToolbarSeparator.vue
39489
- var _hoisted_1$14 = {
39577
+ var _hoisted_1$13 = {
39490
39578
  class: "toolbar-separator",
39491
39579
  role: "separator",
39492
39580
  "aria-label": "Toolbar separator"
@@ -39505,7 +39593,7 @@ var ToolbarSeparator_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
39505
39593
  return "var(--sd-ui-border, #dbdbdb)";
39506
39594
  };
39507
39595
  return (_ctx, _cache) => {
39508
- return openBlock(), createElementBlock("div", _hoisted_1$14, [createElementVNode("div", {
39596
+ return openBlock(), createElementBlock("div", _hoisted_1$13, [createElementVNode("div", {
39509
39597
  class: "separator-inner",
39510
39598
  style: normalizeStyle({ backgroundColor: getSeparatorColor() })
39511
39599
  }, null, 4)]);
@@ -39514,7 +39602,7 @@ var ToolbarSeparator_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
39514
39602
  }, [["__scopeId", "data-v-cb82253a"]]);
39515
39603
  //#endregion
39516
39604
  //#region src/internal/toolbar/built-in/ToolbarDropdown.vue
39517
- var _hoisted_1$13 = { class: "toolbar-dropdown" };
39605
+ var _hoisted_1$12 = { class: "toolbar-dropdown" };
39518
39606
  var _hoisted_2$10 = ["onClick"];
39519
39607
  var _hoisted_3$8 = {
39520
39608
  key: 0,
@@ -39869,7 +39957,7 @@ var ToolbarDropdown_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
39869
39957
  window.removeEventListener("scroll", updateMenuPosition, true);
39870
39958
  });
39871
39959
  return (_ctx, _cache) => {
39872
- return openBlock(), createElementBlock("div", _hoisted_1$13, [createElementVNode("div", {
39960
+ return openBlock(), createElementBlock("div", _hoisted_1$12, [createElementVNode("div", {
39873
39961
  ref_key: "triggerRef",
39874
39962
  ref: triggerRef,
39875
39963
  class: "toolbar-dropdown-trigger",
@@ -40132,7 +40220,7 @@ var normalizeCustomFontSize = (value) => {
40132
40220
  };
40133
40221
  //#endregion
40134
40222
  //#region src/internal/toolbar/built-in/ToolbarComboBox.vue
40135
- var _hoisted_1$12 = ["data-item"];
40223
+ var _hoisted_1$11 = ["data-item"];
40136
40224
  var _hoisted_2$9 = [
40137
40225
  "id",
40138
40226
  "value",
@@ -40643,7 +40731,7 @@ var ToolbarComboBox_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
40643
40731
  }), [createElementVNode("span", _hoisted_7$1, toDisplayString(option.label), 1)], 16, _hoisted_6$3);
40644
40732
  }), 128))], 14, _hoisted_5$4)) : createCommentVNode("", true)])),
40645
40733
  createElementVNode("span", _hoisted_8$1, toDisplayString(appliedLabel.value), 1)
40646
- ], 14, _hoisted_1$12);
40734
+ ], 14, _hoisted_1$11);
40647
40735
  };
40648
40736
  }
40649
40737
  }, [["__scopeId", "data-v-e288ef9f"]]);
@@ -40731,7 +40819,6 @@ var _sfc_main$13 = {
40731
40819
  };
40732
40820
  //#endregion
40733
40821
  //#region src/internal/toolbar/built-in/SdTooltip.vue
40734
- var _hoisted_1$11 = ["data-placement"];
40735
40822
  var AUTO_HIDE_DELAY = 2500;
40736
40823
  var SdTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
40737
40824
  __name: "SdTooltip",
@@ -40765,20 +40852,25 @@ var SdTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
40765
40852
  const contentRef = ref(null);
40766
40853
  const position = ref({
40767
40854
  top: "0px",
40768
- left: "0px"
40855
+ left: "0px",
40856
+ below: false
40769
40857
  });
40770
- const placement = ref("top");
40771
40858
  let closeTimeout = null;
40772
40859
  let openTimeout = null;
40773
40860
  let autoHideTimeout = null;
40774
- const mergedContentClass = computed$1(() => ["sd-tooltip-content", attrs.class]);
40861
+ const mergedContentClass = computed$1(() => [
40862
+ "sd-tooltip-content",
40863
+ position.value.below && "sd-tooltip-below",
40864
+ attrs.class
40865
+ ]);
40775
40866
  const contentStyle = computed$1(() => ({
40776
40867
  ...props.contentStyle,
40777
40868
  ...attrs.style || {},
40778
40869
  position: "fixed",
40779
40870
  top: position.value.top,
40780
40871
  left: position.value.left,
40781
- zIndex: 2100
40872
+ zIndex: 2100,
40873
+ transformOrigin: position.value.below ? "top center" : "bottom center"
40782
40874
  }));
40783
40875
  const clearCloseTimeout = () => {
40784
40876
  if (closeTimeout) {
@@ -40805,49 +40897,24 @@ var SdTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
40805
40897
  close();
40806
40898
  }, AUTO_HIDE_DELAY);
40807
40899
  };
40808
- const getElementSize = (element, dimension) => {
40809
- const styles = window.getComputedStyle(element);
40810
- const size = parseFloat(styles[dimension]);
40811
- if (!Number.isFinite(size)) return dimension === "width" ? element.offsetWidth : element.offsetHeight;
40812
- if (styles.boxSizing === "border-box") return size;
40813
- return (dimension === "width" ? [
40814
- "paddingLeft",
40815
- "paddingRight",
40816
- "borderLeftWidth",
40817
- "borderRightWidth"
40818
- ] : [
40819
- "paddingTop",
40820
- "paddingBottom",
40821
- "borderTopWidth",
40822
- "borderBottomWidth"
40823
- ]).reduce((total, property) => total + (parseFloat(styles[property]) || 0), size);
40824
- };
40825
40900
  const updatePosition = () => {
40826
40901
  if (!triggerRef.value || !contentRef.value) return;
40827
40902
  const triggerRect = triggerRef.value.getBoundingClientRect();
40828
- const contentWidth = getElementSize(contentRef.value, "width");
40829
- const contentHeight = getElementSize(contentRef.value, "height");
40903
+ const contentWidth = contentRef.value.offsetWidth;
40904
+ const contentHeight = contentRef.value.offsetHeight;
40830
40905
  const viewportWidth = window.innerWidth || document.documentElement.clientWidth || 0;
40831
- const viewportHeight = document.documentElement.clientHeight || window.innerHeight || 0;
40906
+ const viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0;
40832
40907
  const gutter = 8;
40833
- const offset = 10;
40834
40908
  let left = triggerRect.left + triggerRect.width / 2 - contentWidth / 2;
40835
40909
  left = Math.max(gutter, Math.min(left, viewportWidth - contentWidth - gutter));
40836
- const topAbove = triggerRect.top - contentHeight - offset;
40837
- const topBelow = triggerRect.bottom + offset;
40838
- const fitsAbove = topAbove >= gutter;
40839
- const fitsBelow = topBelow + contentHeight <= viewportHeight - gutter;
40840
- const availableAbove = triggerRect.top - offset;
40841
- const availableBelow = viewportHeight - triggerRect.bottom - offset;
40842
- if (fitsAbove) placement.value = "top";
40843
- else if (fitsBelow) placement.value = "bottom";
40844
- else placement.value = availableAbove >= availableBelow ? "top" : "bottom";
40845
- const desiredTop = placement.value === "top" ? topAbove : topBelow;
40846
- const minTop = Math.min(gutter, Math.max(0, viewportHeight - contentHeight));
40847
- const maxTop = Math.max(minTop, viewportHeight - contentHeight - gutter);
40910
+ const aboveTop = triggerRect.top - contentHeight - 10;
40911
+ const below = aboveTop < gutter;
40912
+ const preferredTop = below ? triggerRect.bottom + 10 : aboveTop;
40913
+ const top = Math.max(gutter, Math.min(preferredTop, viewportHeight - contentHeight - gutter));
40848
40914
  position.value = {
40849
- top: `${Math.max(minTop, Math.min(desiredTop, maxTop))}px`,
40850
- left: `${left}px`
40915
+ top: `${top}px`,
40916
+ left: `${left}px`,
40917
+ below
40851
40918
  };
40852
40919
  };
40853
40920
  const open = async () => {
@@ -40957,18 +41024,17 @@ var SdTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
40957
41024
  ref: contentRef,
40958
41025
  class: normalizeClass(mergedContentClass.value),
40959
41026
  style: normalizeStyle(contentStyle.value),
40960
- "data-placement": placement.value,
40961
41027
  onMouseenter: handleContentMouseEnter,
40962
41028
  onMouseleave: handleContentMouseLeave
40963
41029
  }, [_cache[0] || (_cache[0] = createElementVNode("span", {
40964
41030
  class: "sd-tooltip-arrow",
40965
41031
  "aria-hidden": "true"
40966
- }, null, -1)), renderSlot(_ctx.$slots, "default", {}, void 0, true)], 46, _hoisted_1$11)) : createCommentVNode("", true)]),
41032
+ }, null, -1)), renderSlot(_ctx.$slots, "default", {}, void 0, true)], 38)) : createCommentVNode("", true)]),
40967
41033
  _: 3
40968
41034
  }, 8, ["css"])]))], 64);
40969
41035
  };
40970
41036
  }
40971
- }), [["__scopeId", "data-v-44bd03f9"]]);
41037
+ }), [["__scopeId", "data-v-71c6de4c"]]);
40972
41038
  //#endregion
40973
41039
  //#region src/internal/toolbar/built-in/ButtonGroup.vue
40974
41040
  var _hoisted_1$10 = [
@@ -46398,7 +46464,7 @@ var SuperDoc = class extends import_eventemitter3.default {
46398
46464
  }
46399
46465
  this.userColorMap = /* @__PURE__ */ new Map();
46400
46466
  this.colorIndex = 0;
46401
- this.version = "2.23.1-next.1";
46467
+ this.version = "2.23.1-next.11";
46402
46468
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46403
46469
  this.superdocId = config.superdocId || v4();
46404
46470
  this.colors = this.config.colors ?? [];
@@ -47845,6 +47911,8 @@ var SuperDoc = class extends import_eventemitter3.default {
47845
47911
  */
47846
47912
  registerEditorRuntime(runtime) {
47847
47913
  this.#editorRuntimeRegistry.register(runtime);
47914
+ const show = this.config.layoutEngineOptions?.showFormattingMarks;
47915
+ if (typeof show === "boolean") runtime.setShowFormattingMarks(show);
47848
47916
  }
47849
47917
  /**
47850
47918
  * Unregister a mounted editor runtime by id. If it was active, active state
@@ -48089,7 +48157,7 @@ var SuperDoc = class extends import_eventemitter3.default {
48089
48157
  });
48090
48158
  }
48091
48159
  /**
48092
- * Toggle nonprinting formatting marks (spaces, tabs, paragraph marks) in the
48160
+ * Toggle nonprinting formatting marks (spaces, tabs, paragraph marks and manual line breaks) in the
48093
48161
  * rendered layout. This is a view-only setting and is not exported to DOCX.
48094
48162
  */
48095
48163
  setShowFormattingMarks(show = true) {
@@ -48098,6 +48166,11 @@ var SuperDoc = class extends import_eventemitter3.default {
48098
48166
  if (layoutOptions.showFormattingMarks === nextValue) return;
48099
48167
  layoutOptions.showFormattingMarks = nextValue;
48100
48168
  this.superdocStore?.documents?.forEach((doc) => {
48169
+ const runtimes = typeof doc.id === "string" ? this.#editorRuntimeRegistry.getAllByDocumentId(doc.id) : [];
48170
+ if (runtimes.length) {
48171
+ for (const runtime of runtimes) runtime.setShowFormattingMarks(nextValue);
48172
+ return;
48173
+ }
48101
48174
  (doc.getDocumentRuntime?.())?.setShowFormattingMarks?.(nextValue);
48102
48175
  });
48103
48176
  this.emit("formatting-marks-change", {