superdoc 1.0.0-beta.4 → 1.0.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/chunks/{PdfViewer-DUns3s8O.es.js → PdfViewer-CdGAVn-4.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-ZtwLhE_8.cjs → PdfViewer-DmPiOFJ8.cjs} +1 -1
  3. package/dist/chunks/{index-BW38mdZF.cjs → index-QulG3CF7.cjs} +3 -3
  4. package/dist/chunks/{index-BNGaD3Up-D2cRHMMk.cjs → index-hjUbJ86s-BLl65XJn.cjs} +1 -1
  5. package/dist/chunks/{index-BNGaD3Up-CQuoo1EF.es.js → index-hjUbJ86s-BMiwCR8J.es.js} +1 -1
  6. package/dist/chunks/{index-DIccWgYh.es.js → index-nXifzD54.es.js} +3 -3
  7. package/dist/chunks/{super-editor.es-C06-V-Iy.cjs → super-editor.es-0GatZWs9.cjs} +452 -183
  8. package/dist/chunks/{super-editor.es-CtCHBIPE.es.js → super-editor.es-BYVEYLjl.es.js} +452 -183
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-ZJiSHoiq.js → converter-CZF9SnYh.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-B7FStorN.js → docx-zipper-DWypbE0V.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-DvepAjbe.js → editor-BdXHlHt-.js} +440 -176
  13. package/dist/super-editor/chunks/{index-BNGaD3Up.js → index-hjUbJ86s.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-CKXXbIQO.js → toolbar-CmelvLTd.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/super-editor.es.js +19 -14
  20. package/dist/super-editor/toolbar.es.js +2 -2
  21. package/dist/super-editor.cjs +1 -1
  22. package/dist/super-editor.es.js +1 -1
  23. package/dist/superdoc.cjs +2 -2
  24. package/dist/superdoc.es.js +2 -2
  25. package/dist/superdoc.umd.js +454 -185
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -35563,7 +35563,7 @@ const _SuperConverter = class _SuperConverter2 {
35563
35563
  static getStoredSuperdocVersion(docx) {
35564
35564
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
35565
35565
  }
35566
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.4") {
35566
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.6") {
35567
35567
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
35568
35568
  }
35569
35569
  /**
@@ -52270,7 +52270,7 @@ const isHeadless = (editor) => {
52270
52270
  const shouldSkipNodeView = (editor) => {
52271
52271
  return isHeadless(editor);
52272
52272
  };
52273
- const summaryVersion = "1.0.0-beta.4";
52273
+ const summaryVersion = "1.0.0-beta.6";
52274
52274
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
52275
52275
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
52276
52276
  function mapAttributes(attrs) {
@@ -53049,7 +53049,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53049
53049
  { default: remarkStringify },
53050
53050
  { default: remarkGfm }
53051
53051
  ] = await Promise.all([
53052
- import("./index-BNGaD3Up-CQuoo1EF.es.js"),
53052
+ import("./index-hjUbJ86s-BMiwCR8J.es.js"),
53053
53053
  import("./index-DRCvimau-Cw339678.es.js"),
53054
53054
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
53055
53055
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -53254,7 +53254,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53254
53254
  * Process collaboration migrations
53255
53255
  */
53256
53256
  processCollaborationMigrations() {
53257
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.4");
53257
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.6");
53258
53258
  if (!this.options.ydoc) return;
53259
53259
  const metaMap = this.options.ydoc.getMap("meta");
53260
53260
  let docVersion = metaMap.get("version");
@@ -55386,9 +55386,10 @@ function extractTableBorders(bordersInput) {
55386
55386
  }
55387
55387
  function extractCellBorders(cellAttrs) {
55388
55388
  if (!cellAttrs?.borders) return void 0;
55389
+ const bordersData = cellAttrs.borders;
55389
55390
  const borders = {};
55390
55391
  for (const side of ["top", "right", "bottom", "left"]) {
55391
- const spec = convertBorderSpec(cellAttrs.borders[side]);
55392
+ const spec = convertBorderSpec(bordersData[side]);
55392
55393
  if (spec) {
55393
55394
  borders[side] = spec;
55394
55395
  }
@@ -55492,7 +55493,7 @@ const normalizeString = (value) => {
55492
55493
  return trimmed ? trimmed : void 0;
55493
55494
  };
55494
55495
  const MAX_AUTO_LINE_MULTIPLIER = 10;
55495
- const TWIPS_THRESHOLD = 50;
55496
+ const TWIPS_THRESHOLD$1 = 50;
55496
55497
  const spacingPxToPt = (spacing) => {
55497
55498
  const result = {};
55498
55499
  if (spacing.before != null) result.before = pxToPt(spacing.before);
@@ -55632,7 +55633,7 @@ const normalizeParagraphIndent = (value) => {
55632
55633
  const convert = (value2) => {
55633
55634
  const num = pickNumber(value2);
55634
55635
  if (num == null) return void 0;
55635
- if (Math.abs(num) <= TWIPS_THRESHOLD) {
55636
+ if (Math.abs(num) <= TWIPS_THRESHOLD$1) {
55636
55637
  return num;
55637
55638
  }
55638
55639
  return twipsToPx$1(Number(num));
@@ -55647,24 +55648,18 @@ const normalizeParagraphIndent = (value) => {
55647
55648
  if (hanging != null) indent.hanging = hanging;
55648
55649
  return Object.keys(indent).length > 0 ? indent : void 0;
55649
55650
  };
55651
+ const PX_TO_TWIPS = 15;
55652
+ const TWIPS_THRESHOLD = 1e3;
55650
55653
  const normalizeOoxmlTabs = (tabs) => {
55651
55654
  if (!Array.isArray(tabs)) return void 0;
55652
55655
  const normalized = [];
55653
55656
  for (const entry of tabs) {
55654
55657
  if (!entry || typeof entry !== "object") continue;
55655
- const source = entry;
55656
- let posTwips;
55657
- const originalPos = pickNumber(source.originalPos);
55658
- if (originalPos != null) {
55659
- posTwips = originalPos;
55660
- } else {
55661
- const posPx = pickNumber(source.pos ?? source.position ?? source.offset);
55662
- if (posPx != null) {
55663
- posTwips = Math.round(posPx * 15);
55664
- }
55665
- }
55658
+ const rawEntry = entry;
55659
+ const source = rawEntry.tab && typeof rawEntry.tab === "object" ? rawEntry.tab : rawEntry;
55660
+ const posTwips = resolveTabPosition(source);
55666
55661
  if (posTwips == null) continue;
55667
- const val = normalizeTabVal(source.val ?? source.align ?? source.alignment ?? source.type);
55662
+ const val = normalizeTabVal(source.val ?? source.align ?? source.alignment ?? source.type ?? source.tabType);
55668
55663
  if (!val) continue;
55669
55664
  const tab = {
55670
55665
  val,
@@ -55676,6 +55671,21 @@ const normalizeOoxmlTabs = (tabs) => {
55676
55671
  }
55677
55672
  return normalized.length > 0 ? normalized : void 0;
55678
55673
  };
55674
+ const resolveTabPosition = (source) => {
55675
+ const originalPos = pickNumber(source.originalPos);
55676
+ if (originalPos != null) {
55677
+ return originalPos;
55678
+ }
55679
+ const posValue = pickNumber(source.pos ?? source.position ?? source.offset);
55680
+ if (posValue == null) {
55681
+ return void 0;
55682
+ }
55683
+ if (posValue > TWIPS_THRESHOLD) {
55684
+ return posValue;
55685
+ } else {
55686
+ return Math.round(posValue * PX_TO_TWIPS);
55687
+ }
55688
+ };
55679
55689
  const normalizeTabVal = (value) => {
55680
55690
  switch (value) {
55681
55691
  case "start":
@@ -55687,12 +55697,13 @@ const normalizeTabVal = (value) => {
55687
55697
  return value;
55688
55698
  case "left":
55689
55699
  return "start";
55690
- // Legacy mapping
55700
+ // Legacy mapping for RTL support
55691
55701
  case "right":
55692
55702
  return "end";
55693
- // Legacy mapping
55703
+ // Legacy mapping for RTL support
55694
55704
  case "dec":
55695
55705
  return "decimal";
55706
+ // Abbreviation mapping
55696
55707
  default:
55697
55708
  return void 0;
55698
55709
  }
@@ -55708,7 +55719,7 @@ const normalizeTabLeader = (value) => {
55708
55719
  return value;
55709
55720
  case "thick":
55710
55721
  return "heavy";
55711
- // Map legacy 'thick' to OOXML 'heavy'
55722
+ // Legacy mapping
55712
55723
  default:
55713
55724
  return void 0;
55714
55725
  }
@@ -56636,29 +56647,6 @@ const normalizeSuffix = (suffix2) => {
56636
56647
  }
56637
56648
  return void 0;
56638
56649
  };
56639
- function resolveSpacingIndent$1(style2, numbering) {
56640
- const spacing = {
56641
- before: style2.spacing?.before ?? 0,
56642
- after: style2.spacing?.after ?? 0,
56643
- line: style2.spacing?.line ?? 12,
56644
- // Default line spacing
56645
- lineRule: style2.spacing?.lineRule ?? "auto"
56646
- };
56647
- let indent = {
56648
- left: style2.indent?.left ?? 0,
56649
- right: style2.indent?.right ?? 0,
56650
- firstLine: style2.indent?.firstLine ?? 0,
56651
- hanging: style2.indent?.hanging ?? 0
56652
- };
56653
- if (numbering?.indent) {
56654
- indent = {
56655
- ...indent,
56656
- left: numbering.indent.left ?? indent.left,
56657
- hanging: numbering.indent.hanging ?? indent.hanging
56658
- };
56659
- }
56660
- return { spacing, indent };
56661
- }
56662
56650
  function computeTabStops$1(context) {
56663
56651
  const { explicitStops, defaultTabInterval, paragraphIndent } = context;
56664
56652
  const leftIndent = paragraphIndent.left ?? 0;
@@ -56770,6 +56758,90 @@ function computeEndAlignedX(entry, stop) {
56770
56758
  const targetX = stop.pos - width;
56771
56759
  return targetX < 0 ? 0 : targetX;
56772
56760
  }
56761
+ function calculateTabWidth(params2) {
56762
+ const {
56763
+ currentX,
56764
+ tabStops,
56765
+ paragraphWidth,
56766
+ defaultTabDistance: defaultTabDistance2,
56767
+ defaultLineLength: defaultLineLength2,
56768
+ followingText = "",
56769
+ measureText: measureText2,
56770
+ decimalSeparator = "."
56771
+ } = params2;
56772
+ const nextStop = tabStops.find((stop) => stop.val !== "clear" && stop.pos > currentX);
56773
+ const fallbackWidth = () => {
56774
+ let tabWidth = defaultTabDistance2 - currentX % defaultLineLength2 % defaultTabDistance2;
56775
+ if (tabWidth <= 0) tabWidth = defaultTabDistance2;
56776
+ return {
56777
+ width: tabWidth,
56778
+ alignment: "default",
56779
+ tabStopPosUsed: "default"
56780
+ };
56781
+ };
56782
+ if (!nextStop) {
56783
+ return fallbackWidth();
56784
+ }
56785
+ let width = Math.min(nextStop.pos, paragraphWidth) - currentX;
56786
+ const alignment2 = nextStop.val;
56787
+ if (alignment2 === "bar") {
56788
+ return {
56789
+ width: 0,
56790
+ leader: nextStop.leader,
56791
+ alignment: alignment2,
56792
+ tabStopPosUsed: nextStop.pos
56793
+ };
56794
+ }
56795
+ if (alignment2 === "center" || alignment2 === "end") {
56796
+ const textWidth = measureText2 ? measureText2(followingText) : 0;
56797
+ if (alignment2 === "center") {
56798
+ width -= textWidth / 2;
56799
+ } else {
56800
+ width -= textWidth;
56801
+ }
56802
+ } else if (alignment2 === "decimal") {
56803
+ const decimalIndex = followingText.indexOf(decimalSeparator);
56804
+ if (decimalIndex >= 0) {
56805
+ const before = followingText.slice(0, decimalIndex);
56806
+ const beforeWidth = measureText2 ? measureText2(before) : 0;
56807
+ width -= beforeWidth;
56808
+ }
56809
+ } else if (alignment2 === "bar") {
56810
+ width = 0;
56811
+ }
56812
+ if (width < 1) {
56813
+ return fallbackWidth();
56814
+ }
56815
+ return {
56816
+ width,
56817
+ leader: nextStop.leader,
56818
+ alignment: alignment2,
56819
+ tabStopPosUsed: nextStop.pos
56820
+ };
56821
+ }
56822
+ function resolveSpacingIndent$1(style2, numbering) {
56823
+ const spacing = {
56824
+ before: style2.spacing?.before ?? 0,
56825
+ after: style2.spacing?.after ?? 0,
56826
+ line: style2.spacing?.line ?? 12,
56827
+ // Default line spacing
56828
+ lineRule: style2.spacing?.lineRule ?? "auto"
56829
+ };
56830
+ let indent = {
56831
+ left: style2.indent?.left ?? 0,
56832
+ right: style2.indent?.right ?? 0,
56833
+ firstLine: style2.indent?.firstLine ?? 0,
56834
+ hanging: style2.indent?.hanging ?? 0
56835
+ };
56836
+ if (numbering?.indent) {
56837
+ indent = {
56838
+ ...indent,
56839
+ left: numbering.indent.left ?? indent.left,
56840
+ hanging: numbering.indent.hanging ?? indent.hanging
56841
+ };
56842
+ }
56843
+ return { spacing, indent };
56844
+ }
56773
56845
  function formatListLabel(level, indices) {
56774
56846
  const { format, text: template, start: start2 } = level;
56775
56847
  if (format === "bullet" || format === "custom") {
@@ -56935,6 +57007,7 @@ function measureRowHeights(cells, _columnWidths) {
56935
57007
  }
56936
57008
  const Engines = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
56937
57009
  __proto__: null,
57010
+ calculateTabWidth,
56938
57011
  computeListIndent,
56939
57012
  computeTabStops: computeTabStops$1,
56940
57013
  computeWrapExclusion,
@@ -56983,17 +57056,18 @@ const hydrateParagraphStyleAttrs = (para, context, preResolved) => {
56983
57056
  return null;
56984
57057
  }
56985
57058
  const resolvedExtended = resolved;
57059
+ const resolvedAsRecord = resolved;
56986
57060
  const hydrated = {
56987
57061
  resolved,
56988
- spacing: cloneIfObject(resolved.spacing),
56989
- indent: cloneIfObject(resolved.indent),
57062
+ spacing: cloneIfObject(resolvedAsRecord.spacing),
57063
+ indent: cloneIfObject(resolvedAsRecord.indent),
56990
57064
  borders: cloneIfObject(resolvedExtended.borders),
56991
57065
  shading: cloneIfObject(resolvedExtended.shading),
56992
57066
  alignment: resolvedExtended.justification,
56993
57067
  tabStops: cloneIfObject(resolvedExtended.tabStops),
56994
57068
  keepLines: resolvedExtended.keepLines,
56995
57069
  keepNext: resolvedExtended.keepNext,
56996
- numberingProperties: cloneIfObject(resolved.numberingProperties)
57070
+ numberingProperties: cloneIfObject(resolvedAsRecord.numberingProperties)
56997
57071
  };
56998
57072
  return hydrated;
56999
57073
  };
@@ -57206,6 +57280,9 @@ const normalizeResolvedTabAlignment = (value) => {
57206
57280
  }
57207
57281
  };
57208
57282
  const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleContext) => {
57283
+ if (numberingProps === null) {
57284
+ return null;
57285
+ }
57209
57286
  try {
57210
57287
  let effectiveIndent = paragraphAttrs.indent;
57211
57288
  if (numberingProps?.resolvedLevelIndent) {
@@ -57240,7 +57317,7 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
57240
57317
  return computeWordParagraphLayout({
57241
57318
  paragraph: resolvedParagraph,
57242
57319
  numbering: numberingProps,
57243
- markerRun: numberingProps.resolvedMarkerRpr,
57320
+ markerRun: numberingProps?.resolvedMarkerRpr,
57244
57321
  // Use cached if available
57245
57322
  docDefaults
57246
57323
  });
@@ -57686,7 +57763,7 @@ function processImageChild(child, sectionMetadata, context, output, converters)
57686
57763
  function processNestedStructuredContent(child, sectionMetadata, context, output, converters) {
57687
57764
  const { getListCounter, incrementListCounter, resetListCounter } = context.listCounterContext;
57688
57765
  const nestedMetadata = resolveNodeSdtMetadata(child, "structuredContentBlock");
57689
- child.content.forEach((grandchild) => {
57766
+ child.content?.forEach((grandchild) => {
57690
57767
  if (grandchild.type === "paragraph") {
57691
57768
  const paragraphBlocks = converters.paragraphToFlowBlocks(
57692
57769
  grandchild,
@@ -57738,7 +57815,7 @@ function processDocumentPartObject(child, sectionMetadata, context, output, conv
57738
57815
  if (docPartGallery === "Table of Contents") {
57739
57816
  const blocksBeforeToc = output.blocks.length;
57740
57817
  processTocChildren(
57741
- Array.from(child.content),
57818
+ Array.from(child.content ?? []),
57742
57819
  { docPartGallery, docPartObjectId, tocInstruction, sdtMetadata: docPartSdtMetadata },
57743
57820
  {
57744
57821
  nextBlockId: context.nextBlockId,
@@ -58416,7 +58493,8 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58416
58493
  trackedChanges,
58417
58494
  bookmarks,
58418
58495
  hyperlinkConfig,
58419
- converterContext
58496
+ themeColors,
58497
+ ...converterContext !== void 0 ? [converterContext] : []
58420
58498
  );
58421
58499
  if (tableBlock) {
58422
58500
  blocks.push(tableBlock);
@@ -58542,6 +58620,8 @@ function handleParagraphNode(node, context) {
58542
58620
  trackedChangesConfig,
58543
58621
  bookmarks,
58544
58622
  hyperlinkConfig,
58623
+ void 0,
58624
+ // themeColors - not available in NodeHandlerContext
58545
58625
  context.converterContext
58546
58626
  );
58547
58627
  paragraphBlocks.forEach((block) => {
@@ -59051,9 +59131,9 @@ const parseTableCell = (args) => {
59051
59131
  const paragraph = paragraphBlocks.find((b2) => b2.kind === "paragraph");
59052
59132
  if (!paragraph) return null;
59053
59133
  const cellAttrs = {};
59054
- const borders = extractCellBorders(cellNode.attrs);
59134
+ const borders = extractCellBorders(cellNode.attrs ?? {});
59055
59135
  if (borders) cellAttrs.borders = borders;
59056
- const padding = extractCellPadding(cellNode.attrs) ?? (defaultCellPadding ? { ...defaultCellPadding } : void 0);
59136
+ const padding = extractCellPadding(cellNode.attrs ?? {}) ?? (defaultCellPadding ? { ...defaultCellPadding } : void 0);
59057
59137
  if (padding) cellAttrs.padding = padding;
59058
59138
  const verticalAlign = cellNode.attrs?.verticalAlign;
59059
59139
  if (verticalAlign === "top" || verticalAlign === "middle" || verticalAlign === "bottom") {
@@ -59390,7 +59470,7 @@ function toFlowBlocks(pmDoc, options) {
59390
59470
  themeColors,
59391
59471
  converterContext
59392
59472
  );
59393
- const tableConverter = (node, nextBlockId2, positions2, defaultFont2, defaultSize2, context, trackedChanges, bookmarks2, hyperlinkConfig2) => tableNodeToBlock(
59473
+ const tableConverter = (node, nextBlockId2, positions2, defaultFont2, defaultSize2, context, trackedChanges, bookmarks2, hyperlinkConfig2, themeColorsParam, converterCtx) => tableNodeToBlock(
59394
59474
  node,
59395
59475
  nextBlockId2,
59396
59476
  positions2,
@@ -59400,8 +59480,8 @@ function toFlowBlocks(pmDoc, options) {
59400
59480
  trackedChanges,
59401
59481
  bookmarks2,
59402
59482
  hyperlinkConfig2,
59403
- themeColors,
59404
- converterContext
59483
+ themeColorsParam ?? themeColors,
59484
+ converterCtx ?? converterContext
59405
59485
  );
59406
59486
  const handlerContext = {
59407
59487
  blocks,
@@ -66083,7 +66163,7 @@ const _DomPainter = class _DomPainter2 {
66083
66163
  markerEl.style.display = "inline-block";
66084
66164
  markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66085
66165
  markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66086
- markerEl.style.textAlign = marker.justification ?? "";
66166
+ markerEl.style.textAlign = marker.justification ?? "left";
66087
66167
  markerEl.style.fontFamily = marker.run.fontFamily;
66088
66168
  markerEl.style.fontSize = `${marker.run.fontSize}px`;
66089
66169
  if (marker.run.bold) markerEl.style.fontWeight = "bold";
@@ -66471,7 +66551,7 @@ const _DomPainter = class _DomPainter2 {
66471
66551
  buildLinkRenderData(link) {
66472
66552
  const dataset = buildLinkDataset(link);
66473
66553
  const sanitized = typeof link.href === "string" ? sanitizeHref(link.href) : null;
66474
- const anchorHref = normalizeAnchor(link.anchor ?? link.name ?? null);
66554
+ const anchorHref = normalizeAnchor(link.anchor ?? link.name ?? "");
66475
66555
  let href = sanitized?.href ?? anchorHref;
66476
66556
  if (link.version === 2) {
66477
66557
  href = appendDocLocation(href, link.docLocation ?? null);
@@ -66649,6 +66729,10 @@ const _DomPainter = class _DomPainter2 {
66649
66729
  const el = this.doc.createElement("div");
66650
66730
  el.classList.add(CLASS_NAMES.line);
66651
66731
  applyStyles$2(el, lineStyles(line.lineHeight));
66732
+ const styleId = block.attrs?.styleId;
66733
+ if (styleId) {
66734
+ el.setAttribute("styleid", styleId);
66735
+ }
66652
66736
  const lineRange = computeLinePmRange(block, line);
66653
66737
  if (lineRange.pmStart != null) {
66654
66738
  el.dataset.pmStart = String(lineRange.pmStart);
@@ -66676,7 +66760,7 @@ const _DomPainter = class _DomPainter2 {
66676
66760
  leaderEl.style.height = ld.style === "heavy" ? "2px" : "1px";
66677
66761
  leaderEl.style.pointerEvents = "none";
66678
66762
  leaderEl.style.zIndex = "0";
66679
- if (ld.style === "dot") {
66763
+ if (ld.style === "dot" || ld.style === "middleDot") {
66680
66764
  leaderEl.style.borderBottom = "1px dotted currentColor";
66681
66765
  } else if (ld.style === "hyphen") {
66682
66766
  leaderEl.style.borderBottom = "1px dashed currentColor";
@@ -66713,6 +66797,9 @@ const _DomPainter = class _DomPainter2 {
66713
66797
  const segmentRun = { ...baseRun, text: segmentText };
66714
66798
  const elem = this.renderRun(segmentRun, context, trackedConfig);
66715
66799
  if (elem) {
66800
+ if (styleId) {
66801
+ elem.setAttribute("styleid", styleId);
66802
+ }
66716
66803
  let xPos;
66717
66804
  if (segment.x !== void 0) {
66718
66805
  xPos = segment.x;
@@ -66738,6 +66825,9 @@ const _DomPainter = class _DomPainter2 {
66738
66825
  runs.forEach((run2) => {
66739
66826
  const elem = this.renderRun(run2, context, trackedConfig);
66740
66827
  if (elem) {
66828
+ if (styleId) {
66829
+ elem.setAttribute("styleid", styleId);
66830
+ }
66741
66831
  el.appendChild(elem);
66742
66832
  }
66743
66833
  });
@@ -67157,6 +67247,9 @@ const applyRunDataAttributes = (element, dataAttrs) => {
67157
67247
  };
67158
67248
  const applyParagraphBlockStyles = (element, attrs) => {
67159
67249
  if (!attrs) return;
67250
+ if (attrs.styleId) {
67251
+ element.setAttribute("styleid", attrs.styleId);
67252
+ }
67160
67253
  if (attrs.alignment) {
67161
67254
  element.style.textAlign = attrs.alignment;
67162
67255
  }
@@ -67378,6 +67471,7 @@ const pxToTwips = (px) => Math.round(px * TWIPS_PER_PX);
67378
67471
  const DEFAULT_TAB_INTERVAL_PX = twipsToPx(DEFAULT_TAB_INTERVAL_TWIPS);
67379
67472
  const TAB_EPSILON = 0.1;
67380
67473
  const DEFAULT_DECIMAL_SEPARATOR = ".";
67474
+ const ALLOWED_TAB_VALS = /* @__PURE__ */ new Set(["start", "center", "end", "decimal", "bar", "clear"]);
67381
67475
  const roundValue = (value) => value;
67382
67476
  function getCanvasContext() {
67383
67477
  if (!canvasContext) {
@@ -67500,6 +67594,14 @@ async function measureParagraphBlock(block, maxWidth) {
67500
67594
  let tabStopCursor = 0;
67501
67595
  let pendingTabAlignment = null;
67502
67596
  let lastAppliedTabAlign = null;
67597
+ const warnedTabVals = /* @__PURE__ */ new Set();
67598
+ const validateTabStopVal = (stop) => {
67599
+ if (!ALLOWED_TAB_VALS.has(stop.val) && !warnedTabVals.has(stop.val)) {
67600
+ warnedTabVals.add(stop.val);
67601
+ return false;
67602
+ }
67603
+ return true;
67604
+ };
67503
67605
  const alignSegmentAtTab = (segmentText, font, runContext) => {
67504
67606
  if (!pendingTabAlignment || !currentLine) return;
67505
67607
  const { target, val } = pendingTabAlignment;
@@ -67548,8 +67650,13 @@ async function measureParagraphBlock(block, maxWidth) {
67548
67650
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
67549
67651
  currentLine.toRun = runIndex;
67550
67652
  currentLine.toChar = 1;
67551
- pendingTabAlignment = stop ? { target, val: stop.val } : null;
67552
- if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
67653
+ if (stop) {
67654
+ validateTabStopVal(stop);
67655
+ pendingTabAlignment = { target, val: stop.val };
67656
+ } else {
67657
+ pendingTabAlignment = null;
67658
+ }
67659
+ if (stop && stop.leader && stop.leader !== "none") {
67553
67660
  const leaderStyle = stop.leader;
67554
67661
  const from2 = Math.min(originX, target);
67555
67662
  const to = Math.max(originX, target);
@@ -67695,7 +67802,12 @@ async function measureParagraphBlock(block, maxWidth) {
67695
67802
  currentLine.toRun = runIndex;
67696
67803
  currentLine.toChar = charPosInRun;
67697
67804
  charPosInRun += 1;
67698
- pendingTabAlignment = stop ? { target, val: stop.val } : null;
67805
+ if (stop) {
67806
+ validateTabStopVal(stop);
67807
+ pendingTabAlignment = { target, val: stop.val };
67808
+ } else {
67809
+ pendingTabAlignment = null;
67810
+ }
67699
67811
  if (stop && stop.leader && stop.leader !== "none" && stop.leader !== "middleDot") {
67700
67812
  const leaderStyle = stop.leader;
67701
67813
  const from2 = Math.min(originX, target);
@@ -67747,10 +67859,6 @@ async function measureParagraphBlock(block, maxWidth) {
67747
67859
  markerTextWidth: glyphWidth,
67748
67860
  indentLeft: wordLayout.indentLeftPx ?? 0
67749
67861
  };
67750
- console.log(
67751
- "[measure] Marker:",
67752
- JSON.stringify({ text: markerText, width: markerInfo.markerWidth, indent: markerInfo.indentLeft })
67753
- );
67754
67862
  }
67755
67863
  return {
67756
67864
  kind: "paragraph",
@@ -74579,29 +74687,6 @@ const restartNumbering = ({ editor, tr, state: state2, dispatch }) => {
74579
74687
  };
74580
74688
  const defaultTabDistance = 48;
74581
74689
  const defaultLineLength = 816;
74582
- const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
74583
- const decorations = [];
74584
- const paragraphCache = /* @__PURE__ */ new Map();
74585
- const coordCache = /* @__PURE__ */ new Map();
74586
- const domPosCache = /* @__PURE__ */ new Map();
74587
- const end2 = to ?? doc2.content.size;
74588
- doc2.nodesBetween(from2, end2, (node, pos) => {
74589
- if (node.type.name !== "tab") return;
74590
- const $pos = doc2.resolve(pos);
74591
- const paragraphContext = findParagraphContext($pos, paragraphCache, helpers2);
74592
- if (!paragraphContext) return;
74593
- const blockParent2 = $pos.node(paragraphContext.paragraphDepth);
74594
- const style2 = calculateTabStyle(node.nodeSize, view, pos, blockParent2, paragraphContext, coordCache, domPosCache);
74595
- if (style2) {
74596
- decorations.push(
74597
- Decoration.node(pos, pos + node.nodeSize, {
74598
- style: style2
74599
- })
74600
- );
74601
- }
74602
- });
74603
- return decorations;
74604
- };
74605
74690
  function calculateTabStyle(nodeSize2, view, pos, blockParent2, paragraphContext, coordCache = null, domPosCache = null) {
74606
74691
  let extraStyles = "";
74607
74692
  try {
@@ -74653,14 +74738,14 @@ function calculateTabStyle(nodeSize2, view, pos, blockParent2, paragraphContext,
74653
74738
  tabWidth -= integralWidth;
74654
74739
  }
74655
74740
  if (tabStop.leader) {
74656
- const leaderStyles = {
74741
+ const leaderStyles2 = {
74657
74742
  dot: "border-bottom: 1px dotted black;",
74658
74743
  heavy: "border-bottom: 2px solid black;",
74659
74744
  hyphen: "border-bottom: 1px solid black;",
74660
74745
  middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
74661
74746
  underscore: "border-bottom: 1px solid black;"
74662
74747
  };
74663
- extraStyles += leaderStyles[tabStop.leader] || "";
74748
+ extraStyles += leaderStyles2[tabStop.leader] || "";
74664
74749
  }
74665
74750
  }
74666
74751
  }
@@ -74672,7 +74757,7 @@ function calculateTabStyle(nodeSize2, view, pos, blockParent2, paragraphContext,
74672
74757
  paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
74673
74758
  return `width: ${tabWidth}px; height: ${tabHeight}; ${extraStyles}`;
74674
74759
  } catch (error) {
74675
- console.error("tab decoration error", error);
74760
+ return null;
74676
74761
  }
74677
74762
  }
74678
74763
  function findParagraphContext($pos, cache2, helpers2) {
@@ -74691,13 +74776,16 @@ function findParagraphContext($pos, cache2, helpers2) {
74691
74776
  }
74692
74777
  function extractParagraphContext(node, startPos, helpers2, depth = 0) {
74693
74778
  const paragraphProperties = getResolvedParagraphProperties(node);
74779
+ const alignmentAliases = { left: "start", right: "end" };
74694
74780
  let tabStops = [];
74695
74781
  if (Array.isArray(paragraphProperties.tabStops)) {
74696
74782
  tabStops = paragraphProperties.tabStops.map((stop) => {
74697
74783
  const ref2 = stop?.tab;
74698
74784
  if (!ref2) return stop || null;
74785
+ const rawType = ref2.tabType || "start";
74786
+ const mappedVal = alignmentAliases[rawType] || rawType;
74699
74787
  return {
74700
- val: ref2.tabType || "start",
74788
+ val: mappedVal,
74701
74789
  pos: twipsToPixels(Number(ref2.pos) || 0),
74702
74790
  leader: ref2.leader
74703
74791
  };
@@ -75762,6 +75850,184 @@ const CommentsMark = Mark2.create({
75762
75850
  return [CommentMarkName, Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
75763
75851
  }
75764
75852
  });
75853
+ const leaderStyles = {
75854
+ dot: "border-bottom: 1px dotted black;",
75855
+ heavy: "border-bottom: 2px solid black;",
75856
+ hyphen: "border-bottom: 1px solid black;",
75857
+ middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
75858
+ underscore: "border-bottom: 1px solid black;"
75859
+ };
75860
+ const paragraphIdFromPos = (startPos) => `para-${startPos}`;
75861
+ const tabIdForIndex = (paragraphId, index2) => `${paragraphId}-tab-${index2}`;
75862
+ function createLayoutRequest(doc2, paragraphPos, view, helpers2, revision, paragraphWidthOverride) {
75863
+ const $pos = doc2.resolve(paragraphPos);
75864
+ const paragraphCache = /* @__PURE__ */ new Map();
75865
+ const paragraphContext = findParagraphContext($pos, paragraphCache, helpers2);
75866
+ if (!paragraphContext) return null;
75867
+ const paragraphId = paragraphIdFromPos(paragraphContext.startPos);
75868
+ const paragraphNode = paragraphContext.paragraph;
75869
+ const { entries } = flattenParagraph(paragraphNode, paragraphContext.startPos);
75870
+ const spans = [];
75871
+ let tabIndex = 0;
75872
+ entries.forEach((entry, idx) => {
75873
+ const node = entry.node;
75874
+ const spanId = `${paragraphId}-span-${idx}`;
75875
+ const from2 = entry.pos;
75876
+ const to = entry.pos + node.nodeSize;
75877
+ if (node.type.name === "tab") {
75878
+ spans.push({
75879
+ type: "tab",
75880
+ spanId,
75881
+ tabId: tabIdForIndex(paragraphId, tabIndex++),
75882
+ pos: entry.pos,
75883
+ nodeSize: node.nodeSize
75884
+ });
75885
+ } else if (node.type.name === "text") {
75886
+ spans.push({
75887
+ type: "text",
75888
+ spanId,
75889
+ text: node.text || "",
75890
+ style: node.marks?.find((mark) => mark.type.name === "textStyle")?.attrs || {},
75891
+ from: from2,
75892
+ to
75893
+ });
75894
+ }
75895
+ });
75896
+ const tabStops = Array.isArray(paragraphContext.tabStops) ? [...paragraphContext.tabStops] : [];
75897
+ const hangingPx = twipsToPixels(Number(paragraphContext.indent?.hanging) || 0);
75898
+ if (hangingPx > 0 && paragraphContext.indentWidth != null) {
75899
+ tabStops.unshift({ val: "start", pos: paragraphContext.indentWidth + hangingPx, leader: "none" });
75900
+ }
75901
+ const paragraphWidth = getBlockNodeWidth(view, paragraphContext.startPos) ?? defaultLineLength;
75902
+ const indentWidth = paragraphContext.indentWidth ?? getIndentWidth(view, paragraphContext.startPos, paragraphContext.indent);
75903
+ return {
75904
+ paragraphId,
75905
+ revision,
75906
+ paragraphWidth,
75907
+ defaultTabDistance,
75908
+ defaultLineLength,
75909
+ indents: {
75910
+ left: twipsToPixels(Number(paragraphContext.indent?.left) || 0),
75911
+ right: twipsToPixels(Number(paragraphContext.indent?.right) || 0),
75912
+ firstLine: twipsToPixels(Number(paragraphContext.indent?.firstLine) || 0),
75913
+ hanging: hangingPx
75914
+ },
75915
+ tabStops,
75916
+ spans,
75917
+ indentWidth,
75918
+ paragraphNode
75919
+ };
75920
+ }
75921
+ function calculateTabLayout(request, measurement, view) {
75922
+ const {
75923
+ spans,
75924
+ tabStops,
75925
+ paragraphWidth,
75926
+ defaultTabDistance: defaultTabDistance2,
75927
+ defaultLineLength: defaultLineLength2,
75928
+ paragraphId,
75929
+ revision,
75930
+ indentWidth = 0,
75931
+ paragraphNode
75932
+ } = request;
75933
+ const tabs = {};
75934
+ let currentX = indentWidth;
75935
+ const measureText2 = (span) => {
75936
+ if (view && typeof span.from === "number" && typeof span.to === "number") {
75937
+ return measureRangeWidth(view, span.from, span.to);
75938
+ }
75939
+ return 0;
75940
+ };
75941
+ const tabHeight = paragraphNode ? calcTabHeight(paragraphNode) : void 0;
75942
+ for (let i = 0; i < spans.length; i++) {
75943
+ const span = spans[i];
75944
+ if (span.type === "text") {
75945
+ currentX += measureText2(span);
75946
+ } else if (span.type === "tab") {
75947
+ const followingText = collectFollowingText(spans, i + 1);
75948
+ let measureTextCallback;
75949
+ if (view) {
75950
+ const followingRange = getFollowingTextRange(spans, i + 1);
75951
+ if (followingRange) {
75952
+ const fullWidth = measureRangeWidth(view, followingRange.from, followingRange.to);
75953
+ const fullText = followingText;
75954
+ measureTextCallback = (text) => {
75955
+ if (text === fullText) return fullWidth;
75956
+ if (fullText.length > 0) {
75957
+ return text.length / fullText.length * fullWidth;
75958
+ }
75959
+ return 0;
75960
+ };
75961
+ }
75962
+ }
75963
+ const result = calculateTabWidth({
75964
+ currentX,
75965
+ tabStops,
75966
+ paragraphWidth,
75967
+ defaultTabDistance: defaultTabDistance2,
75968
+ defaultLineLength: defaultLineLength2,
75969
+ followingText,
75970
+ measureText: measureTextCallback
75971
+ });
75972
+ tabs[span.tabId] = {
75973
+ width: result.width,
75974
+ height: tabHeight,
75975
+ leader: result.leader,
75976
+ alignment: result.alignment,
75977
+ tabStopPosUsed: result.tabStopPosUsed
75978
+ };
75979
+ currentX += result.width;
75980
+ }
75981
+ }
75982
+ return {
75983
+ paragraphId,
75984
+ revision,
75985
+ tabs
75986
+ };
75987
+ }
75988
+ function applyLayoutResult(result, paragraph, paragraphPos) {
75989
+ const decorations = [];
75990
+ let tabIndex = 0;
75991
+ paragraph.forEach((node, offset2) => {
75992
+ if (node.type.name !== "tab") return;
75993
+ const pos = paragraphPos + offset2 + 1;
75994
+ const tabId = tabIdForIndex(result.paragraphId, tabIndex++);
75995
+ const layout = result.tabs[tabId];
75996
+ if (!layout) return;
75997
+ let style2 = `width: ${layout.width}px;`;
75998
+ if (layout.height) style2 += ` height: ${layout.height};`;
75999
+ if (layout.leader && leaderStyles[layout.leader]) {
76000
+ style2 += ` ${leaderStyles[layout.leader]}`;
76001
+ }
76002
+ decorations.push(Decoration.node(pos, pos + node.nodeSize, { style: style2 }));
76003
+ });
76004
+ return decorations;
76005
+ }
76006
+ function collectFollowingText(spans, startIndex) {
76007
+ let text = "";
76008
+ for (let i = startIndex; i < spans.length; i++) {
76009
+ const span = spans[i];
76010
+ if (span.type === "tab") break;
76011
+ if (span.type === "text") text += span.text || "";
76012
+ }
76013
+ return text;
76014
+ }
76015
+ function getFollowingTextRange(spans, startIndex) {
76016
+ let from2 = null;
76017
+ let to = null;
76018
+ for (let i = startIndex; i < spans.length; i++) {
76019
+ const span = spans[i];
76020
+ if (span.type === "tab") break;
76021
+ if (span.type === "text" && typeof span.from === "number" && typeof span.to === "number") {
76022
+ if (from2 === null) from2 = span.from;
76023
+ to = span.to;
76024
+ }
76025
+ }
76026
+ if (from2 !== null && to !== null) {
76027
+ return { from: from2, to };
76028
+ }
76029
+ return null;
76030
+ }
75765
76031
  const TabNode = Node$1.create({
75766
76032
  name: "tab",
75767
76033
  group: "inline",
@@ -75803,87 +76069,24 @@ const TabNode = Node$1.create({
75803
76069
  return [];
75804
76070
  }
75805
76071
  const { view, helpers: helpers2 } = this.editor;
75806
- const mergeRanges2 = (ranges) => {
75807
- if (ranges.length === 0) return [];
75808
- const sorted = ranges.slice().sort((a, b2) => a[0] - b2[0]);
75809
- const merged = [sorted[0]];
75810
- for (let i = 1; i < sorted.length; i++) {
75811
- const [start2, end2] = sorted[i];
75812
- const last = merged[merged.length - 1];
75813
- if (start2 <= last[1]) {
75814
- last[1] = Math.max(last[1], end2);
75815
- } else {
75816
- merged.push([start2, end2]);
75817
- }
75818
- }
75819
- return merged;
75820
- };
75821
76072
  const tabPlugin = new Plugin({
75822
76073
  name: "tabPlugin",
75823
76074
  key: new PluginKey("tabPlugin"),
75824
76075
  state: {
75825
76076
  init() {
75826
- return { decorations: false };
76077
+ return { decorations: false, revision: 0 };
75827
76078
  },
75828
- apply(tr, { decorations }, _oldState, newState) {
76079
+ apply(tr, { decorations, revision }, _oldState, newState) {
75829
76080
  if (!decorations) {
75830
- decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view, helpers2));
75831
- return { decorations };
76081
+ const newDecorations2 = buildDecorations(newState.doc, view, helpers2, 0);
76082
+ return { decorations: newDecorations2, revision: 0 };
75832
76083
  }
75833
76084
  if (!tr.docChanged || tr.getMeta("blockNodeInitialUpdate")) {
75834
- return { decorations };
76085
+ return { decorations, revision };
75835
76086
  }
75836
- decorations = decorations.map(tr.mapping, tr.doc);
75837
- const rangesToRecalculate = [];
75838
- const containsTab = (node) => node.type.name === "tab";
75839
- tr.steps.forEach((step, index2) => {
75840
- if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep$1)) {
75841
- return;
75842
- }
75843
- let hasTabInRange = false;
75844
- if (step.slice?.content) {
75845
- step.slice.content.descendants((node) => {
75846
- if (containsTab(node)) {
75847
- hasTabInRange = true;
75848
- return false;
75849
- }
75850
- });
75851
- }
75852
- if (!hasTabInRange) {
75853
- tr.docs[index2].nodesBetween(step.from, step.to, (node) => {
75854
- if (containsTab(node)) {
75855
- hasTabInRange = true;
75856
- return false;
75857
- }
75858
- });
75859
- }
75860
- if (!hasTabInRange) {
75861
- return;
75862
- }
75863
- let fromPos = step.from;
75864
- let toPos = step.to;
75865
- for (let i = index2; i < tr.steps.length; i++) {
75866
- const stepMap = tr.steps[i].getMap();
75867
- fromPos = stepMap.map(fromPos, -1);
75868
- toPos = stepMap.map(toPos, 1);
75869
- }
75870
- const $from = newState.doc.resolve(fromPos);
75871
- const $to = newState.doc.resolve(toPos);
75872
- const start2 = $from.start(Math.min($from.depth, 1));
75873
- const end2 = $to.end(Math.min($to.depth, 1));
75874
- rangesToRecalculate.push([start2, end2]);
75875
- });
75876
- if (rangesToRecalculate.length === 0) {
75877
- return { decorations };
75878
- }
75879
- const mergedRanges = mergeRanges2(rangesToRecalculate);
75880
- mergedRanges.forEach(([start2, end2]) => {
75881
- const oldDecorations = decorations.find(start2, end2);
75882
- decorations = decorations.remove(oldDecorations);
75883
- const newDecorations = getTabDecorations(newState.doc, view, helpers2, start2, end2);
75884
- decorations = decorations.add(newState.doc, newDecorations);
75885
- });
75886
- return { decorations };
76087
+ const nextRevision = revision + 1;
76088
+ const newDecorations = buildDecorations(newState.doc, view, helpers2, nextRevision);
76089
+ return { decorations: newDecorations, revision: nextRevision };
75887
76090
  }
75888
76091
  },
75889
76092
  props: {
@@ -75895,6 +76098,27 @@ const TabNode = Node$1.create({
75895
76098
  return [tabPlugin];
75896
76099
  }
75897
76100
  });
76101
+ function buildDecorations(doc2, view, helpers2, revision) {
76102
+ const decorations = [];
76103
+ doc2.descendants((node, pos) => {
76104
+ if (node.type.name !== "paragraph") return;
76105
+ let hasTab = false;
76106
+ node.descendants((child) => {
76107
+ if (child.type.name === "tab") {
76108
+ hasTab = true;
76109
+ return false;
76110
+ }
76111
+ return true;
76112
+ });
76113
+ if (!hasTab) return;
76114
+ const request = createLayoutRequest(doc2, pos + 1, view, helpers2, revision);
76115
+ if (!request) return;
76116
+ const result = calculateTabLayout(request, void 0, view);
76117
+ const paragraphDecorations = applyLayoutResult(result, node, pos);
76118
+ decorations.push(...paragraphDecorations);
76119
+ });
76120
+ return DecorationSet.create(doc2, decorations);
76121
+ }
75898
76122
  const LineBreak = Node$1.create({
75899
76123
  name: "lineBreak",
75900
76124
  group: "inline",
@@ -89371,13 +89595,22 @@ function checkWordBoundary(state2, pos) {
89371
89595
  return !/\p{L}$/u.test(before.text) || !/^\p{L}/u.test(after.text);
89372
89596
  }
89373
89597
  class SearchState {
89374
- constructor(query, range2, deco) {
89598
+ /**
89599
+ * Create a new SearchState instance.
89600
+ *
89601
+ * @param {SearchQuery} query - The search query to execute
89602
+ * @param {{from: number, to: number}|null} range - Optional range to restrict search to, or null for entire document
89603
+ * @param {boolean} highlight - Whether to apply CSS classes for visual highlighting of matches
89604
+ * @param {DecorationSet} deco - The decoration set containing match highlights
89605
+ */
89606
+ constructor(query, range2, highlight, deco) {
89375
89607
  this.query = query;
89376
89608
  this.range = range2;
89609
+ this.highlight = highlight;
89377
89610
  this.deco = deco;
89378
89611
  }
89379
89612
  }
89380
- function buildMatchDeco(state2, query, range2) {
89613
+ function buildMatchDeco(state2, query, range2, highlight = true) {
89381
89614
  if (!query.valid) return DecorationSet.empty;
89382
89615
  let deco = [];
89383
89616
  let sel = state2.selection;
@@ -89385,7 +89618,8 @@ function buildMatchDeco(state2, query, range2) {
89385
89618
  let next = query.findNext(state2, pos, end2);
89386
89619
  if (!next) break;
89387
89620
  let cls = next.from == sel.from && next.to == sel.to ? "ProseMirror-active-search-match" : "ProseMirror-search-match";
89388
- deco.push(Decoration.inline(next.from, next.to, { class: cls }));
89621
+ const attrs = highlight ? { class: cls } : {};
89622
+ deco.push(Decoration.inline(next.from, next.to, attrs));
89389
89623
  pos = next.to;
89390
89624
  }
89391
89625
  return DecorationSet.create(state2.doc, deco);
@@ -89398,11 +89632,20 @@ function search(options = {}) {
89398
89632
  init(_config, state2) {
89399
89633
  let query = options.initialQuery || new SearchQuery({ search: "" });
89400
89634
  let range2 = options.initialRange || null;
89401
- return new SearchState(query, range2, buildMatchDeco(state2, query, range2));
89635
+ const highlight = options.initialHighlight ?? true;
89636
+ return new SearchState(query, range2, highlight, buildMatchDeco(state2, query, range2, highlight));
89402
89637
  },
89403
89638
  apply(tr, search2, _oldState, state2) {
89404
89639
  let set = tr.getMeta(searchKey);
89405
- if (set) return new SearchState(set.query, set.range, buildMatchDeco(state2, set.query, set.range));
89640
+ if (set) {
89641
+ const highlight = typeof set.highlight === "boolean" ? set.highlight : true;
89642
+ return new SearchState(
89643
+ set.query,
89644
+ set.range,
89645
+ highlight,
89646
+ buildMatchDeco(state2, set.query, set.range, highlight)
89647
+ );
89648
+ }
89406
89649
  if (tr.docChanged || tr.selectionSet) {
89407
89650
  let range2 = search2.range;
89408
89651
  if (range2) {
@@ -89410,7 +89653,13 @@ function search(options = {}) {
89410
89653
  let to = tr.mapping.map(range2.to, -1);
89411
89654
  range2 = from2 < to ? { from: from2, to } : null;
89412
89655
  }
89413
- search2 = new SearchState(search2.query, range2, buildMatchDeco(state2, search2.query, range2));
89656
+ const highlight = typeof search2.highlight === "boolean" ? search2.highlight : true;
89657
+ search2 = new SearchState(
89658
+ search2.query,
89659
+ range2,
89660
+ highlight,
89661
+ buildMatchDeco(state2, search2.query, range2, highlight)
89662
+ );
89414
89663
  }
89415
89664
  return search2;
89416
89665
  }
@@ -89424,8 +89673,12 @@ function getMatchHighlights(state2) {
89424
89673
  let search2 = searchKey.getState(state2);
89425
89674
  return search2 ? search2.deco : DecorationSet.empty;
89426
89675
  }
89427
- function setSearchState(tr, query, range2 = null) {
89428
- return tr.setMeta(searchKey, { query, range: range2 });
89676
+ function setSearchState(tr, query, range2 = null, options = {}) {
89677
+ if (options != null && (typeof options !== "object" || Array.isArray(options))) {
89678
+ throw new TypeError("setSearchState options must be an object");
89679
+ }
89680
+ const highlight = typeof options?.highlight === "boolean" ? options.highlight : true;
89681
+ return tr.setMeta(searchKey, { query, range: range2, highlight });
89429
89682
  }
89430
89683
  const isRegExp = (value) => Object.prototype.toString.call(value) === "[object RegExp]";
89431
89684
  const Search = Extension.create({
@@ -89486,14 +89739,25 @@ const Search = Extension.create({
89486
89739
  * Search for string matches in editor content
89487
89740
  * @category Command
89488
89741
  * @param {String|RegExp} patternInput - Search string or pattern
89742
+ * @param {SearchCommandOptions} [options={}] - Options to control search behavior
89489
89743
  * @example
89744
+ * // Basic search with highlighting (default)
89490
89745
  * const matches = editor.commands.search('test string')
89746
+ *
89747
+ * // Regex search
89491
89748
  * const regexMatches = editor.commands.search(/test/i)
89749
+ *
89750
+ * // Search without visual highlighting
89751
+ * const silentMatches = editor.commands.search('test', { highlight: false })
89492
89752
  * @note Returns array of SearchMatch objects with positions and IDs
89493
89753
  */
89494
- search: (patternInput) => (
89754
+ search: (patternInput, options = {}) => (
89495
89755
  /** @returns {SearchMatch[]} */
89496
89756
  (({ state: state2, dispatch }) => {
89757
+ if (options != null && (typeof options !== "object" || Array.isArray(options))) {
89758
+ throw new TypeError("Search options must be an object");
89759
+ }
89760
+ const highlight = typeof options?.highlight === "boolean" ? options.highlight : true;
89497
89761
  let pattern;
89498
89762
  let caseSensitive = false;
89499
89763
  let regexp = false;
@@ -89520,7 +89784,7 @@ const Search = Extension.create({
89520
89784
  regexp,
89521
89785
  wholeWord
89522
89786
  });
89523
- const tr = setSearchState(state2.tr, query);
89787
+ const tr = setSearchState(state2.tr, query, null, { highlight });
89524
89788
  dispatch(tr);
89525
89789
  const newState = state2.apply(tr);
89526
89790
  const decoSet = getMatchHighlights(newState);
@@ -103839,14 +104103,19 @@ deactivateAll_fn = function() {
103839
104103
  });
103840
104104
  };
103841
104105
  updateToolbarHistory_fn = function() {
103842
- if (!this.activeEditor) return;
103843
- if (this.activeEditor.options.ydoc) {
103844
- const undoManager = yUndoPluginKey.getState(this.activeEditor.state)?.undoManager;
103845
- this.undoDepth = undoManager?.undoStack.length || 0;
103846
- this.redoDepth = undoManager?.redoStack.length || 0;
103847
- } else {
103848
- this.undoDepth = undoDepth(this.activeEditor.state);
103849
- this.redoDepth = redoDepth(this.activeEditor.state);
104106
+ if (!this.activeEditor?.state) return;
104107
+ try {
104108
+ if (this.activeEditor.options.ydoc) {
104109
+ const undoManager = yUndoPluginKey.getState(this.activeEditor.state)?.undoManager;
104110
+ this.undoDepth = undoManager?.undoStack.length || 0;
104111
+ this.redoDepth = undoManager?.redoStack.length || 0;
104112
+ } else {
104113
+ this.undoDepth = undoDepth(this.activeEditor.state);
104114
+ this.redoDepth = redoDepth(this.activeEditor.state);
104115
+ }
104116
+ } catch {
104117
+ this.undoDepth = 0;
104118
+ this.redoDepth = 0;
103850
104119
  }
103851
104120
  };
103852
104121
  enrichTrackedChanges_fn = function(trackedChanges = []) {