@harbour-enterprises/superdoc 1.3.0 → 1.3.1-next.2

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,7 +1,7 @@
1
1
  "use strict";
2
2
  const jszip = require("./jszip-C8_CqJxM.cjs");
3
3
  const helpers$1 = require("./helpers-nOdwpmwb.cjs");
4
- const superEditor_converter = require("./SuperConverter-BJ-tba6U.cjs");
4
+ const superEditor_converter = require("./SuperConverter-Cu6cvHlN.cjs");
5
5
  const vue = require("./vue-De9wkgLl.cjs");
6
6
  require("./jszip.min-BPh2MMAa.cjs");
7
7
  const eventemitter3 = require("./eventemitter3-BQuRcMPI.cjs");
@@ -15451,7 +15451,7 @@ const canUseDOM = () => {
15451
15451
  return false;
15452
15452
  }
15453
15453
  };
15454
- const summaryVersion = "1.3.0";
15454
+ const summaryVersion = "1.3.1-next.2";
15455
15455
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
15456
15456
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
15457
15457
  function mapAttributes(attrs) {
@@ -18083,7 +18083,7 @@ class Editor extends EventEmitter {
18083
18083
  * Process collaboration migrations
18084
18084
  */
18085
18085
  processCollaborationMigrations() {
18086
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0");
18086
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.1-next.2");
18087
18087
  if (!this.options.ydoc) return;
18088
18088
  const metaMap = this.options.ydoc.getMap("meta");
18089
18089
  let docVersion = metaMap.get("version");
@@ -24946,7 +24946,7 @@ function isMinimalWordLayout(value) {
24946
24946
  return true;
24947
24947
  }
24948
24948
  const LIST_MARKER_GAP$2 = 8;
24949
- const DEFAULT_TAB_INTERVAL_PX$2 = 48;
24949
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
24950
24950
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
24951
24951
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
24952
24952
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -25097,6 +25097,7 @@ class DomPainter {
25097
25097
  this.layoutVersion = 0;
25098
25098
  this.layoutEpoch = 0;
25099
25099
  this.processedLayoutVersion = -1;
25100
+ this.currentMapping = null;
25100
25101
  this.onScrollHandler = null;
25101
25102
  this.onWindowScrollHandler = null;
25102
25103
  this.onResizeHandler = null;
@@ -25202,7 +25203,7 @@ class DomPainter {
25202
25203
  this.blockLookup = nextLookup;
25203
25204
  this.changedBlocks = changed;
25204
25205
  }
25205
- paint(layout, mount2) {
25206
+ paint(layout, mount2, mapping) {
25206
25207
  if (!(mount2 instanceof HTMLElement)) {
25207
25208
  throw new Error("DomPainter.paint requires a valid HTMLElement mount");
25208
25209
  }
@@ -25211,6 +25212,13 @@ class DomPainter {
25211
25212
  throw new Error("DomPainter.paint requires a DOM-like document");
25212
25213
  }
25213
25214
  this.doc = doc2;
25215
+ const isSimpleTransaction = mapping && mapping.maps.length === 1;
25216
+ if (mapping && !isSimpleTransaction) {
25217
+ this.blockLookup.forEach((_, id) => this.changedBlocks.add(id));
25218
+ this.currentMapping = null;
25219
+ } else {
25220
+ this.currentMapping = mapping ?? null;
25221
+ }
25214
25222
  ensurePrintStyles(doc2);
25215
25223
  ensureLinkStyles(doc2);
25216
25224
  ensureTrackChangeStyles(doc2);
@@ -25237,6 +25245,7 @@ class DomPainter {
25237
25245
  this.currentLayout = layout;
25238
25246
  this.pageStates = [];
25239
25247
  this.changedBlocks.clear();
25248
+ this.currentMapping = null;
25240
25249
  return;
25241
25250
  }
25242
25251
  if (mode === "book") {
@@ -25245,6 +25254,7 @@ class DomPainter {
25245
25254
  this.currentLayout = layout;
25246
25255
  this.pageStates = [];
25247
25256
  this.changedBlocks.clear();
25257
+ this.currentMapping = null;
25248
25258
  return;
25249
25259
  }
25250
25260
  applyStyles$2(mount2, containerStyles);
@@ -25253,6 +25263,7 @@ class DomPainter {
25253
25263
  this.renderVirtualized(layout, mount2);
25254
25264
  this.currentLayout = layout;
25255
25265
  this.changedBlocks.clear();
25266
+ this.currentMapping = null;
25256
25267
  return;
25257
25268
  }
25258
25269
  mount2.style.gap = `${this.pageGap}px`;
@@ -25263,6 +25274,7 @@ class DomPainter {
25263
25274
  }
25264
25275
  this.currentLayout = layout;
25265
25276
  this.changedBlocks.clear();
25277
+ this.currentMapping = null;
25266
25278
  }
25267
25279
  // ----------------
25268
25280
  // Virtualized path
@@ -25794,6 +25806,8 @@ class DomPainter {
25794
25806
  pageEl.replaceChild(replacement, current.element);
25795
25807
  current.element = replacement;
25796
25808
  current.signature = fragmentSignature(fragment, this.blockLookup);
25809
+ } else if (this.currentMapping) {
25810
+ this.updatePositionAttributes(current.element, this.currentMapping);
25797
25811
  }
25798
25812
  this.updateFragmentElement(current.element, fragment, contextBase.section);
25799
25813
  current.fragment = fragment;
@@ -25822,6 +25836,45 @@ class DomPainter {
25822
25836
  state.fragments = nextFragments;
25823
25837
  this.renderDecorationsForPage(pageEl, page);
25824
25838
  }
25839
+ /**
25840
+ * Updates data-pm-start/data-pm-end attributes on all elements within a fragment
25841
+ * using the transaction's mapping. Skips header/footer content (separate PM coordinate space).
25842
+ * Also skips fragments that end before the edit point (their positions don't change).
25843
+ */
25844
+ updatePositionAttributes(fragmentEl, mapping) {
25845
+ if (fragmentEl.closest(".superdoc-page-header, .superdoc-page-footer")) {
25846
+ return;
25847
+ }
25848
+ try {
25849
+ const fragEnd = fragmentEl.dataset.pmEnd;
25850
+ if (fragEnd !== void 0 && fragEnd !== "") {
25851
+ const endNum = Number(fragEnd);
25852
+ if (Number.isFinite(endNum) && mapping.map(endNum, -1) === endNum) {
25853
+ return;
25854
+ }
25855
+ }
25856
+ const elements = fragmentEl.querySelectorAll("[data-pm-start], [data-pm-end]");
25857
+ const allElements = [fragmentEl, ...Array.from(elements)];
25858
+ for (const el of allElements) {
25859
+ const oldStart = el.dataset.pmStart;
25860
+ const oldEnd = el.dataset.pmEnd;
25861
+ if (oldStart !== void 0 && oldStart !== "") {
25862
+ const num = Number(oldStart);
25863
+ if (Number.isFinite(num)) {
25864
+ el.dataset.pmStart = String(mapping.map(num));
25865
+ }
25866
+ }
25867
+ if (oldEnd !== void 0 && oldEnd !== "") {
25868
+ const num = Number(oldEnd);
25869
+ if (Number.isFinite(num)) {
25870
+ el.dataset.pmEnd = String(mapping.map(num, -1));
25871
+ }
25872
+ }
25873
+ }
25874
+ } catch (error) {
25875
+ console.error("Error updating position attributes with mapping:", error);
25876
+ }
25877
+ }
25825
25878
  createPageState(page, pageSize) {
25826
25879
  if (!this.doc) {
25827
25880
  throw new Error("DomPainter.createPageState requires a document");
@@ -25980,7 +26033,7 @@ class DomPainter {
25980
26033
  const textStart = paraIndentLeft + firstLine;
25981
26034
  tabWidth = textStart - currentPos;
25982
26035
  if (tabWidth <= 0) {
25983
- tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
26036
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
25984
26037
  } else if (tabWidth < LIST_MARKER_GAP$2) {
25985
26038
  tabWidth = LIST_MARKER_GAP$2;
25986
26039
  }
@@ -26132,7 +26185,7 @@ class DomPainter {
26132
26185
  const textStart = paraIndentLeft + firstLine;
26133
26186
  tabWidth = textStart - currentPos;
26134
26187
  if (tabWidth <= 0) {
26135
- tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
26188
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
26136
26189
  } else if (tabWidth < LIST_MARKER_GAP$2) {
26137
26190
  tabWidth = LIST_MARKER_GAP$2;
26138
26191
  }
@@ -27480,6 +27533,13 @@ class DomPainter {
27480
27533
  const trackedConfig = this.resolveTrackedChangesConfig(block);
27481
27534
  if (runsForLine.length === 0) {
27482
27535
  const span = this.doc.createElement("span");
27536
+ span.classList.add("superdoc-empty-run");
27537
+ if (lineRange.pmStart != null) {
27538
+ span.dataset.pmStart = String(lineRange.pmStart);
27539
+ }
27540
+ if (lineRange.pmEnd != null) {
27541
+ span.dataset.pmEnd = String(lineRange.pmEnd);
27542
+ }
27483
27543
  span.innerHTML = "&nbsp;";
27484
27544
  el.appendChild(span);
27485
27545
  }
@@ -28192,8 +28252,6 @@ const fragmentSignature = (fragment, lookup) => {
28192
28252
  base2,
28193
28253
  fragment.fromLine,
28194
28254
  fragment.toLine,
28195
- fragment.pmStart ?? "",
28196
- fragment.pmEnd ?? "",
28197
28255
  fragment.continuesFromPrev ? 1 : 0,
28198
28256
  fragment.continuesOnNext ? 1 : 0,
28199
28257
  fragment.markerWidth ?? ""
@@ -28285,16 +28343,15 @@ const deriveBlockVersion = (block) => {
28285
28343
  imgRun.distTop ?? "",
28286
28344
  imgRun.distBottom ?? "",
28287
28345
  imgRun.distLeft ?? "",
28288
- imgRun.distRight ?? "",
28289
- imgRun.pmStart ?? "",
28290
- imgRun.pmEnd ?? ""
28346
+ imgRun.distRight ?? ""
28347
+ // Note: pmStart/pmEnd intentionally excluded to prevent O(n) change detection
28291
28348
  ].join(",");
28292
28349
  }
28293
28350
  if (run.kind === "lineBreak") {
28294
- return ["linebreak", run.pmStart ?? "", run.pmEnd ?? ""].join(",");
28351
+ return "linebreak";
28295
28352
  }
28296
28353
  if (run.kind === "tab") {
28297
- return [run.text ?? "", "tab", run.pmStart ?? "", run.pmEnd ?? ""].join(",");
28354
+ return [run.text ?? "", "tab"].join(",");
28298
28355
  }
28299
28356
  const textRun = run;
28300
28357
  return [
@@ -28310,8 +28367,7 @@ const deriveBlockVersion = (block) => {
28310
28367
  textRun.strike ? 1 : 0,
28311
28368
  textRun.highlight ?? "",
28312
28369
  textRun.letterSpacing != null ? textRun.letterSpacing : "",
28313
- textRun.pmStart ?? "",
28314
- textRun.pmEnd ?? "",
28370
+ // Note: pmStart/pmEnd intentionally excluded to prevent O(n) change detection
28315
28371
  textRun.token ?? "",
28316
28372
  // Tracked changes - force re-render when added or removed tracked change
28317
28373
  textRun.trackedChange ? 1 : 0,
@@ -28770,8 +28826,8 @@ const createDomPainter = (options) => {
28770
28826
  ruler: options.ruler
28771
28827
  });
28772
28828
  return {
28773
- paint(layout, mount2) {
28774
- painter.paint(layout, mount2);
28829
+ paint(layout, mount2, mapping) {
28830
+ painter.paint(layout, mount2, mapping);
28775
28831
  },
28776
28832
  setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures) {
28777
28833
  painter.setData(blocks, measures, headerBlocks, headerMeasures, footerBlocks, footerMeasures);
@@ -30726,7 +30782,6 @@ const DEFAULT_LIST_INDENT_BASE_PX = 24;
30726
30782
  const DEFAULT_LIST_INDENT_STEP_PX = 24;
30727
30783
  const DEFAULT_LIST_HANGING_PX$1 = 18;
30728
30784
  const SPACE_SUFFIX_GAP_PX = 4;
30729
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
30730
30785
  function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
30731
30786
  const marker = wordLayout?.marker;
30732
30787
  if (!marker) {
@@ -30760,9 +30815,13 @@ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, meas
30760
30815
  return markerStartPos + finalMarkerTextWidth;
30761
30816
  }
30762
30817
  const markerJustification = marker.justification ?? "left";
30818
+ const markerWidthEffective = Math.max(
30819
+ typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0,
30820
+ finalMarkerTextWidth
30821
+ );
30763
30822
  if (markerJustification !== "left") {
30764
- const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
30765
- return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
30823
+ const gutterWidth2 = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
30824
+ return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth2, LIST_MARKER_GAP$1);
30766
30825
  }
30767
30826
  if (wordLayout?.firstLineIndentMode === true) {
30768
30827
  let targetTabStop;
@@ -30774,12 +30833,12 @@ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, meas
30774
30833
  }
30775
30834
  }
30776
30835
  }
30777
- const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
30836
+ const textStartTarget2 = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
30778
30837
  let tabWidth2;
30779
30838
  if (targetTabStop !== void 0) {
30780
30839
  tabWidth2 = targetTabStop - currentPos;
30781
- } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
30782
- tabWidth2 = textStartTarget - currentPos;
30840
+ } else if (textStartTarget2 !== void 0 && Number.isFinite(textStartTarget2) && textStartTarget2 > currentPos) {
30841
+ tabWidth2 = textStartTarget2 - currentPos;
30783
30842
  } else {
30784
30843
  tabWidth2 = LIST_MARKER_GAP$1;
30785
30844
  }
@@ -30788,14 +30847,21 @@ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, meas
30788
30847
  }
30789
30848
  return markerStartPos + finalMarkerTextWidth + tabWidth2;
30790
30849
  }
30850
+ const textStartTarget = typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
30851
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
30852
+ const currentPosStandard = markerStartPos + markerWidthEffective;
30853
+ if (textStartTarget !== void 0) {
30854
+ const gap = Math.max(textStartTarget - currentPosStandard, gutterWidth);
30855
+ return currentPosStandard + gap;
30856
+ }
30791
30857
  const textStart = indentLeft + firstLine;
30792
- let tabWidth = textStart - currentPos;
30858
+ let tabWidth = textStart - currentPosStandard;
30793
30859
  if (tabWidth <= 0) {
30794
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
30860
+ tabWidth = gutterWidth;
30795
30861
  } else if (tabWidth < LIST_MARKER_GAP$1) {
30796
- tabWidth = LIST_MARKER_GAP$1;
30862
+ tabWidth = Math.max(tabWidth, gutterWidth);
30797
30863
  }
30798
- return markerStartPos + finalMarkerTextWidth + tabWidth;
30864
+ return currentPosStandard + tabWidth;
30799
30865
  }
30800
30866
  function getWordLayoutConfig(block) {
30801
30867
  if (!block || block.kind !== "paragraph") {
@@ -30824,21 +30890,45 @@ function isListItem(markerWidth, block) {
30824
30890
  return hasHangingIndentPattern;
30825
30891
  }
30826
30892
  function calculateTextStartIndent(params2) {
30827
- const { isFirstLine, isListItem: isListItem2, markerWidth, paraIndentLeft, firstLineIndent, hangingIndent, wordLayout } = params2;
30893
+ const {
30894
+ isFirstLine,
30895
+ isListItem: isListItem2,
30896
+ markerWidth,
30897
+ markerTextWidth,
30898
+ paraIndentLeft,
30899
+ firstLineIndent,
30900
+ hangingIndent,
30901
+ wordLayout
30902
+ } = params2;
30828
30903
  const firstLineOffset = firstLineIndent - hangingIndent;
30829
- const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
30904
+ const effectiveMarkerTextWidth = typeof markerTextWidth === "number" && Number.isFinite(markerTextWidth) && markerTextWidth > 0 ? markerTextWidth : markerWidth;
30830
30905
  let indentAdjust = paraIndentLeft;
30831
- if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
30906
+ if (isListItem2 && isFirstLine) {
30832
30907
  const resolvedTextStart = resolveListTextStartPx(
30833
30908
  wordLayout,
30834
30909
  paraIndentLeft,
30835
30910
  Math.max(firstLineIndent, 0),
30836
30911
  Math.max(hangingIndent, 0),
30837
- () => markerWidth
30838
- // Use provided markerWidth since we don't have canvas access here
30912
+ () => effectiveMarkerTextWidth
30913
+ // Use measured marker text width when available
30839
30914
  );
30840
- const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
30841
- indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
30915
+ if (typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart)) {
30916
+ indentAdjust = resolvedTextStart;
30917
+ } else {
30918
+ const explicitTextStart = wordLayout?.marker?.textStartX ?? wordLayout?.textStartPx;
30919
+ const isStandardHangingList = hangingIndent > 0 && wordLayout?.firstLineIndentMode !== true;
30920
+ const textStartLooksValid = typeof explicitTextStart === "number" && Number.isFinite(explicitTextStart) && (!isStandardHangingList || explicitTextStart > paraIndentLeft);
30921
+ if (textStartLooksValid) {
30922
+ indentAdjust = explicitTextStart;
30923
+ } else if (wordLayout?.firstLineIndentMode === true) {
30924
+ indentAdjust = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
30925
+ } else if (isStandardHangingList && effectiveMarkerTextWidth > 0) {
30926
+ const markerStartPos = Math.max(0, paraIndentLeft - hangingIndent + firstLineIndent);
30927
+ const gutterWidthCandidate = wordLayout?.gutterWidthPx;
30928
+ const gutterWidth = typeof gutterWidthCandidate === "number" && Number.isFinite(gutterWidthCandidate) ? gutterWidthCandidate : wordLayout?.marker?.gutterWidthPx ?? LIST_MARKER_GAP$1;
30929
+ indentAdjust = markerStartPos + effectiveMarkerTextWidth + gutterWidth;
30930
+ }
30931
+ }
30842
30932
  } else if (isFirstLine && !isListItem2) {
30843
30933
  indentAdjust += firstLineOffset;
30844
30934
  }
@@ -31689,12 +31779,16 @@ function layoutParagraphBlock(ctx2, anchors) {
31689
31779
  const negativeRightIndent = indentRight < 0 ? indentRight : 0;
31690
31780
  const remeasureWidth = Math.max(1, columnWidth - indentLeft - indentRight);
31691
31781
  let didRemeasureForColumnWidth = false;
31782
+ let remeasuredMarkerInfo;
31692
31783
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
31693
31784
  const firstLineIndent = calculateFirstLineIndent(block, measure);
31694
31785
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
31695
31786
  const newLines = normalizeLines(newMeasure);
31696
31787
  lines = newLines;
31697
31788
  didRemeasureForColumnWidth = true;
31789
+ if (newMeasure.marker) {
31790
+ remeasuredMarkerInfo = newMeasure.marker;
31791
+ }
31698
31792
  }
31699
31793
  let fromLine = 0;
31700
31794
  const attrs = getParagraphAttrs(block);
@@ -31733,10 +31827,12 @@ function layoutParagraphBlock(ctx2, anchors) {
31733
31827
  width: fragmentWidth,
31734
31828
  ...computeFragmentPmRange(block, lines, 0, lines.length)
31735
31829
  };
31736
- if (measure.marker) {
31737
- fragment.markerWidth = measure.marker.markerWidth;
31738
- if (measure.marker.markerTextWidth != null) {
31739
- fragment.markerTextWidth = measure.marker.markerTextWidth;
31830
+ if (measure.marker || remeasuredMarkerInfo) {
31831
+ const effectiveMarkerInfo = remeasuredMarkerInfo ?? measure.marker;
31832
+ fragment.markerWidth = effectiveMarkerInfo?.markerWidth ?? measure.marker?.markerWidth ?? 0;
31833
+ const markerTextWidth = remeasuredMarkerInfo?.markerTextWidth ?? measure.marker?.markerTextWidth;
31834
+ if (markerTextWidth != null) {
31835
+ fragment.markerTextWidth = markerTextWidth;
31740
31836
  }
31741
31837
  }
31742
31838
  state.page.fragments.push(fragment);
@@ -31778,6 +31874,9 @@ function layoutParagraphBlock(ctx2, anchors) {
31778
31874
  const newLines = normalizeLines(newMeasure);
31779
31875
  lines = newLines;
31780
31876
  didRemeasureForFloats = true;
31877
+ if (newMeasure.marker) {
31878
+ remeasuredMarkerInfo = newMeasure.marker;
31879
+ }
31781
31880
  }
31782
31881
  }
31783
31882
  while (fromLine < lines.length) {
@@ -31849,13 +31948,16 @@ function layoutParagraphBlock(ctx2, anchors) {
31849
31948
  if (didRemeasureForColumnWidth) {
31850
31949
  fragment.lines = lines.slice(fromLine, slice2.toLine);
31851
31950
  }
31852
- if (measure.marker && fromLine === 0) {
31853
- fragment.markerWidth = measure.marker.markerWidth;
31854
- if (measure.marker.markerTextWidth != null) {
31855
- fragment.markerTextWidth = measure.marker.markerTextWidth;
31951
+ if ((measure.marker || remeasuredMarkerInfo) && fromLine === 0) {
31952
+ const effectiveMarkerInfo = remeasuredMarkerInfo ?? measure.marker;
31953
+ fragment.markerWidth = effectiveMarkerInfo?.markerWidth ?? measure.marker?.markerWidth ?? 0;
31954
+ const markerTextWidth = remeasuredMarkerInfo?.markerTextWidth ?? measure.marker?.markerTextWidth;
31955
+ if (markerTextWidth != null) {
31956
+ fragment.markerTextWidth = markerTextWidth;
31856
31957
  }
31857
- if (measure.kind === "paragraph" && measure.marker?.gutterWidth != null) {
31858
- fragment.markerGutter = measure.marker.gutterWidth;
31958
+ const gutterWidth = remeasuredMarkerInfo?.gutterWidth ?? measure.marker?.gutterWidth;
31959
+ if (gutterWidth != null) {
31960
+ fragment.markerGutter = gutterWidth;
31859
31961
  }
31860
31962
  }
31861
31963
  if (fromLine > 0) fragment.continuesFromPrev = true;
@@ -35296,16 +35398,19 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
35296
35398
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
35297
35399
  const markerTextStartX = wordLayout?.marker?.textStartX;
35298
35400
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
35401
+ let measuredMarkerTextWidth;
35299
35402
  const resolvedTextStartPx = resolveListTextStartPx(
35300
35403
  wordLayout,
35301
35404
  indentLeft,
35302
35405
  indentFirstLine,
35303
35406
  indentHanging,
35304
- (markerText, marker) => {
35407
+ (markerText, marker2) => {
35305
35408
  const context = getCtx();
35306
35409
  if (!context) return 0;
35307
- context.font = markerFontString(marker.run);
35308
- return context.measureText(markerText).width;
35410
+ context.font = markerFontString(marker2.run);
35411
+ const width = context.measureText(markerText).width;
35412
+ measuredMarkerTextWidth = width;
35413
+ return width;
35309
35414
  }
35310
35415
  );
35311
35416
  const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
@@ -35396,7 +35501,14 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
35396
35501
  }
35397
35502
  }
35398
35503
  const totalHeight = lines.reduce((s2, l) => s2 + l.lineHeight, 0);
35399
- return { kind: "paragraph", lines, totalHeight };
35504
+ const marker = wordLayout?.marker;
35505
+ const markerInfo = marker ? {
35506
+ markerWidth: marker.markerBoxWidthPx ?? indentHanging ?? 0,
35507
+ markerTextWidth: measuredMarkerTextWidth ?? 0,
35508
+ indentLeft,
35509
+ gutterWidth: marker.gutterWidthPx
35510
+ } : void 0;
35511
+ return { kind: "paragraph", lines, totalHeight, marker: markerInfo };
35400
35512
  }
35401
35513
  function hasComments(run) {
35402
35514
  return "comments" in run && Array.isArray(run.comments) && run.comments.length > 0;
@@ -37447,6 +37559,7 @@ function selectionToRects(layout, blocks, measures, from3, to, geometryHelper) {
37447
37559
  isFirstLine,
37448
37560
  isListItem: isListItemFlag,
37449
37561
  markerWidth,
37562
+ markerTextWidth: fragment.markerTextWidth ?? measure.marker?.markerTextWidth ?? void 0,
37450
37563
  paraIndentLeft: indent.left,
37451
37564
  firstLineIndent: indent.firstLine,
37452
37565
  hangingIndent: indent.hanging,
@@ -37584,6 +37697,7 @@ function selectionToRects(layout, blocks, measures, from3, to, geometryHelper) {
37584
37697
  isFirstLine,
37585
37698
  isListItem: cellIsListItem,
37586
37699
  markerWidth: paragraphMarkerWidth,
37700
+ markerTextWidth: info.measure?.marker?.markerTextWidth ?? void 0,
37587
37701
  paraIndentLeft: cellIndent.left,
37588
37702
  firstLineIndent: cellIndent.firstLine,
37589
37703
  hangingIndent: cellIndent.hanging,
@@ -37835,25 +37949,36 @@ const mapPointToPm = (block, line, x, isRTL, availableWidthOverride, alignmentOv
37835
37949
  const range = computeLinePmRange(block, line);
37836
37950
  if (range.pmStart == null || range.pmEnd == null) return null;
37837
37951
  const result = findCharacterAtX(block, line, x, range.pmStart, availableWidthOverride, alignmentOverride);
37952
+ let pmPosition = result.pmPosition;
37838
37953
  if (isRTL) {
37839
37954
  const charOffset = result.charOffset;
37840
37955
  const charsInLine = Math.max(1, line.toChar - line.fromChar);
37841
37956
  const reversedOffset = Math.max(0, Math.min(charsInLine, charsInLine - charOffset));
37842
- return charOffsetToPm(block, line, reversedOffset, range.pmStart);
37957
+ pmPosition = charOffsetToPm(block, line, reversedOffset, range.pmStart);
37843
37958
  }
37844
- return result.pmPosition;
37959
+ return pmPosition;
37845
37960
  };
37846
37961
  const mapPmToX = (block, line, offset2, fragmentWidth, alignmentOverride) => {
37847
37962
  if (fragmentWidth <= 0 || line.width <= 0) return 0;
37848
37963
  let paraIndentLeft = 0;
37849
37964
  let paraIndentRight = 0;
37965
+ let effectiveLeft = 0;
37850
37966
  if (block.kind === "paragraph") {
37851
37967
  const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
37852
37968
  const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
37853
37969
  paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
37854
37970
  paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
37971
+ effectiveLeft = paraIndentLeft;
37972
+ const wl = getWordLayoutConfig(block);
37973
+ const isListParagraph = Boolean(block.attrs?.numberingProperties) || Boolean(wl?.marker);
37974
+ if (isListParagraph) {
37975
+ const explicitTextStart = typeof wl?.marker?.textStartX === "number" && Number.isFinite(wl.marker.textStartX) ? wl.marker.textStartX : typeof wl?.textStartPx === "number" && Number.isFinite(wl.textStartPx) ? wl.textStartPx : void 0;
37976
+ if (typeof explicitTextStart === "number" && explicitTextStart > paraIndentLeft) {
37977
+ effectiveLeft = explicitTextStart;
37978
+ }
37979
+ }
37855
37980
  }
37856
- const totalIndent = paraIndentLeft + paraIndentRight;
37981
+ const totalIndent = effectiveLeft + paraIndentRight;
37857
37982
  const availableWidth = Math.max(0, fragmentWidth - totalIndent);
37858
37983
  if (totalIndent > fragmentWidth) {
37859
37984
  console.warn(
@@ -39191,16 +39316,26 @@ function lineHeightBeforeIndex(lines, fromLine, targetIndex) {
39191
39316
  }
39192
39317
  function computeCaretLayoutRectGeometry({ layout, blocks, measures, painterHost, viewportHost, visibleHost, zoom }, pos, includeDomFallback = true) {
39193
39318
  if (!layout) return null;
39194
- const hit = getFragmentAtPosition(layout, blocks, measures, pos);
39319
+ let effectivePos = pos;
39320
+ let hit = getFragmentAtPosition(layout, blocks, measures, pos);
39195
39321
  if (!hit) {
39196
- return null;
39322
+ const fallbackCandidates = [pos - 1, pos + 1, pos - 2, pos + 2].filter((candidate) => candidate >= 0);
39323
+ for (const candidate of fallbackCandidates) {
39324
+ const fallbackHit = getFragmentAtPosition(layout, blocks, measures, candidate);
39325
+ if (fallbackHit) {
39326
+ hit = fallbackHit;
39327
+ effectivePos = candidate;
39328
+ break;
39329
+ }
39330
+ }
39331
+ if (!hit) return null;
39197
39332
  }
39198
39333
  const block = hit.block;
39199
39334
  const measure = hit.measure;
39200
39335
  if (hit.fragment.kind === "table" && block?.kind === "table" && measure?.kind === "table") {
39201
39336
  return computeTableCaretLayoutRectFromDom(
39202
39337
  { viewportHost, visibleHost, zoom },
39203
- pos,
39338
+ effectivePos,
39204
39339
  hit.fragment,
39205
39340
  block,
39206
39341
  measure,
@@ -39208,92 +39343,32 @@ function computeCaretLayoutRectGeometry({ layout, blocks, measures, painterHost,
39208
39343
  );
39209
39344
  }
39210
39345
  if (!block || block.kind !== "paragraph" || measure?.kind !== "paragraph") return null;
39211
- if (hit.fragment.kind !== "para") {
39212
- return null;
39213
- }
39346
+ if (hit.fragment.kind !== "para") return null;
39214
39347
  const fragment = hit.fragment;
39215
- const lineInfo = findLineContainingPos(block, measure, fragment.fromLine, fragment.toLine, pos);
39216
- if (!lineInfo) {
39217
- return null;
39218
- }
39348
+ const lineInfo = findLineContainingPos(block, measure, fragment.fromLine, fragment.toLine, effectivePos);
39349
+ if (!lineInfo) return null;
39219
39350
  const { line, index: index2 } = lineInfo;
39220
39351
  const range = computeLinePmRange(block, line);
39221
39352
  if (range.pmStart == null || range.pmEnd == null) return null;
39222
- const pmOffset = pmPosToCharOffset(block, line, pos);
39353
+ const pmOffset = pmPosToCharOffset(block, line, effectivePos);
39223
39354
  const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
39224
- const indent = extractParagraphIndent(block.attrs?.indent);
39225
- const availableWidth = Math.max(0, fragment.width - (indent.left + indent.right));
39226
- const charX = measureCharacterX(block, line, pmOffset, availableWidth);
39355
+ const markerTextWidth = fragment.markerTextWidth ?? measure.marker?.markerTextWidth ?? void 0;
39227
39356
  const isFirstLine = index2 === fragment.fromLine;
39228
39357
  const isListItemFlag = isListItem(markerWidth, block);
39229
- const isListFirstLine = isFirstLine && !fragment.continuesFromPrev && isListItemFlag;
39230
39358
  const wordLayout = getWordLayoutConfig(block);
39231
- const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
39232
- if (isListFirstLine && isFirstLineIndentMode) {
39233
- const textStartPx = calculateTextStartIndent({
39234
- isFirstLine,
39235
- isListItem: isListItemFlag,
39236
- markerWidth,
39237
- paraIndentLeft: indent.left,
39238
- firstLineIndent: indent.firstLine,
39239
- hangingIndent: indent.hanging,
39240
- wordLayout
39241
- });
39242
- const localX2 = fragment.x + textStartPx + charX;
39243
- const lineOffset2 = lineHeightBeforeIndex(measure.lines, fragment.fromLine, index2);
39244
- const localY2 = fragment.y + lineOffset2;
39245
- const result2 = {
39246
- pageIndex: hit.pageIndex,
39247
- x: localX2,
39248
- y: localY2,
39249
- height: line.lineHeight
39250
- };
39251
- const pageEl2 = painterHost?.querySelector(
39252
- `.superdoc-page[data-page-index="${hit.pageIndex}"]`
39253
- );
39254
- const pageRect2 = pageEl2?.getBoundingClientRect();
39255
- let domCaretX2 = null;
39256
- let domCaretY2 = null;
39257
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]");
39258
- for (const spanEl of Array.from(spanEls2 ?? [])) {
39259
- const pmStart = Number(spanEl.dataset.pmStart);
39260
- const pmEnd = Number(spanEl.dataset.pmEnd);
39261
- if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
39262
- const textNode = spanEl.firstChild;
39263
- const charIndex = Math.min(pos - pmStart, textNode.length);
39264
- const rangeObj = document.createRange();
39265
- rangeObj.setStart(textNode, charIndex);
39266
- rangeObj.setEnd(textNode, charIndex);
39267
- if (typeof rangeObj.getBoundingClientRect !== "function") {
39268
- break;
39269
- }
39270
- const rangeRect = rangeObj.getBoundingClientRect();
39271
- if (pageRect2) {
39272
- domCaretX2 = (rangeRect.left - pageRect2.left) / zoom;
39273
- domCaretY2 = (rangeRect.top - pageRect2.top) / zoom;
39274
- }
39275
- break;
39276
- }
39277
- }
39278
- if (includeDomFallback && domCaretX2 != null && domCaretY2 != null) {
39279
- return {
39280
- pageIndex: hit.pageIndex,
39281
- x: domCaretX2,
39282
- y: domCaretY2,
39283
- height: line.lineHeight
39284
- };
39285
- }
39286
- return result2;
39287
- }
39359
+ const indent = extractParagraphIndent(block.attrs?.indent);
39288
39360
  const indentAdjust = calculateTextStartIndent({
39289
39361
  isFirstLine,
39290
39362
  isListItem: isListItemFlag,
39291
39363
  markerWidth,
39364
+ markerTextWidth,
39292
39365
  paraIndentLeft: indent.left,
39293
39366
  firstLineIndent: indent.firstLine,
39294
39367
  hangingIndent: indent.hanging,
39295
39368
  wordLayout
39296
39369
  });
39370
+ const availableWidth = Math.max(0, fragment.width - (indentAdjust + indent.right));
39371
+ const charX = measureCharacterX(block, line, pmOffset, availableWidth);
39297
39372
  const localX = fragment.x + indentAdjust + charX;
39298
39373
  const lineOffset = lineHeightBeforeIndex(measure.lines, fragment.fromLine, index2);
39299
39374
  const localY = fragment.y + lineOffset;
@@ -39311,9 +39386,9 @@ function computeCaretLayoutRectGeometry({ layout, blocks, measures, painterHost,
39311
39386
  for (const spanEl of Array.from(spanEls ?? [])) {
39312
39387
  const pmStart = Number(spanEl.dataset.pmStart);
39313
39388
  const pmEnd = Number(spanEl.dataset.pmEnd);
39314
- if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
39389
+ if (effectivePos >= pmStart && effectivePos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
39315
39390
  const textNode = spanEl.firstChild;
39316
- const charIndex = Math.min(pos - pmStart, textNode.length);
39391
+ const charIndex = Math.min(effectivePos - pmStart, textNode.length);
39317
39392
  const rangeObj = document.createRange();
39318
39393
  rangeObj.setStart(textNode, charIndex);
39319
39394
  rangeObj.setEnd(textNode, charIndex);
@@ -50212,6 +50287,7 @@ class PresentationEditor extends EventEmitter {
50212
50287
  #telemetryEmitter = null;
50213
50288
  #renderScheduled = false;
50214
50289
  #pendingDocChange = false;
50290
+ #pendingMapping = null;
50215
50291
  #isRerendering = false;
50216
50292
  #selectionSync = new SelectionSyncCoordinator();
50217
50293
  #remoteCursorUpdateScheduled = false;
@@ -51819,6 +51895,15 @@ class PresentationEditor extends EventEmitter {
51819
51895
  }
51820
51896
  if (trackedChangesChanged || transaction?.docChanged) {
51821
51897
  this.#pendingDocChange = true;
51898
+ if (transaction?.docChanged) {
51899
+ if (this.#pendingMapping !== null) {
51900
+ const combined = this.#pendingMapping.slice();
51901
+ combined.appendMapping(transaction.mapping);
51902
+ this.#pendingMapping = combined;
51903
+ } else {
51904
+ this.#pendingMapping = transaction.mapping;
51905
+ }
51906
+ }
51822
51907
  this.#selectionSync.onLayoutStart();
51823
51908
  this.#scheduleRerender();
51824
51909
  }
@@ -52537,7 +52622,12 @@ class PresentationEditor extends EventEmitter {
52537
52622
  }
52538
52623
  if (!handledByDepth) {
52539
52624
  try {
52540
- const tr = this.#editor.state.tr.setSelection(superEditor_converter.TextSelection.create(this.#editor.state.doc, hit.pos));
52625
+ const doc22 = this.#editor.state.doc;
52626
+ let nextSelection = superEditor_converter.TextSelection.create(doc22, hit.pos);
52627
+ if (!nextSelection.$from.parent.inlineContent) {
52628
+ nextSelection = superEditor_converter.Selection.near(doc22.resolve(hit.pos), 1);
52629
+ }
52630
+ const tr = this.#editor.state.tr.setSelection(nextSelection);
52541
52631
  this.#editor.view?.dispatch(tr);
52542
52632
  } catch {
52543
52633
  }
@@ -53406,7 +53496,9 @@ class PresentationEditor extends EventEmitter {
53406
53496
  footerMeasures.length > 0 ? footerMeasures : void 0
53407
53497
  );
53408
53498
  this.#domIndexObserverManager?.pause();
53409
- painter.paint(layout, this.#painterHost);
53499
+ const mapping = this.#pendingMapping;
53500
+ this.#pendingMapping = null;
53501
+ painter.paint(layout, this.#painterHost, mapping ?? void 0);
53410
53502
  this.#applyVertAlignToLayout();
53411
53503
  this.#rebuildDomPositionIndex();
53412
53504
  this.#domIndexObserverManager?.resume();
@@ -53527,6 +53619,7 @@ class PresentationEditor extends EventEmitter {
53527
53619
  if (!layout) {
53528
53620
  return;
53529
53621
  }
53622
+ const { from: from3, to } = selection;
53530
53623
  const docEpoch = this.#epochMapper.getCurrentEpoch();
53531
53624
  if (this.#layoutEpoch < docEpoch) {
53532
53625
  return;
@@ -53541,7 +53634,6 @@ class PresentationEditor extends EventEmitter {
53541
53634
  }
53542
53635
  return;
53543
53636
  }
53544
- const { from: from3, to } = selection;
53545
53637
  if (from3 === to) {
53546
53638
  const caretLayout = this.#computeCaretLayoutRect(from3);
53547
53639
  if (!caretLayout) {
@@ -58140,6 +58232,28 @@ const createMarkDefsFromStyleRunProps = (styleRunProps) => {
58140
58232
  }
58141
58233
  return markDefs;
58142
58234
  };
58235
+ const normalizeSelectionIntoRun = (tr, runType) => {
58236
+ const selection = tr.selection;
58237
+ if (!(selection instanceof superEditor_converter.TextSelection)) return;
58238
+ if (selection.from !== selection.to) return;
58239
+ const $pos = tr.doc.resolve(selection.from);
58240
+ if ($pos.parent.type === runType) return;
58241
+ const nodeAfter = $pos.nodeAfter;
58242
+ if (nodeAfter?.type === runType && nodeAfter.content.size > 0) {
58243
+ const nextPos = selection.from + 1;
58244
+ if (nextPos <= tr.doc.content.size) {
58245
+ tr.setSelection(superEditor_converter.TextSelection.create(tr.doc, nextPos));
58246
+ }
58247
+ return;
58248
+ }
58249
+ const nodeBefore = $pos.nodeBefore;
58250
+ if (nodeBefore?.type === runType && nodeBefore.content.size > 0) {
58251
+ const prevPos = selection.from - 1;
58252
+ if (prevPos >= 0) {
58253
+ tr.setSelection(superEditor_converter.TextSelection.create(tr.doc, prevPos));
58254
+ }
58255
+ }
58256
+ };
58143
58257
  const buildWrapTransaction = (state, ranges, runType, editor, markDefsFromMeta = []) => {
58144
58258
  if (!ranges.length) return null;
58145
58259
  const replacements = [];
@@ -58173,6 +58287,7 @@ const buildWrapTransaction = (state, ranges, runType, editor, markDefsFromMeta =
58173
58287
  if (!replacements.length) return null;
58174
58288
  const tr = state.tr;
58175
58289
  replacements.sort((a, b) => b.from - a.from).forEach(({ from: from3, to, runNode }) => tr.replaceWith(from3, to, runNode));
58290
+ normalizeSelectionIntoRun(tr, runType);
58176
58291
  return tr.docChanged ? tr : null;
58177
58292
  };
58178
58293
  const wrapTextInRunsPlugin = (editor) => {
@@ -73080,6 +73195,7 @@ const useToolbarItem = (options) => {
73080
73195
  const parentItem = vue.ref(null);
73081
73196
  const iconColor = vue.ref(options.iconColor);
73082
73197
  const hasCaret = vue.ref(options.hasCaret);
73198
+ const restoreEditorFocus = Boolean(options.restoreEditorFocus);
73083
73199
  const dropdownStyles = vue.ref(options.dropdownStyles);
73084
73200
  const tooltip = vue.ref(options.tooltip);
73085
73201
  const tooltipVisible = vue.ref(options.tooltipVisible);
@@ -73155,6 +73271,7 @@ const useToolbarItem = (options) => {
73155
73271
  hideLabel,
73156
73272
  inlineTextInputVisible,
73157
73273
  hasInlineTextInput,
73274
+ restoreEditorFocus,
73158
73275
  markName,
73159
73276
  labelAttr,
73160
73277
  childItem,
@@ -75468,6 +75585,7 @@ const makeDefaultItems = ({
75468
75585
  command: "toggleBulletList",
75469
75586
  icon: toolbarIcons2.bulletList,
75470
75587
  tooltip: toolbarTexts2.bulletList,
75588
+ restoreEditorFocus: true,
75471
75589
  attributes: {
75472
75590
  ariaLabel: "Bullet list"
75473
75591
  }
@@ -75478,6 +75596,7 @@ const makeDefaultItems = ({
75478
75596
  command: "toggleOrderedList",
75479
75597
  icon: toolbarIcons2.numberedList,
75480
75598
  tooltip: toolbarTexts2.numberedList,
75599
+ restoreEditorFocus: true,
75481
75600
  attributes: {
75482
75601
  ariaLabel: "Numbered list"
75483
75602
  }
@@ -86348,6 +86467,7 @@ class SuperToolbar extends eventemitter3.EventEmitter {
86348
86467
  selectionUpdate: null,
86349
86468
  focus: null
86350
86469
  };
86470
+ this._restoreFocusTimeoutId = null;
86351
86471
  if (!this.config.selector && this.config.element) {
86352
86472
  this.config.selector = this.config.element;
86353
86473
  }
@@ -87013,6 +87133,7 @@ class SuperToolbar extends eventemitter3.EventEmitter {
87013
87133
  const wasFocused = Boolean(typeof hasFocusFn === "function" && hasFocusFn.call(this.activeEditor.view));
87014
87134
  const { command: command2 } = item;
87015
87135
  const isMarkToggle = this.isMarkToggle(item);
87136
+ const shouldRestoreFocus = Boolean(item?.restoreEditorFocus);
87016
87137
  if (!wasFocused && isMarkToggle) {
87017
87138
  this.pendingMarkCommands.push({ command: command2, argument, item });
87018
87139
  item?.activate?.();
@@ -87043,6 +87164,13 @@ class SuperToolbar extends eventemitter3.EventEmitter {
87043
87164
  }
87044
87165
  if (isMarkToggle) this.#syncStickyMarksFromState();
87045
87166
  this.updateToolbarState();
87167
+ if (shouldRestoreFocus && this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
87168
+ this._restoreFocusTimeoutId = setTimeout(() => {
87169
+ this._restoreFocusTimeoutId = null;
87170
+ if (!this.activeEditor || this.activeEditor.options.isHeaderOrFooter) return;
87171
+ this.activeEditor.focus();
87172
+ }, 0);
87173
+ }
87046
87174
  }
87047
87175
  /**
87048
87176
  * Processes and executes pending mark commands when editor selection updates.
@@ -87185,6 +87313,17 @@ class SuperToolbar extends eventemitter3.EventEmitter {
87185
87313
  const tr = state.tr.setStoredMarks([mark]);
87186
87314
  view.dispatch(tr);
87187
87315
  }
87316
+ /**
87317
+ * Cleans up resources when the toolbar is destroyed.
87318
+ * Clears any pending timeouts to prevent callbacks firing after unmount.
87319
+ * @returns {void}
87320
+ */
87321
+ destroy() {
87322
+ if (this._restoreFocusTimeoutId !== null) {
87323
+ clearTimeout(this._restoreFocusTimeoutId);
87324
+ this._restoreFocusTimeoutId = null;
87325
+ }
87326
+ }
87188
87327
  }
87189
87328
  const onMarginClickCursorChange = (event, editor) => {
87190
87329
  const y = event.clientY;