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

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.
@@ -36435,7 +36435,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36435
36435
  static getStoredSuperdocVersion(docx) {
36436
36436
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
36437
36437
  }
36438
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.3.0") {
36438
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.3.1-next.1") {
36439
36439
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
36440
36440
  }
36441
36441
  /**
@@ -62245,7 +62245,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62245
62245
  return false;
62246
62246
  }
62247
62247
  };
62248
- const summaryVersion = "1.3.0";
62248
+ const summaryVersion = "1.3.1-next.1";
62249
62249
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
62250
62250
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
62251
62251
  function mapAttributes(attrs) {
@@ -64878,7 +64878,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
64878
64878
  * Process collaboration migrations
64879
64879
  */
64880
64880
  processCollaborationMigrations() {
64881
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0");
64881
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.1-next.1");
64882
64882
  if (!this.options.ydoc) return;
64883
64883
  const metaMap = this.options.ydoc.getMap("meta");
64884
64884
  let docVersion = metaMap.get("version");
@@ -71743,7 +71743,7 @@ ${l}
71743
71743
  return true;
71744
71744
  }
71745
71745
  const LIST_MARKER_GAP$2 = 8;
71746
- const DEFAULT_TAB_INTERVAL_PX$2 = 48;
71746
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
71747
71747
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
71748
71748
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
71749
71749
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -72777,7 +72777,7 @@ ${l}
72777
72777
  const textStart = paraIndentLeft + firstLine;
72778
72778
  tabWidth = textStart - currentPos;
72779
72779
  if (tabWidth <= 0) {
72780
- tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
72780
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
72781
72781
  } else if (tabWidth < LIST_MARKER_GAP$2) {
72782
72782
  tabWidth = LIST_MARKER_GAP$2;
72783
72783
  }
@@ -72929,7 +72929,7 @@ ${l}
72929
72929
  const textStart = paraIndentLeft + firstLine;
72930
72930
  tabWidth = textStart - currentPos;
72931
72931
  if (tabWidth <= 0) {
72932
- tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
72932
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
72933
72933
  } else if (tabWidth < LIST_MARKER_GAP$2) {
72934
72934
  tabWidth = LIST_MARKER_GAP$2;
72935
72935
  }
@@ -74277,6 +74277,13 @@ ${l}
74277
74277
  const trackedConfig = this.resolveTrackedChangesConfig(block);
74278
74278
  if (runsForLine.length === 0) {
74279
74279
  const span = this.doc.createElement("span");
74280
+ span.classList.add("superdoc-empty-run");
74281
+ if (lineRange.pmStart != null) {
74282
+ span.dataset.pmStart = String(lineRange.pmStart);
74283
+ }
74284
+ if (lineRange.pmEnd != null) {
74285
+ span.dataset.pmEnd = String(lineRange.pmEnd);
74286
+ }
74280
74287
  span.innerHTML = "&nbsp;";
74281
74288
  el.appendChild(span);
74282
74289
  }
@@ -77521,7 +77528,6 @@ ${l}
77521
77528
  const DEFAULT_LIST_INDENT_STEP_PX = 24;
77522
77529
  const DEFAULT_LIST_HANGING_PX$1 = 18;
77523
77530
  const SPACE_SUFFIX_GAP_PX = 4;
77524
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
77525
77531
  function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
77526
77532
  const marker = wordLayout?.marker;
77527
77533
  if (!marker) {
@@ -77555,9 +77561,13 @@ ${l}
77555
77561
  return markerStartPos + finalMarkerTextWidth;
77556
77562
  }
77557
77563
  const markerJustification = marker.justification ?? "left";
77564
+ const markerWidthEffective = Math.max(
77565
+ typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0,
77566
+ finalMarkerTextWidth
77567
+ );
77558
77568
  if (markerJustification !== "left") {
77559
- const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
77560
- return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
77569
+ const gutterWidth2 = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
77570
+ return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth2, LIST_MARKER_GAP$1);
77561
77571
  }
77562
77572
  if (wordLayout?.firstLineIndentMode === true) {
77563
77573
  let targetTabStop;
@@ -77569,12 +77579,12 @@ ${l}
77569
77579
  }
77570
77580
  }
77571
77581
  }
77572
- const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
77582
+ const textStartTarget2 = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
77573
77583
  let tabWidth2;
77574
77584
  if (targetTabStop !== void 0) {
77575
77585
  tabWidth2 = targetTabStop - currentPos;
77576
- } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
77577
- tabWidth2 = textStartTarget - currentPos;
77586
+ } else if (textStartTarget2 !== void 0 && Number.isFinite(textStartTarget2) && textStartTarget2 > currentPos) {
77587
+ tabWidth2 = textStartTarget2 - currentPos;
77578
77588
  } else {
77579
77589
  tabWidth2 = LIST_MARKER_GAP$1;
77580
77590
  }
@@ -77583,14 +77593,21 @@ ${l}
77583
77593
  }
77584
77594
  return markerStartPos + finalMarkerTextWidth + tabWidth2;
77585
77595
  }
77596
+ const textStartTarget = typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
77597
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
77598
+ const currentPosStandard = markerStartPos + markerWidthEffective;
77599
+ if (textStartTarget !== void 0) {
77600
+ const gap = Math.max(textStartTarget - currentPosStandard, gutterWidth);
77601
+ return currentPosStandard + gap;
77602
+ }
77586
77603
  const textStart = indentLeft + firstLine;
77587
- let tabWidth = textStart - currentPos;
77604
+ let tabWidth = textStart - currentPosStandard;
77588
77605
  if (tabWidth <= 0) {
77589
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
77606
+ tabWidth = gutterWidth;
77590
77607
  } else if (tabWidth < LIST_MARKER_GAP$1) {
77591
- tabWidth = LIST_MARKER_GAP$1;
77608
+ tabWidth = Math.max(tabWidth, gutterWidth);
77592
77609
  }
77593
- return markerStartPos + finalMarkerTextWidth + tabWidth;
77610
+ return currentPosStandard + tabWidth;
77594
77611
  }
77595
77612
  function getWordLayoutConfig(block) {
77596
77613
  if (!block || block.kind !== "paragraph") {
@@ -77619,21 +77636,45 @@ ${l}
77619
77636
  return hasHangingIndentPattern;
77620
77637
  }
77621
77638
  function calculateTextStartIndent(params2) {
77622
- const { isFirstLine, isListItem: isListItem2, markerWidth, paraIndentLeft, firstLineIndent, hangingIndent, wordLayout } = params2;
77639
+ const {
77640
+ isFirstLine,
77641
+ isListItem: isListItem2,
77642
+ markerWidth,
77643
+ markerTextWidth,
77644
+ paraIndentLeft,
77645
+ firstLineIndent,
77646
+ hangingIndent,
77647
+ wordLayout
77648
+ } = params2;
77623
77649
  const firstLineOffset = firstLineIndent - hangingIndent;
77624
- const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
77650
+ const effectiveMarkerTextWidth = typeof markerTextWidth === "number" && Number.isFinite(markerTextWidth) && markerTextWidth > 0 ? markerTextWidth : markerWidth;
77625
77651
  let indentAdjust = paraIndentLeft;
77626
- if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
77652
+ if (isListItem2 && isFirstLine) {
77627
77653
  const resolvedTextStart = resolveListTextStartPx(
77628
77654
  wordLayout,
77629
77655
  paraIndentLeft,
77630
77656
  Math.max(firstLineIndent, 0),
77631
77657
  Math.max(hangingIndent, 0),
77632
- () => markerWidth
77633
- // Use provided markerWidth since we don't have canvas access here
77658
+ () => effectiveMarkerTextWidth
77659
+ // Use measured marker text width when available
77634
77660
  );
77635
- const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
77636
- indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
77661
+ if (typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart)) {
77662
+ indentAdjust = resolvedTextStart;
77663
+ } else {
77664
+ const explicitTextStart = wordLayout?.marker?.textStartX ?? wordLayout?.textStartPx;
77665
+ const isStandardHangingList = hangingIndent > 0 && wordLayout?.firstLineIndentMode !== true;
77666
+ const textStartLooksValid = typeof explicitTextStart === "number" && Number.isFinite(explicitTextStart) && (!isStandardHangingList || explicitTextStart > paraIndentLeft);
77667
+ if (textStartLooksValid) {
77668
+ indentAdjust = explicitTextStart;
77669
+ } else if (wordLayout?.firstLineIndentMode === true) {
77670
+ indentAdjust = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
77671
+ } else if (isStandardHangingList && effectiveMarkerTextWidth > 0) {
77672
+ const markerStartPos = Math.max(0, paraIndentLeft - hangingIndent + firstLineIndent);
77673
+ const gutterWidthCandidate = wordLayout?.gutterWidthPx;
77674
+ const gutterWidth = typeof gutterWidthCandidate === "number" && Number.isFinite(gutterWidthCandidate) ? gutterWidthCandidate : wordLayout?.marker?.gutterWidthPx ?? LIST_MARKER_GAP$1;
77675
+ indentAdjust = markerStartPos + effectiveMarkerTextWidth + gutterWidth;
77676
+ }
77677
+ }
77637
77678
  } else if (isFirstLine && !isListItem2) {
77638
77679
  indentAdjust += firstLineOffset;
77639
77680
  }
@@ -78484,12 +78525,16 @@ ${l}
78484
78525
  const negativeRightIndent = indentRight < 0 ? indentRight : 0;
78485
78526
  const remeasureWidth = Math.max(1, columnWidth - indentLeft - indentRight);
78486
78527
  let didRemeasureForColumnWidth = false;
78528
+ let remeasuredMarkerInfo;
78487
78529
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
78488
78530
  const firstLineIndent = calculateFirstLineIndent(block, measure);
78489
78531
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
78490
78532
  const newLines = normalizeLines(newMeasure);
78491
78533
  lines = newLines;
78492
78534
  didRemeasureForColumnWidth = true;
78535
+ if (newMeasure.marker) {
78536
+ remeasuredMarkerInfo = newMeasure.marker;
78537
+ }
78493
78538
  }
78494
78539
  let fromLine = 0;
78495
78540
  const attrs = getParagraphAttrs(block);
@@ -78528,10 +78573,12 @@ ${l}
78528
78573
  width: fragmentWidth,
78529
78574
  ...computeFragmentPmRange(block, lines, 0, lines.length)
78530
78575
  };
78531
- if (measure.marker) {
78532
- fragment.markerWidth = measure.marker.markerWidth;
78533
- if (measure.marker.markerTextWidth != null) {
78534
- fragment.markerTextWidth = measure.marker.markerTextWidth;
78576
+ if (measure.marker || remeasuredMarkerInfo) {
78577
+ const effectiveMarkerInfo = remeasuredMarkerInfo ?? measure.marker;
78578
+ fragment.markerWidth = effectiveMarkerInfo?.markerWidth ?? measure.marker?.markerWidth ?? 0;
78579
+ const markerTextWidth = remeasuredMarkerInfo?.markerTextWidth ?? measure.marker?.markerTextWidth;
78580
+ if (markerTextWidth != null) {
78581
+ fragment.markerTextWidth = markerTextWidth;
78535
78582
  }
78536
78583
  }
78537
78584
  state.page.fragments.push(fragment);
@@ -78573,6 +78620,9 @@ ${l}
78573
78620
  const newLines = normalizeLines(newMeasure);
78574
78621
  lines = newLines;
78575
78622
  didRemeasureForFloats = true;
78623
+ if (newMeasure.marker) {
78624
+ remeasuredMarkerInfo = newMeasure.marker;
78625
+ }
78576
78626
  }
78577
78627
  }
78578
78628
  while (fromLine < lines.length) {
@@ -78644,13 +78694,16 @@ ${l}
78644
78694
  if (didRemeasureForColumnWidth) {
78645
78695
  fragment.lines = lines.slice(fromLine, slice.toLine);
78646
78696
  }
78647
- if (measure.marker && fromLine === 0) {
78648
- fragment.markerWidth = measure.marker.markerWidth;
78649
- if (measure.marker.markerTextWidth != null) {
78650
- fragment.markerTextWidth = measure.marker.markerTextWidth;
78697
+ if ((measure.marker || remeasuredMarkerInfo) && fromLine === 0) {
78698
+ const effectiveMarkerInfo = remeasuredMarkerInfo ?? measure.marker;
78699
+ fragment.markerWidth = effectiveMarkerInfo?.markerWidth ?? measure.marker?.markerWidth ?? 0;
78700
+ const markerTextWidth = remeasuredMarkerInfo?.markerTextWidth ?? measure.marker?.markerTextWidth;
78701
+ if (markerTextWidth != null) {
78702
+ fragment.markerTextWidth = markerTextWidth;
78651
78703
  }
78652
- if (measure.kind === "paragraph" && measure.marker?.gutterWidth != null) {
78653
- fragment.markerGutter = measure.marker.gutterWidth;
78704
+ const gutterWidth = remeasuredMarkerInfo?.gutterWidth ?? measure.marker?.gutterWidth;
78705
+ if (gutterWidth != null) {
78706
+ fragment.markerGutter = gutterWidth;
78654
78707
  }
78655
78708
  }
78656
78709
  if (fromLine > 0) fragment.continuesFromPrev = true;
@@ -82093,16 +82146,19 @@ ${l}
82093
82146
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
82094
82147
  const markerTextStartX = wordLayout?.marker?.textStartX;
82095
82148
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
82149
+ let measuredMarkerTextWidth;
82096
82150
  const resolvedTextStartPx = resolveListTextStartPx(
82097
82151
  wordLayout,
82098
82152
  indentLeft,
82099
82153
  indentFirstLine,
82100
82154
  indentHanging,
82101
- (markerText, marker) => {
82155
+ (markerText, marker2) => {
82102
82156
  const context = getCtx();
82103
82157
  if (!context) return 0;
82104
- context.font = markerFontString(marker.run);
82105
- return context.measureText(markerText).width;
82158
+ context.font = markerFontString(marker2.run);
82159
+ const width = context.measureText(markerText).width;
82160
+ measuredMarkerTextWidth = width;
82161
+ return width;
82106
82162
  }
82107
82163
  );
82108
82164
  const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
@@ -82193,7 +82249,14 @@ ${l}
82193
82249
  }
82194
82250
  }
82195
82251
  const totalHeight = lines.reduce((s2, l) => s2 + l.lineHeight, 0);
82196
- return { kind: "paragraph", lines, totalHeight };
82252
+ const marker = wordLayout?.marker;
82253
+ const markerInfo = marker ? {
82254
+ markerWidth: marker.markerBoxWidthPx ?? indentHanging ?? 0,
82255
+ markerTextWidth: measuredMarkerTextWidth ?? 0,
82256
+ indentLeft,
82257
+ gutterWidth: marker.gutterWidthPx
82258
+ } : void 0;
82259
+ return { kind: "paragraph", lines, totalHeight, marker: markerInfo };
82197
82260
  }
82198
82261
  function hasComments(run2) {
82199
82262
  return "comments" in run2 && Array.isArray(run2.comments) && run2.comments.length > 0;
@@ -84245,6 +84308,7 @@ ${l}
84245
84308
  isFirstLine,
84246
84309
  isListItem: isListItemFlag,
84247
84310
  markerWidth,
84311
+ markerTextWidth: fragment.markerTextWidth ?? measure.marker?.markerTextWidth ?? void 0,
84248
84312
  paraIndentLeft: indent2.left,
84249
84313
  firstLineIndent: indent2.firstLine,
84250
84314
  hangingIndent: indent2.hanging,
@@ -84382,6 +84446,7 @@ ${l}
84382
84446
  isFirstLine,
84383
84447
  isListItem: cellIsListItem,
84384
84448
  markerWidth: paragraphMarkerWidth,
84449
+ markerTextWidth: info.measure?.marker?.markerTextWidth ?? void 0,
84385
84450
  paraIndentLeft: cellIndent.left,
84386
84451
  firstLineIndent: cellIndent.firstLine,
84387
84452
  hangingIndent: cellIndent.hanging,
@@ -84633,25 +84698,36 @@ ${l}
84633
84698
  const range2 = computeLinePmRange(block, line);
84634
84699
  if (range2.pmStart == null || range2.pmEnd == null) return null;
84635
84700
  const result = findCharacterAtX(block, line, x2, range2.pmStart, availableWidthOverride, alignmentOverride);
84701
+ let pmPosition = result.pmPosition;
84636
84702
  if (isRTL) {
84637
84703
  const charOffset = result.charOffset;
84638
84704
  const charsInLine = Math.max(1, line.toChar - line.fromChar);
84639
84705
  const reversedOffset = Math.max(0, Math.min(charsInLine, charsInLine - charOffset));
84640
- return charOffsetToPm(block, line, reversedOffset, range2.pmStart);
84706
+ pmPosition = charOffsetToPm(block, line, reversedOffset, range2.pmStart);
84641
84707
  }
84642
- return result.pmPosition;
84708
+ return pmPosition;
84643
84709
  };
84644
84710
  const mapPmToX = (block, line, offset2, fragmentWidth, alignmentOverride) => {
84645
84711
  if (fragmentWidth <= 0 || line.width <= 0) return 0;
84646
84712
  let paraIndentLeft = 0;
84647
84713
  let paraIndentRight = 0;
84714
+ let effectiveLeft = 0;
84648
84715
  if (block.kind === "paragraph") {
84649
84716
  const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
84650
84717
  const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
84651
84718
  paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
84652
84719
  paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
84720
+ effectiveLeft = paraIndentLeft;
84721
+ const wl = getWordLayoutConfig(block);
84722
+ const isListParagraph = Boolean(block.attrs?.numberingProperties) || Boolean(wl?.marker);
84723
+ if (isListParagraph) {
84724
+ 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;
84725
+ if (typeof explicitTextStart === "number" && explicitTextStart > paraIndentLeft) {
84726
+ effectiveLeft = explicitTextStart;
84727
+ }
84728
+ }
84653
84729
  }
84654
- const totalIndent = paraIndentLeft + paraIndentRight;
84730
+ const totalIndent = effectiveLeft + paraIndentRight;
84655
84731
  const availableWidth = Math.max(0, fragmentWidth - totalIndent);
84656
84732
  if (totalIndent > fragmentWidth) {
84657
84733
  console.warn(
@@ -85983,16 +86059,26 @@ ${l}
85983
86059
  }
85984
86060
  function computeCaretLayoutRectGeometry({ layout, blocks: blocks2, measures, painterHost, viewportHost, visibleHost, zoom }, pos, includeDomFallback = true) {
85985
86061
  if (!layout) return null;
85986
- const hit = getFragmentAtPosition(layout, blocks2, measures, pos);
86062
+ let effectivePos = pos;
86063
+ let hit = getFragmentAtPosition(layout, blocks2, measures, pos);
85987
86064
  if (!hit) {
85988
- return null;
86065
+ const fallbackCandidates = [pos - 1, pos + 1, pos - 2, pos + 2].filter((candidate) => candidate >= 0);
86066
+ for (const candidate of fallbackCandidates) {
86067
+ const fallbackHit = getFragmentAtPosition(layout, blocks2, measures, candidate);
86068
+ if (fallbackHit) {
86069
+ hit = fallbackHit;
86070
+ effectivePos = candidate;
86071
+ break;
86072
+ }
86073
+ }
86074
+ if (!hit) return null;
85989
86075
  }
85990
86076
  const block = hit.block;
85991
86077
  const measure = hit.measure;
85992
86078
  if (hit.fragment.kind === "table" && block?.kind === "table" && measure?.kind === "table") {
85993
86079
  return computeTableCaretLayoutRectFromDom(
85994
86080
  { viewportHost, visibleHost, zoom },
85995
- pos,
86081
+ effectivePos,
85996
86082
  hit.fragment,
85997
86083
  block,
85998
86084
  measure,
@@ -86000,92 +86086,32 @@ ${l}
86000
86086
  );
86001
86087
  }
86002
86088
  if (!block || block.kind !== "paragraph" || measure?.kind !== "paragraph") return null;
86003
- if (hit.fragment.kind !== "para") {
86004
- return null;
86005
- }
86089
+ if (hit.fragment.kind !== "para") return null;
86006
86090
  const fragment = hit.fragment;
86007
- const lineInfo = findLineContainingPos(block, measure, fragment.fromLine, fragment.toLine, pos);
86008
- if (!lineInfo) {
86009
- return null;
86010
- }
86091
+ const lineInfo = findLineContainingPos(block, measure, fragment.fromLine, fragment.toLine, effectivePos);
86092
+ if (!lineInfo) return null;
86011
86093
  const { line, index: index2 } = lineInfo;
86012
86094
  const range2 = computeLinePmRange(block, line);
86013
86095
  if (range2.pmStart == null || range2.pmEnd == null) return null;
86014
- const pmOffset = pmPosToCharOffset(block, line, pos);
86096
+ const pmOffset = pmPosToCharOffset(block, line, effectivePos);
86015
86097
  const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
86016
- const indent2 = extractParagraphIndent(block.attrs?.indent);
86017
- const availableWidth = Math.max(0, fragment.width - (indent2.left + indent2.right));
86018
- const charX = measureCharacterX(block, line, pmOffset, availableWidth);
86098
+ const markerTextWidth = fragment.markerTextWidth ?? measure.marker?.markerTextWidth ?? void 0;
86019
86099
  const isFirstLine = index2 === fragment.fromLine;
86020
86100
  const isListItemFlag = isListItem(markerWidth, block);
86021
- const isListFirstLine = isFirstLine && !fragment.continuesFromPrev && isListItemFlag;
86022
86101
  const wordLayout = getWordLayoutConfig(block);
86023
- const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
86024
- if (isListFirstLine && isFirstLineIndentMode) {
86025
- const textStartPx = calculateTextStartIndent({
86026
- isFirstLine,
86027
- isListItem: isListItemFlag,
86028
- markerWidth,
86029
- paraIndentLeft: indent2.left,
86030
- firstLineIndent: indent2.firstLine,
86031
- hangingIndent: indent2.hanging,
86032
- wordLayout
86033
- });
86034
- const localX2 = fragment.x + textStartPx + charX;
86035
- const lineOffset2 = lineHeightBeforeIndex(measure.lines, fragment.fromLine, index2);
86036
- const localY2 = fragment.y + lineOffset2;
86037
- const result2 = {
86038
- pageIndex: hit.pageIndex,
86039
- x: localX2,
86040
- y: localY2,
86041
- height: line.lineHeight
86042
- };
86043
- const pageEl2 = painterHost?.querySelector(
86044
- `.superdoc-page[data-page-index="${hit.pageIndex}"]`
86045
- );
86046
- const pageRect2 = pageEl2?.getBoundingClientRect();
86047
- let domCaretX2 = null;
86048
- let domCaretY2 = null;
86049
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]");
86050
- for (const spanEl of Array.from(spanEls2 ?? [])) {
86051
- const pmStart = Number(spanEl.dataset.pmStart);
86052
- const pmEnd = Number(spanEl.dataset.pmEnd);
86053
- if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
86054
- const textNode = spanEl.firstChild;
86055
- const charIndex = Math.min(pos - pmStart, textNode.length);
86056
- const rangeObj = document.createRange();
86057
- rangeObj.setStart(textNode, charIndex);
86058
- rangeObj.setEnd(textNode, charIndex);
86059
- if (typeof rangeObj.getBoundingClientRect !== "function") {
86060
- break;
86061
- }
86062
- const rangeRect = rangeObj.getBoundingClientRect();
86063
- if (pageRect2) {
86064
- domCaretX2 = (rangeRect.left - pageRect2.left) / zoom;
86065
- domCaretY2 = (rangeRect.top - pageRect2.top) / zoom;
86066
- }
86067
- break;
86068
- }
86069
- }
86070
- if (includeDomFallback && domCaretX2 != null && domCaretY2 != null) {
86071
- return {
86072
- pageIndex: hit.pageIndex,
86073
- x: domCaretX2,
86074
- y: domCaretY2,
86075
- height: line.lineHeight
86076
- };
86077
- }
86078
- return result2;
86079
- }
86102
+ const indent2 = extractParagraphIndent(block.attrs?.indent);
86080
86103
  const indentAdjust = calculateTextStartIndent({
86081
86104
  isFirstLine,
86082
86105
  isListItem: isListItemFlag,
86083
86106
  markerWidth,
86107
+ markerTextWidth,
86084
86108
  paraIndentLeft: indent2.left,
86085
86109
  firstLineIndent: indent2.firstLine,
86086
86110
  hangingIndent: indent2.hanging,
86087
86111
  wordLayout
86088
86112
  });
86113
+ const availableWidth = Math.max(0, fragment.width - (indentAdjust + indent2.right));
86114
+ const charX = measureCharacterX(block, line, pmOffset, availableWidth);
86089
86115
  const localX = fragment.x + indentAdjust + charX;
86090
86116
  const lineOffset = lineHeightBeforeIndex(measure.lines, fragment.fromLine, index2);
86091
86117
  const localY = fragment.y + lineOffset;
@@ -86103,9 +86129,9 @@ ${l}
86103
86129
  for (const spanEl of Array.from(spanEls ?? [])) {
86104
86130
  const pmStart = Number(spanEl.dataset.pmStart);
86105
86131
  const pmEnd = Number(spanEl.dataset.pmEnd);
86106
- if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
86132
+ if (effectivePos >= pmStart && effectivePos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
86107
86133
  const textNode = spanEl.firstChild;
86108
- const charIndex = Math.min(pos - pmStart, textNode.length);
86134
+ const charIndex = Math.min(effectivePos - pmStart, textNode.length);
86109
86135
  const rangeObj = document.createRange();
86110
86136
  rangeObj.setStart(textNode, charIndex);
86111
86137
  rangeObj.setEnd(textNode, charIndex);
@@ -99257,7 +99283,12 @@ ${l}
99257
99283
  }
99258
99284
  if (!handledByDepth) {
99259
99285
  try {
99260
- const tr = this.#editor.state.tr.setSelection(TextSelection$1.create(this.#editor.state.doc, hit.pos));
99286
+ const doc22 = this.#editor.state.doc;
99287
+ let nextSelection = TextSelection$1.create(doc22, hit.pos);
99288
+ if (!nextSelection.$from.parent.inlineContent) {
99289
+ nextSelection = Selection.near(doc22.resolve(hit.pos), 1);
99290
+ }
99291
+ const tr = this.#editor.state.tr.setSelection(nextSelection);
99261
99292
  this.#editor.view?.dispatch(tr);
99262
99293
  } catch {
99263
99294
  }
@@ -100235,6 +100266,7 @@ ${l}
100235
100266
  if (!layout) {
100236
100267
  return;
100237
100268
  }
100269
+ const { from: from2, to } = selection;
100238
100270
  const docEpoch = this.#epochMapper.getCurrentEpoch();
100239
100271
  if (this.#layoutEpoch < docEpoch) {
100240
100272
  return;
@@ -100249,7 +100281,6 @@ ${l}
100249
100281
  }
100250
100282
  return;
100251
100283
  }
100252
- const { from: from2, to } = selection;
100253
100284
  if (from2 === to) {
100254
100285
  const caretLayout = this.#computeCaretLayoutRect(from2);
100255
100286
  if (!caretLayout) {
@@ -104836,6 +104867,28 @@ ${l}
104836
104867
  }
104837
104868
  return markDefs;
104838
104869
  };
104870
+ const normalizeSelectionIntoRun = (tr, runType) => {
104871
+ const selection = tr.selection;
104872
+ if (!(selection instanceof TextSelection$1)) return;
104873
+ if (selection.from !== selection.to) return;
104874
+ const $pos = tr.doc.resolve(selection.from);
104875
+ if ($pos.parent.type === runType) return;
104876
+ const nodeAfter = $pos.nodeAfter;
104877
+ if (nodeAfter?.type === runType && nodeAfter.content.size > 0) {
104878
+ const nextPos = selection.from + 1;
104879
+ if (nextPos <= tr.doc.content.size) {
104880
+ tr.setSelection(TextSelection$1.create(tr.doc, nextPos));
104881
+ }
104882
+ return;
104883
+ }
104884
+ const nodeBefore = $pos.nodeBefore;
104885
+ if (nodeBefore?.type === runType && nodeBefore.content.size > 0) {
104886
+ const prevPos = selection.from - 1;
104887
+ if (prevPos >= 0) {
104888
+ tr.setSelection(TextSelection$1.create(tr.doc, prevPos));
104889
+ }
104890
+ }
104891
+ };
104839
104892
  const buildWrapTransaction = (state, ranges, runType, editor, markDefsFromMeta = []) => {
104840
104893
  if (!ranges.length) return null;
104841
104894
  const replacements = [];
@@ -104869,6 +104922,7 @@ ${l}
104869
104922
  if (!replacements.length) return null;
104870
104923
  const tr = state.tr;
104871
104924
  replacements.sort((a2, b2) => b2.from - a2.from).forEach(({ from: from2, to, runNode }) => tr.replaceWith(from2, to, runNode));
104925
+ normalizeSelectionIntoRun(tr, runType);
104872
104926
  return tr.docChanged ? tr : null;
104873
104927
  };
104874
104928
  const wrapTextInRunsPlugin = (editor) => {
@@ -119817,6 +119871,7 @@ ${l}
119817
119871
  const parentItem = ref(null);
119818
119872
  const iconColor = ref(options.iconColor);
119819
119873
  const hasCaret = ref(options.hasCaret);
119874
+ const restoreEditorFocus = Boolean(options.restoreEditorFocus);
119820
119875
  const dropdownStyles = ref(options.dropdownStyles);
119821
119876
  const tooltip = ref(options.tooltip);
119822
119877
  const tooltipVisible = ref(options.tooltipVisible);
@@ -119892,6 +119947,7 @@ ${l}
119892
119947
  hideLabel,
119893
119948
  inlineTextInputVisible,
119894
119949
  hasInlineTextInput,
119950
+ restoreEditorFocus,
119895
119951
  markName,
119896
119952
  labelAttr,
119897
119953
  childItem,
@@ -122205,6 +122261,7 @@ ${l}
122205
122261
  command: "toggleBulletList",
122206
122262
  icon: toolbarIcons2.bulletList,
122207
122263
  tooltip: toolbarTexts2.bulletList,
122264
+ restoreEditorFocus: true,
122208
122265
  attributes: {
122209
122266
  ariaLabel: "Bullet list"
122210
122267
  }
@@ -122215,6 +122272,7 @@ ${l}
122215
122272
  command: "toggleOrderedList",
122216
122273
  icon: toolbarIcons2.numberedList,
122217
122274
  tooltip: toolbarTexts2.numberedList,
122275
+ restoreEditorFocus: true,
122218
122276
  attributes: {
122219
122277
  ariaLabel: "Numbered list"
122220
122278
  }
@@ -135114,6 +135172,7 @@ ${style2}
135114
135172
  selectionUpdate: null,
135115
135173
  focus: null
135116
135174
  };
135175
+ this._restoreFocusTimeoutId = null;
135117
135176
  if (!this.config.selector && this.config.element) {
135118
135177
  this.config.selector = this.config.element;
135119
135178
  }
@@ -135779,6 +135838,7 @@ ${style2}
135779
135838
  const wasFocused = Boolean(typeof hasFocusFn === "function" && hasFocusFn.call(this.activeEditor.view));
135780
135839
  const { command: command2 } = item;
135781
135840
  const isMarkToggle = this.isMarkToggle(item);
135841
+ const shouldRestoreFocus = Boolean(item?.restoreEditorFocus);
135782
135842
  if (!wasFocused && isMarkToggle) {
135783
135843
  this.pendingMarkCommands.push({ command: command2, argument, item });
135784
135844
  item?.activate?.();
@@ -135809,6 +135869,13 @@ ${style2}
135809
135869
  }
135810
135870
  if (isMarkToggle) this.#syncStickyMarksFromState();
135811
135871
  this.updateToolbarState();
135872
+ if (shouldRestoreFocus && this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
135873
+ this._restoreFocusTimeoutId = setTimeout(() => {
135874
+ this._restoreFocusTimeoutId = null;
135875
+ if (!this.activeEditor || this.activeEditor.options.isHeaderOrFooter) return;
135876
+ this.activeEditor.focus();
135877
+ }, 0);
135878
+ }
135812
135879
  }
135813
135880
  /**
135814
135881
  * Processes and executes pending mark commands when editor selection updates.
@@ -135951,6 +136018,17 @@ ${style2}
135951
136018
  const tr = state.tr.setStoredMarks([mark2]);
135952
136019
  view.dispatch(tr);
135953
136020
  }
136021
+ /**
136022
+ * Cleans up resources when the toolbar is destroyed.
136023
+ * Clears any pending timeouts to prevent callbacks firing after unmount.
136024
+ * @returns {void}
136025
+ */
136026
+ destroy() {
136027
+ if (this._restoreFocusTimeoutId !== null) {
136028
+ clearTimeout(this._restoreFocusTimeoutId);
136029
+ this._restoreFocusTimeoutId = null;
136030
+ }
136031
+ }
135954
136032
  }
135955
136033
  async function createZip(blobs, fileNames) {
135956
136034
  const zip = new JSZip();
@@ -144479,7 +144557,7 @@ ${reason}`);
144479
144557
  this.config.colors = shuffleArray(this.config.colors);
144480
144558
  this.userColorMap = /* @__PURE__ */ new Map();
144481
144559
  this.colorIndex = 0;
144482
- this.version = "1.3.0";
144560
+ this.version = "1.3.1-next.1";
144483
144561
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
144484
144562
  this.superdocId = config2.superdocId || v4();
144485
144563
  this.colors = this.config.colors;