@pixerate/editor 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +101 -1
  2. package/THIRD_PARTY_NOTICES.md +40 -0
  3. package/dist/agent/index.cjs +175 -11
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +18 -4
  6. package/dist/agent/index.d.ts +18 -4
  7. package/dist/agent/index.js +168 -4
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/{arrangeShortcuts-B8O3f8-P.d.cts → arrange-BICutYPk.d.cts} +243 -29
  10. package/dist/{arrangeShortcuts-sLlD2rSX.d.ts → arrange-BICutYPk.d.ts} +243 -29
  11. package/dist/builtins-CdPcLwwF.d.cts +176 -0
  12. package/dist/builtins-Chj6zv_O.d.ts +176 -0
  13. package/dist/canvas/index.cjs +8588 -1857
  14. package/dist/canvas/index.cjs.map +1 -1
  15. package/dist/canvas/index.d.cts +1847 -9
  16. package/dist/canvas/index.d.ts +1847 -9
  17. package/dist/canvas/index.js +8577 -1846
  18. package/dist/canvas/index.js.map +1 -1
  19. package/dist/chunk-3CC7OPUQ.cjs +831 -0
  20. package/dist/chunk-3CC7OPUQ.cjs.map +1 -0
  21. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  22. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  23. package/dist/chunk-BVP3TSLH.cjs +69 -0
  24. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  25. package/dist/{chunk-OLZJXL4R.cjs → chunk-CS6NZWWA.cjs} +59 -25
  26. package/dist/chunk-CS6NZWWA.cjs.map +1 -0
  27. package/dist/{chunk-MCSJFWAO.cjs → chunk-EWCOFSCQ.cjs} +685 -100
  28. package/dist/chunk-EWCOFSCQ.cjs.map +1 -0
  29. package/dist/chunk-HDYMLS3X.cjs +409 -0
  30. package/dist/chunk-HDYMLS3X.cjs.map +1 -0
  31. package/dist/chunk-HRMEDT2L.js +1406 -0
  32. package/dist/chunk-HRMEDT2L.js.map +1 -0
  33. package/dist/{chunk-D27YFC46.cjs → chunk-IFHKKVXH.cjs} +382 -63
  34. package/dist/chunk-IFHKKVXH.cjs.map +1 -0
  35. package/dist/{chunk-PGNZKFQS.js → chunk-JOIREKL7.js} +137 -58
  36. package/dist/chunk-JOIREKL7.js.map +1 -0
  37. package/dist/chunk-KRGXUQ2Y.js +1696 -0
  38. package/dist/chunk-KRGXUQ2Y.js.map +1 -0
  39. package/dist/{chunk-3LV6RRPH.js → chunk-MHEPLBFB.js} +2 -2
  40. package/dist/chunk-MR2764X2.js +831 -0
  41. package/dist/chunk-MR2764X2.js.map +1 -0
  42. package/dist/{chunk-XNORY7M6.cjs → chunk-NFVBT3UZ.cjs} +166 -87
  43. package/dist/chunk-NFVBT3UZ.cjs.map +1 -0
  44. package/dist/chunk-NQF32I6Z.cjs +6478 -0
  45. package/dist/chunk-NQF32I6Z.cjs.map +1 -0
  46. package/dist/chunk-O5RYH2PG.js +69 -0
  47. package/dist/chunk-O5RYH2PG.js.map +1 -0
  48. package/dist/{chunk-ITBSKI26.js → chunk-Q2OHWD2A.js} +1064 -360
  49. package/dist/chunk-Q2OHWD2A.js.map +1 -0
  50. package/dist/{chunk-FODNLX5N.js → chunk-QJSOZFCZ.js} +38 -4
  51. package/dist/chunk-QJSOZFCZ.js.map +1 -0
  52. package/dist/{chunk-SML64VJG.cjs → chunk-RRREAOVM.cjs} +4 -4
  53. package/dist/{chunk-SML64VJG.cjs.map → chunk-RRREAOVM.cjs.map} +1 -1
  54. package/dist/{chunk-5S3Z4PPF.js → chunk-SWE3NPOU.js} +347 -28
  55. package/dist/chunk-SWE3NPOU.js.map +1 -0
  56. package/dist/chunk-TXXNBDQX.cjs +1696 -0
  57. package/dist/chunk-TXXNBDQX.cjs.map +1 -0
  58. package/dist/chunk-UBCFIABU.js +409 -0
  59. package/dist/chunk-UBCFIABU.js.map +1 -0
  60. package/dist/chunk-X7HXL2SB.js +6478 -0
  61. package/dist/chunk-X7HXL2SB.js.map +1 -0
  62. package/dist/{chunk-SBCZ6RN5.cjs → chunk-YOMYSFJU.cjs} +1163 -459
  63. package/dist/chunk-YOMYSFJU.cjs.map +1 -0
  64. package/dist/{chunk-3CN2WD3X.js → chunk-ZRNHGAQT.js} +661 -76
  65. package/dist/chunk-ZRNHGAQT.js.map +1 -0
  66. package/dist/commands/index.cjs +425 -4
  67. package/dist/commands/index.cjs.map +1 -1
  68. package/dist/commands/index.d.cts +39 -77
  69. package/dist/commands/index.d.ts +39 -77
  70. package/dist/commands/index.js +424 -3
  71. package/dist/commands/index.js.map +1 -1
  72. package/dist/compare/index.cjs +3 -3
  73. package/dist/compare/index.d.cts +1 -1
  74. package/dist/compare/index.d.ts +1 -1
  75. package/dist/compare/index.js +2 -2
  76. package/dist/controller-CxXGOEmy.d.cts +2038 -0
  77. package/dist/controller-CxXGOEmy.d.ts +2038 -0
  78. package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
  79. package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
  80. package/dist/export/index.cjs +36 -0
  81. package/dist/export/index.cjs.map +1 -0
  82. package/dist/export/index.d.cts +243 -0
  83. package/dist/export/index.d.ts +243 -0
  84. package/dist/export/index.js +36 -0
  85. package/dist/export/index.js.map +1 -0
  86. package/dist/extensions/index.cjs +101 -6
  87. package/dist/extensions/index.cjs.map +1 -1
  88. package/dist/extensions/index.d.cts +18 -5
  89. package/dist/extensions/index.d.ts +18 -5
  90. package/dist/extensions/index.js +101 -6
  91. package/dist/generation/index.cjs +1013 -69
  92. package/dist/generation/index.cjs.map +1 -1
  93. package/dist/generation/index.d.cts +474 -13
  94. package/dist/generation/index.d.ts +474 -13
  95. package/dist/generation/index.js +976 -32
  96. package/dist/generation/index.js.map +1 -1
  97. package/dist/image-editor/index.cjs +3385 -1275
  98. package/dist/image-editor/index.cjs.map +1 -1
  99. package/dist/image-editor/index.d.cts +693 -128
  100. package/dist/image-editor/index.d.ts +693 -128
  101. package/dist/image-editor/index.js +3325 -1215
  102. package/dist/image-editor/index.js.map +1 -1
  103. package/dist/{index-fJrlkJCd.d.ts → index-B273Zllk.d.ts} +500 -7
  104. package/dist/{index-BhJBSm2d.d.cts → index-jcJwmBYt.d.cts} +500 -7
  105. package/dist/index.cjs +1603 -45
  106. package/dist/index.cjs.map +1 -1
  107. package/dist/index.d.cts +154 -27
  108. package/dist/index.d.ts +154 -27
  109. package/dist/index.js +1584 -26
  110. package/dist/index.js.map +1 -1
  111. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  112. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  113. package/dist/model-C1zApQM8.d.cts +219 -0
  114. package/dist/model-C1zApQM8.d.ts +219 -0
  115. package/dist/persistence/index.d.cts +3 -120
  116. package/dist/persistence/index.d.ts +3 -120
  117. package/dist/registry-CED5C0lA.d.cts +204 -0
  118. package/dist/registry-CED5C0lA.d.ts +204 -0
  119. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
  120. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
  121. package/dist/{registry-D32LpIc4.d.cts → registry-D0GADKc7.d.cts} +1 -1
  122. package/dist/{registry-evKTP4ls.d.ts → registry-DhVUZioj.d.ts} +1 -1
  123. package/dist/serializers/index.cjs +12 -4
  124. package/dist/serializers/index.cjs.map +1 -1
  125. package/dist/serializers/index.d.cts +41 -13
  126. package/dist/serializers/index.d.ts +41 -13
  127. package/dist/serializers/index.js +12 -4
  128. package/dist/spreadsheet/index.cjs +157 -3
  129. package/dist/spreadsheet/index.cjs.map +1 -1
  130. package/dist/spreadsheet/index.d.cts +534 -11
  131. package/dist/spreadsheet/index.d.ts +534 -11
  132. package/dist/spreadsheet/index.js +157 -3
  133. package/dist/storage-BpFfspHm.d.cts +120 -0
  134. package/dist/storage-BpFfspHm.d.ts +120 -0
  135. package/dist/tokens/index.cjs +115 -0
  136. package/dist/tokens/index.cjs.map +1 -0
  137. package/dist/tokens/index.d.cts +212 -0
  138. package/dist/tokens/index.d.ts +212 -0
  139. package/dist/tokens/index.js +115 -0
  140. package/dist/tokens/index.js.map +1 -0
  141. package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
  142. package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
  143. package/package.json +15 -1
  144. package/dist/chunk-3CN2WD3X.js.map +0 -1
  145. package/dist/chunk-5S3Z4PPF.js.map +0 -1
  146. package/dist/chunk-D27YFC46.cjs.map +0 -1
  147. package/dist/chunk-FODNLX5N.js.map +0 -1
  148. package/dist/chunk-ITBSKI26.js.map +0 -1
  149. package/dist/chunk-MA2F5KHF.cjs +0 -3223
  150. package/dist/chunk-MA2F5KHF.cjs.map +0 -1
  151. package/dist/chunk-MCSJFWAO.cjs.map +0 -1
  152. package/dist/chunk-OLZJXL4R.cjs.map +0 -1
  153. package/dist/chunk-PGNZKFQS.js.map +0 -1
  154. package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
  155. package/dist/chunk-U5KWZU4X.js +0 -3223
  156. package/dist/chunk-U5KWZU4X.js.map +0 -1
  157. package/dist/chunk-XNORY7M6.cjs.map +0 -1
  158. package/dist/controller-BhLLAoi8.d.cts +0 -1000
  159. package/dist/controller-BhLLAoi8.d.ts +0 -1000
  160. package/dist/types-DX4Mh4SL.d.cts +0 -217
  161. package/dist/types-DX4Mh4SL.d.ts +0 -217
  162. /package/dist/{chunk-3LV6RRPH.js.map → chunk-MHEPLBFB.js.map} +0 -0
@@ -264,6 +264,7 @@ var INSERTION_MARK_NAME = "insertion";
264
264
  var DELETION_MARK_NAME = "deletion";
265
265
  var FORMAT_CHANGE_MARK_NAME = "formatChange";
266
266
  var BLOCK_CHANGE_ATTRIBUTE = "blockChange";
267
+ var MOVE_ID_ATTRIBUTE = "moveId";
267
268
  var REVIEW_MARK_NAMES = /* @__PURE__ */ new Set([
268
269
  INSERTION_MARK_NAME,
269
270
  DELETION_MARK_NAME,
@@ -337,6 +338,15 @@ var sharedAttributes = () => ({
337
338
  renderHTML: (attrs) => ({ "data-created-at": String(attrs.createdAt) })
338
339
  }
339
340
  });
341
+ var moveAttribute = () => ({
342
+ [MOVE_ID_ATTRIBUTE]: {
343
+ default: null,
344
+ parseHTML: (el) => el.getAttribute("data-move-id"),
345
+ renderHTML: (attrs) => attrs[MOVE_ID_ATTRIBUTE] ? { "data-move-id": attrs[MOVE_ID_ATTRIBUTE] } : {}
346
+ }
347
+ });
348
+ var MOVE_TO_CLASS = "pixerate-move-to underline decoration-double decoration-emerald-600 text-emerald-700 dark:text-emerald-400";
349
+ var MOVE_FROM_CLASS = "pixerate-move-from line-through decoration-double decoration-emerald-600 text-emerald-700 dark:text-emerald-400";
340
350
  var TrackedInsertion = _core.Mark.create({
341
351
  name: INSERTION_MARK_NAME,
342
352
  inclusive: false,
@@ -344,20 +354,22 @@ var TrackedInsertion = _core.Mark.create({
344
354
  return {
345
355
  HTMLAttributes: {
346
356
  class: "pixerate-insertion underline decoration-emerald-500 text-emerald-700 dark:text-emerald-400"
347
- }
357
+ },
358
+ moveHTMLAttributes: { class: MOVE_TO_CLASS }
348
359
  };
349
360
  },
350
361
  addStorage() {
351
362
  return { markdown: { serialize: { open: "", close: "" }, parse: {} } };
352
363
  },
353
- addAttributes: sharedAttributes,
364
+ addAttributes: () => ({ ...sharedAttributes(), ...moveAttribute() }),
354
365
  parseHTML() {
355
366
  return [{ tag: 'ins[data-change-type="insertion"]', priority: 100 }];
356
367
  },
357
- renderHTML({ HTMLAttributes }) {
368
+ renderHTML({ mark, HTMLAttributes }) {
369
+ const base = mark.attrs[MOVE_ID_ATTRIBUTE] ? this.options.moveHTMLAttributes : this.options.HTMLAttributes;
358
370
  return [
359
371
  "ins",
360
- _core.mergeAttributes.call(void 0, this.options.HTMLAttributes, HTMLAttributes, {
372
+ _core.mergeAttributes.call(void 0, base, HTMLAttributes, {
361
373
  "data-change-type": "insertion"
362
374
  }),
363
375
  0
@@ -371,7 +383,8 @@ var TrackedDeletion = _core.Mark.create({
371
383
  return {
372
384
  HTMLAttributes: {
373
385
  class: "pixerate-deletion line-through decoration-red-500 text-red-600 dark:text-red-400"
374
- }
386
+ },
387
+ moveHTMLAttributes: { class: MOVE_FROM_CLASS }
375
388
  };
376
389
  },
377
390
  addStorage() {
@@ -382,14 +395,15 @@ var TrackedDeletion = _core.Mark.create({
382
395
  }
383
396
  };
384
397
  },
385
- addAttributes: sharedAttributes,
398
+ addAttributes: () => ({ ...sharedAttributes(), ...moveAttribute() }),
386
399
  parseHTML() {
387
400
  return [{ tag: 'del[data-change-type="deletion"]', priority: 100 }];
388
401
  },
389
- renderHTML({ HTMLAttributes }) {
402
+ renderHTML({ mark, HTMLAttributes }) {
403
+ const base = mark.attrs[MOVE_ID_ATTRIBUTE] ? this.options.moveHTMLAttributes : this.options.HTMLAttributes;
390
404
  return [
391
405
  "del",
392
- _core.mergeAttributes.call(void 0, this.options.HTMLAttributes, HTMLAttributes, {
406
+ _core.mergeAttributes.call(void 0, base, HTMLAttributes, {
393
407
  "data-change-type": "deletion"
394
408
  }),
395
409
  0
@@ -539,6 +553,8 @@ function describeBlockChange(previous, current, ignoredAttributes = ["id"]) {
539
553
  keys.forEach((key) => {
540
554
  if (key === "textAlign") {
541
555
  parts.push(`Changed alignment to ${humanize(String(_nullishCoalesce(_optionalChain([current, 'access', _8 => _8.attrs, 'optionalAccess', _9 => _9.textAlign]), () => ( "default"))))}`);
556
+ } else if (key === "styleId") {
557
+ parts.push(`Changed style to ${_nullishCoalesce(_optionalChain([current, 'access', _10 => _10.attrs, 'optionalAccess', _11 => _11.styleId]), () => ( "default"))}`);
542
558
  } else {
543
559
  parts.push(`Changed ${humanize(key).toLowerCase()} of ${after}`);
544
560
  }
@@ -559,12 +575,26 @@ function describeBlockChange(previous, current, ignoredAttributes = ["id"]) {
559
575
  }
560
576
  return parts.join("; ") || `Changed ${after}`;
561
577
  }
578
+ function trackedChangeLabel(change) {
579
+ switch (change.type) {
580
+ case "insertion":
581
+ return "Inserted";
582
+ case "deletion":
583
+ return "Deleted";
584
+ case "format":
585
+ return "Formatted";
586
+ case "move":
587
+ return "Moved";
588
+ default:
589
+ return "Changed";
590
+ }
591
+ }
562
592
  function truncate(text, max = 40) {
563
593
  return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
564
594
  }
565
595
  function toDoc(source) {
566
596
  if (!source) return null;
567
- if (_optionalChain([source, 'access', _10 => _10.state, 'optionalAccess', _11 => _11.doc])) return source.state.doc;
597
+ if (_optionalChain([source, 'access', _12 => _12.state, 'optionalAccess', _13 => _13.doc])) return source.state.doc;
568
598
  if (source.doc && typeof source.doc.descendants === "function") return source.doc;
569
599
  if (typeof source.descendants === "function") return source;
570
600
  return null;
@@ -631,10 +661,22 @@ function getTrackedChanges(source) {
631
661
  return change;
632
662
  };
633
663
  const blockCounts = /* @__PURE__ */ new Map();
664
+ const blockCells = /* @__PURE__ */ new Map();
634
665
  doc.descendants((node, pos) => {
635
- const block = _optionalChain([node, 'access', _12 => _12.attrs, 'optionalAccess', _13 => _13[BLOCK_CHANGE_ATTRIBUTE]]);
636
- if (_optionalChain([block, 'optionalAccess', _14 => _14.changeId]) && node.isTextblock) {
666
+ const block = _optionalChain([node, 'access', _14 => _14.attrs, 'optionalAccess', _15 => _15[BLOCK_CHANGE_ATTRIBUTE]]);
667
+ if (_optionalChain([block, 'optionalAccess', _16 => _16.changeId]) && node.isTextblock) {
637
668
  blockCounts.set(block.changeId, (_nullishCoalesce(blockCounts.get(block.changeId), () => ( 0))) + 1);
669
+ if (block.operation && blockCells.get(block.changeId) !== null) {
670
+ const $pos = doc.resolve(pos);
671
+ let cell = -1;
672
+ for (let depth = $pos.depth; depth > 0 && cell < 0; depth--) {
673
+ const role = $pos.node(depth).type.spec.tableRole;
674
+ if (role === "cell" || role === "header_cell") cell = $pos.before(depth);
675
+ }
676
+ const cells = _nullishCoalesce(blockCells.get(block.changeId), () => ( /* @__PURE__ */ new Set()));
677
+ if (cell < 0) blockCells.set(block.changeId, null);
678
+ else blockCells.set(block.changeId, cells.add(cell));
679
+ }
638
680
  const change = add(
639
681
  `block:${block.changeId}`,
640
682
  "block",
@@ -657,6 +699,20 @@ function getTrackedChanges(source) {
657
699
  if (!isMarkChange(markType)) return;
658
700
  const attrs = changeAttributes(mark);
659
701
  if (!attrs.changeId) return;
702
+ const text = node.isText ? _nullishCoalesce(node.text, () => ( "")) : "";
703
+ const moveId = markType !== FORMAT_CHANGE_MARK_NAME ? attrs[MOVE_ID_ATTRIBUTE] : null;
704
+ if (moveId) {
705
+ const change2 = add(`move:${moveId}`, "move", { ...attrs, changeId: moveId }, pos, pos + node.nodeSize, text);
706
+ if (!change2.move) change2.move = { from: [], to: [], fromText: "", toText: "" };
707
+ const source2 = markType === DELETION_MARK_NAME;
708
+ const list = source2 ? change2.move.from : change2.move.to;
709
+ const last = list[list.length - 1];
710
+ if (last && last.to === pos) last.to = pos + node.nodeSize;
711
+ else list.push({ from: pos, to: pos + node.nodeSize });
712
+ if (source2) change2.move.fromText += text;
713
+ else change2.move.toText += text;
714
+ return;
715
+ }
660
716
  const type = markType === FORMAT_CHANGE_MARK_NAME ? "format" : markType;
661
717
  const change = add(
662
718
  `${type}:${attrs.changeId}`,
@@ -664,7 +720,7 @@ function getTrackedChanges(source) {
664
720
  attrs,
665
721
  pos,
666
722
  pos + node.nodeSize,
667
- node.isText ? _nullishCoalesce(node.text, () => ( "")) : ""
723
+ text
668
724
  );
669
725
  if (type === "format") {
670
726
  const summary = diffFormatting(_nullishCoalesce(mark.attrs.before, () => ( [])), _nullishCoalesce(mark.attrs.after, () => ( [])));
@@ -685,12 +741,19 @@ function getTrackedChanges(source) {
685
741
  case "format":
686
742
  change.description = describeFormatChange(change.format);
687
743
  break;
744
+ case "move": {
745
+ const move = change.move;
746
+ change.text = move.toText || move.fromText;
747
+ change.description = change.text ? `Moved "${truncate(change.text)}"` : "Moved content";
748
+ break;
749
+ }
688
750
  case "block": {
689
751
  const { previous, current, operation } = change.block;
690
752
  if (operation) {
691
753
  const count = _nullishCoalesce(blockCounts.get(change.id), () => ( 1));
692
754
  const verb = operation === "insert" ? "Inserted" : "Deleted";
693
- change.description = count > 1 ? `${verb} ${count} blocks` : `${verb} ${blockLabel(current.type, current.attrs)}`;
755
+ const cells = _optionalChain([blockCells, 'access', _17 => _17.get, 'call', _18 => _18(change.id), 'optionalAccess', _19 => _19.size]);
756
+ change.description = cells ? `${verb} ${cells === 1 ? "a table cell" : `${cells} table cells`}` : count > 1 ? `${verb} ${count} blocks` : `${verb} ${blockLabel(current.type, current.attrs)}`;
694
757
  } else {
695
758
  change.description = describeBlockChange(previous, current);
696
759
  }
@@ -712,15 +775,20 @@ function getTrackedChangeAt(state, pos = state.selection.from, changes = getTrac
712
775
  return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(inline.find((c) => c.ranges.some((r) => r.from < pos && pos < r.to)), () => ( inline.find((c) => c.ranges.some((r) => r.from <= pos && pos <= r.to)))), () => ( blocks.find((c) => c.ranges.some((r) => r.from < pos && pos < r.to)))), () => ( null));
713
776
  }
714
777
  function selectionRange(change) {
715
- return change.type === "block" ? [change.from + 1, change.to - 1] : [change.from, change.to];
778
+ if (change.type === "block") return [change.from + 1, change.to - 1];
779
+ if (change.type === "move" && change.move) {
780
+ const ranges = change.move.to.length ? change.move.to : change.move.from;
781
+ if (ranges.length) return [ranges[0].from, ranges[ranges.length - 1].to];
782
+ }
783
+ return [change.from, change.to];
716
784
  }
717
785
  function isTrackChangesEnabled(source) {
718
- const state = _nullishCoalesce(_optionalChain([source, 'optionalAccess', _15 => _15.state]), () => ( source));
786
+ const state = _nullishCoalesce(_optionalChain([source, 'optionalAccess', _20 => _20.state]), () => ( source));
719
787
  if (!state || typeof state.plugins === "undefined") return false;
720
- return _nullishCoalesce(_optionalChain([trackChangesPluginKey, 'access', _16 => _16.getState, 'call', _17 => _17(state), 'optionalAccess', _18 => _18.enabled]), () => ( false));
788
+ return _nullishCoalesce(_optionalChain([trackChangesPluginKey, 'access', _21 => _21.getState, 'call', _22 => _22(state), 'optionalAccess', _23 => _23.enabled]), () => ( false));
721
789
  }
722
790
  function getTrackChangesStore(editor) {
723
- return _nullishCoalesce(_optionalChain([editor, 'optionalAccess', _19 => _19.storage, 'optionalAccess', _20 => _20.trackChanges, 'optionalAccess', _21 => _21.store]), () => ( null));
791
+ return _nullishCoalesce(_optionalChain([editor, 'optionalAccess', _24 => _24.storage, 'optionalAccess', _25 => _25.trackChanges, 'optionalAccess', _26 => _26.store]), () => ( null));
724
792
  }
725
793
  function marksFromJSON(schema, marks) {
726
794
  const result = [];
@@ -781,7 +849,7 @@ function sinkItem(tr, contentPos) {
781
849
  const itemType = $pos.node(itemDepth).type;
782
850
  if (index === 0 || list.child(index - 1).type !== itemType) return false;
783
851
  const nodeBefore = list.child(index - 1);
784
- const nestedBefore = _optionalChain([nodeBefore, 'access', _22 => _22.lastChild, 'optionalAccess', _23 => _23.type]) === list.type;
852
+ const nestedBefore = _optionalChain([nodeBefore, 'access', _27 => _27.lastChild, 'optionalAccess', _28 => _28.type]) === list.type;
785
853
  const inner = _model.Fragment.from(nestedBefore ? itemType.create() : null);
786
854
  const slice = new (0, _model.Slice)(
787
855
  _model.Fragment.from(itemType.create(null, _model.Fragment.from(list.type.create(null, inner)))),
@@ -882,10 +950,10 @@ function restoreWrappers(tr, contentPos, wrappers) {
882
950
  const wrapper = tr.doc.nodeAt(start);
883
951
  if (!wrapper) return;
884
952
  const end = start + wrapper.nodeSize;
885
- if (_optionalChain([tr, 'access', _24 => _24.doc, 'access', _25 => _25.resolve, 'call', _26 => _26(end), 'access', _27 => _27.nodeAfter, 'optionalAccess', _28 => _28.type]) === wrapper.type && _transform.canJoin.call(void 0, tr.doc, end)) {
953
+ if (_optionalChain([tr, 'access', _29 => _29.doc, 'access', _30 => _30.resolve, 'call', _31 => _31(end), 'access', _32 => _32.nodeAfter, 'optionalAccess', _33 => _33.type]) === wrapper.type && _transform.canJoin.call(void 0, tr.doc, end)) {
886
954
  step(() => tr.join(end));
887
955
  }
888
- if (_optionalChain([tr, 'access', _29 => _29.doc, 'access', _30 => _30.resolve, 'call', _31 => _31(start), 'access', _32 => _32.nodeBefore, 'optionalAccess', _33 => _33.type]) === wrapper.type && _transform.canJoin.call(void 0, tr.doc, start)) {
956
+ if (_optionalChain([tr, 'access', _34 => _34.doc, 'access', _35 => _35.resolve, 'call', _36 => _36(start), 'access', _37 => _37.nodeBefore, 'optionalAccess', _38 => _38.type]) === wrapper.type && _transform.canJoin.call(void 0, tr.doc, start)) {
889
957
  step(() => tr.join(start));
890
958
  }
891
959
  return;
@@ -899,8 +967,8 @@ function removeBlocks(tr, ids, decision) {
899
967
  if (cached !== void 0) return cached;
900
968
  let result;
901
969
  if (node.isTextblock) {
902
- const record = _optionalChain([node, 'access', _34 => _34.attrs, 'optionalAccess', _35 => _35[BLOCK_CHANGE_ATTRIBUTE]]);
903
- result = !!_optionalChain([record, 'optionalAccess', _36 => _36.changeId]) && record.operation === removed && ids.has(record.changeId);
970
+ const record = _optionalChain([node, 'access', _39 => _39.attrs, 'optionalAccess', _40 => _40[BLOCK_CHANGE_ATTRIBUTE]]);
971
+ result = !!_optionalChain([record, 'optionalAccess', _41 => _41.changeId]) && record.operation === removed && ids.has(record.changeId);
904
972
  } else if (node.isLeaf || node.childCount === 0) {
905
973
  result = false;
906
974
  } else {
@@ -912,7 +980,7 @@ function removeBlocks(tr, ids, decision) {
912
980
  };
913
981
  const doc = tr.doc;
914
982
  if (removable(doc)) {
915
- const filler = _optionalChain([doc, 'access', _37 => _37.type, 'access', _38 => _38.contentMatch, 'access', _39 => _39.defaultType, 'optionalAccess', _40 => _40.createAndFill, 'call', _41 => _41()]);
983
+ const filler = _optionalChain([doc, 'access', _42 => _42.type, 'access', _43 => _43.contentMatch, 'access', _44 => _44.defaultType, 'optionalAccess', _45 => _45.createAndFill, 'call', _46 => _46()]);
916
984
  if (filler) tr.replaceWith(0, doc.content.size, filler);
917
985
  return;
918
986
  }
@@ -943,8 +1011,8 @@ function decideBlocks(tr, changes, decision) {
943
1011
  removeBlocks(tr, ids, decision);
944
1012
  const items = [];
945
1013
  tr.doc.descendants((node, pos) => {
946
- const record = _optionalChain([node, 'access', _42 => _42.attrs, 'optionalAccess', _43 => _43[BLOCK_CHANGE_ATTRIBUTE]]);
947
- if (node.isTextblock && _optionalChain([record, 'optionalAccess', _44 => _44.changeId]) && ids.has(record.changeId)) {
1014
+ const record = _optionalChain([node, 'access', _47 => _47.attrs, 'optionalAccess', _48 => _48[BLOCK_CHANGE_ATTRIBUTE]]);
1015
+ if (node.isTextblock && _optionalChain([record, 'optionalAccess', _49 => _49.changeId]) && ids.has(record.changeId)) {
948
1016
  items.push({ contentPos: pos + 1, record });
949
1017
  }
950
1018
  return !node.isTextblock;
@@ -982,12 +1050,36 @@ function decideBlocks(tr, changes, decision) {
982
1050
  }
983
1051
  });
984
1052
  }
1053
+ function deleteWholeBlock(tr, from, to) {
1054
+ const $from = tr.doc.resolve(from);
1055
+ const block = $from.parent;
1056
+ if ($from.depth !== 1 || !block.isTextblock || from !== $from.start() || to !== $from.end() || tr.doc.childCount < 2) {
1057
+ return false;
1058
+ }
1059
+ try {
1060
+ tr.delete($from.before(), $from.after());
1061
+ return true;
1062
+ } catch (e8) {
1063
+ return false;
1064
+ }
1065
+ }
985
1066
  function applyDecision(tr, changes, decision) {
986
1067
  const schema = tr.doc.type.schema;
987
1068
  const format = changes.filter((c) => c.type === "format");
988
1069
  if (format.length) decideFormat(tr, format, decision);
989
1070
  const deletions = [];
990
1071
  changes.forEach((change) => {
1072
+ if (change.type === "move" && change.move) {
1073
+ const accept = decision === "accept";
1074
+ const keepType = schema.marks[accept ? INSERTION_MARK_NAME : DELETION_MARK_NAME];
1075
+ (accept ? change.move.to : change.move.from).forEach(({ from, to }) => {
1076
+ if (keepType) tr.removeMark(from, to, keepType);
1077
+ });
1078
+ (accept ? change.move.from : change.move.to).forEach(
1079
+ ({ from, to }) => deletions.push({ from, to, wholeBlocks: true })
1080
+ );
1081
+ return;
1082
+ }
991
1083
  if (change.type !== "insertion" && change.type !== "deletion") return;
992
1084
  const markType = schema.marks[change.type];
993
1085
  if (!markType) return;
@@ -1000,8 +1092,11 @@ function applyDecision(tr, changes, decision) {
1000
1092
  }
1001
1093
  });
1002
1094
  });
1003
- deletions.sort((a, b) => b.from - a.from).forEach(({ from, to }) => {
1004
- tr.delete(tr.mapping.map(from), tr.mapping.map(to));
1095
+ deletions.sort((a, b) => b.from - a.from).forEach(({ from, to, wholeBlocks }) => {
1096
+ const start = tr.mapping.map(from);
1097
+ const end = tr.mapping.map(to);
1098
+ if (wholeBlocks && deleteWholeBlock(tr, start, end)) return;
1099
+ tr.delete(start, end);
1005
1100
  });
1006
1101
  const blocks = changes.filter((c) => c.type === "block");
1007
1102
  if (blocks.length) decideBlocks(tr, blocks, decision);
@@ -1036,7 +1131,7 @@ function acceptSlice(slice, schema) {
1036
1131
  if (insertion) marks = insertion.removeFromSet(marks);
1037
1132
  if (format) marks = format.removeFromSet(marks);
1038
1133
  children.push(marks === child.marks ? child : child.mark(marks));
1039
- } else if (_optionalChain([child, 'access', _45 => _45.attrs, 'optionalAccess', _46 => _46[BLOCK_CHANGE_ATTRIBUTE]])) {
1134
+ } else if (_optionalChain([child, 'access', _50 => _50.attrs, 'optionalAccess', _51 => _51[BLOCK_CHANGE_ATTRIBUTE]])) {
1040
1135
  children.push(
1041
1136
  child.type.create(
1042
1137
  { ...child.attrs, [BLOCK_CHANGE_ATTRIBUTE]: null },
@@ -1059,6 +1154,52 @@ function stripMarks(fragment) {
1059
1154
  });
1060
1155
  return _model.Fragment.fromArray(children);
1061
1156
  }
1157
+ var SENTENCE_END = /[.!?…]$/;
1158
+ var TRAILING_CLOSERS = /["'”’)]+$/;
1159
+ var TRAILING_SPACES = /[  ]+$/;
1160
+ function isMoveSized(text) {
1161
+ const trimmed = text.replace(TRAILING_SPACES, "");
1162
+ if (trimmed.includes("\n")) return true;
1163
+ const sentence = trimmed.replace(TRAILING_CLOSERS, "");
1164
+ return SENTENCE_END.test(sentence) && sentence.trim().split(/\s+/).length >= 2;
1165
+ }
1166
+ var normalizeMoveText = (text) => text.replace(/\s+/g, "");
1167
+ function deletedText(slice, ctx) {
1168
+ let text = "";
1169
+ let blocks = 0;
1170
+ slice.content.descendants((node) => {
1171
+ if (node.isTextblock) {
1172
+ if (blocks++ > 0) text += "\n";
1173
+ return true;
1174
+ }
1175
+ if (!node.isText) return true;
1176
+ const insertion = ctx.insertion.isInSet(node.marks);
1177
+ if (insertion && insertion.attrs.authorId === ctx.author.id) return false;
1178
+ if (ctx.deletion.isInSet(node.marks)) return false;
1179
+ text += _nullishCoalesce(node.text, () => ( ""));
1180
+ return false;
1181
+ });
1182
+ return text;
1183
+ }
1184
+ var rangeText = (doc, from, to) => doc.textBetween(from, to, "\n", "");
1185
+ function linkMoveSource(tr, pending, ctx) {
1186
+ const segments = [];
1187
+ tr.doc.descendants((node, pos) => {
1188
+ if (!node.isInline) return true;
1189
+ const mark = ctx.deletion.isInSet(node.marks);
1190
+ if (mark && mark.attrs.changeId === pending.id && !mark.attrs[MOVE_ID_ATTRIBUTE]) {
1191
+ segments.push({ from: pos, to: pos + node.nodeSize, mark });
1192
+ }
1193
+ return false;
1194
+ });
1195
+ if (segments.length === 0) return false;
1196
+ const text = segments.map((s) => rangeText(tr.doc, s.from, s.to)).join("");
1197
+ if (normalizeMoveText(text) !== pending.text) return false;
1198
+ segments.forEach(
1199
+ ({ from, to, mark }) => tr.addMark(from, to, ctx.deletion.create({ ...mark.attrs, [MOVE_ID_ATTRIBUTE]: pending.id }))
1200
+ );
1201
+ return true;
1202
+ }
1062
1203
  function newAttributes(ctx) {
1063
1204
  return {
1064
1205
  changeId: ctx.generateId(),
@@ -1081,7 +1222,7 @@ function adjacentAttributes(doc, from, to, type, ctx) {
1081
1222
  const candidates = [doc.resolve(from).nodeBefore, doc.resolve(to).nodeAfter];
1082
1223
  for (const node of candidates) {
1083
1224
  const mark = node && type.isInSet(node.marks);
1084
- if (mark && mark.attrs.authorId === ctx.author.id && mark.attrs.changeId) {
1225
+ if (mark && mark.attrs.authorId === ctx.author.id && mark.attrs.changeId && !mark.attrs[MOVE_ID_ATTRIBUTE]) {
1085
1226
  return changeAttributes(mark);
1086
1227
  }
1087
1228
  }
@@ -1210,8 +1351,8 @@ function trackBlocks(tr, pending, ctx) {
1210
1351
  if (!node.isTextblock || $pos.parentOffset !== 0 || $pos.depth === 0) return;
1211
1352
  if (!node.type.spec.attrs || !(BLOCK_CHANGE_ATTRIBUTE in node.type.spec.attrs)) return;
1212
1353
  const pos = $pos.before();
1213
- if (_optionalChain([existing, 'optionalAccess', _47 => _47.operation]) || _optionalChain([node, 'access', _48 => _48.attrs, 'access', _49 => _49[BLOCK_CHANGE_ATTRIBUTE], 'optionalAccess', _50 => _50.operation])) return;
1214
- const original = _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _51 => _51.previous]), () => ( previous));
1354
+ if (_optionalChain([existing, 'optionalAccess', _52 => _52.operation]) || _optionalChain([node, 'access', _53 => _53.attrs, 'access', _54 => _54[BLOCK_CHANGE_ATTRIBUTE], 'optionalAccess', _55 => _55.operation])) return;
1355
+ const original = _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _56 => _56.previous]), () => ( previous));
1215
1356
  const current = blockSnapshot(tr.doc, pos);
1216
1357
  if (sameBlock(original, current, ctx.ignoredAttributes)) {
1217
1358
  if (node.attrs[BLOCK_CHANGE_ATTRIBUTE]) {
@@ -1243,7 +1384,7 @@ function collectBlockChanges(step, docBefore, docAfter, rest, pending, ctx) {
1243
1384
  };
1244
1385
  if (step instanceof _transform.AttrStep) {
1245
1386
  const node = docBefore.nodeAt(step.pos);
1246
- if (_optionalChain([node, 'optionalAccess', _52 => _52.isTextblock]) && step.attr !== BLOCK_CHANGE_ATTRIBUTE && !ctx.ignoredAttributes.has(step.attr)) {
1387
+ if (_optionalChain([node, 'optionalAccess', _57 => _57.isTextblock]) && step.attr !== BLOCK_CHANGE_ATTRIBUTE && !ctx.ignoredAttributes.has(step.attr)) {
1247
1388
  record(step.pos, step.pos);
1248
1389
  }
1249
1390
  return;
@@ -1263,11 +1404,78 @@ function collectBlockChanges(step, docBefore, docAfter, rest, pending, ctx) {
1263
1404
  return false;
1264
1405
  });
1265
1406
  }
1407
+ var TABLE_ROLES = /* @__PURE__ */ new Set(["table", "row", "cell", "header_cell"]);
1408
+ var isTableStructure = (node) => TABLE_ROLES.has(node.type.spec.tableRole);
1409
+ var supportsBlockChange = (node) => !!node.type.spec.attrs && BLOCK_CHANGE_ATTRIBUTE in node.type.spec.attrs;
1410
+ function isWholeTableSlice(slice) {
1411
+ if (slice.openStart !== 0 || slice.openEnd !== 0 || slice.content.childCount === 0) return false;
1412
+ let whole = true;
1413
+ slice.content.forEach((child) => {
1414
+ if (!isTableStructure(child)) whole = false;
1415
+ });
1416
+ return whole;
1417
+ }
1418
+ function canMarkTableBlocks(slice) {
1419
+ let ok = true;
1420
+ let any = false;
1421
+ slice.content.descendants((node) => {
1422
+ if (!ok) return false;
1423
+ if (node.isTextblock) {
1424
+ any = true;
1425
+ if (!supportsBlockChange(node)) ok = false;
1426
+ return false;
1427
+ }
1428
+ return true;
1429
+ });
1430
+ return ok && any;
1431
+ }
1432
+ function isOwnTableInsertion(slice, ctx) {
1433
+ let own = true;
1434
+ slice.content.descendants((node) => {
1435
+ if (!own) return false;
1436
+ if (node.isTextblock) {
1437
+ const record = node.attrs[BLOCK_CHANGE_ATTRIBUTE];
1438
+ if (_optionalChain([record, 'optionalAccess', _58 => _58.operation]) !== "insert" || record.authorId !== ctx.author.id) own = false;
1439
+ return false;
1440
+ }
1441
+ return true;
1442
+ });
1443
+ return own;
1444
+ }
1445
+ function collectInsertedTableNodes(slice, from, rest, out) {
1446
+ slice.content.descendants((node, offset) => {
1447
+ if (!isTableStructure(node)) return !node.isTextblock;
1448
+ const pos = from - slice.openStart + offset;
1449
+ if (pos < from) return true;
1450
+ const start = rest.map(pos, 1);
1451
+ const end = rest.map(pos + node.nodeSize, -1);
1452
+ if (end - start === node.nodeSize) out.push({ from: start, to: end });
1453
+ return false;
1454
+ });
1455
+ }
1456
+ function markTableBlocks(tr, from, to, operation, attrs) {
1457
+ const positions = [];
1458
+ tr.doc.nodesBetween(from, to, (node, pos) => {
1459
+ if (!node.isTextblock) return true;
1460
+ if (pos >= from && pos + node.nodeSize <= to && supportsBlockChange(node)) positions.push(pos);
1461
+ return false;
1462
+ });
1463
+ positions.forEach((pos) => {
1464
+ const record = {
1465
+ ...baseAttributes(attrs),
1466
+ previous: blockSnapshot(tr.doc, pos),
1467
+ operation
1468
+ };
1469
+ tr.setNodeAttribute(pos, BLOCK_CHANGE_ATTRIBUTE, record);
1470
+ });
1471
+ return positions.length > 0;
1472
+ }
1266
1473
  function trackTransactions(transactions, oldState, newState, ctx) {
1267
1474
  const maps = [];
1268
1475
  transactions.forEach((t) => maps.push(...t.mapping.maps));
1269
1476
  const inserted = [];
1270
1477
  const restores = [];
1478
+ const tableInserts = [];
1271
1479
  const formatRanges = [];
1272
1480
  const blocks = /* @__PURE__ */ new Map();
1273
1481
  let mapIndex = 0;
@@ -1304,6 +1512,9 @@ function trackTransactions(transactions, oldState, newState, ctx) {
1304
1512
  return;
1305
1513
  }
1306
1514
  }
1515
+ if (ctx.trackBlocks && slice.size > 0) {
1516
+ collectInsertedTableNodes(slice, from, rest, tableInserts);
1517
+ }
1307
1518
  if (slice.size > 0 && hasInlineContent(slice.content)) {
1308
1519
  const start = rest.map(from, 1);
1309
1520
  const end = rest.map(from + slice.size, -1);
@@ -1311,7 +1522,8 @@ function trackTransactions(transactions, oldState, newState, ctx) {
1311
1522
  }
1312
1523
  if (to > from) {
1313
1524
  const deleted = docBefore.slice(from, to);
1314
- if (!hasInlineContent(deleted.content)) return;
1525
+ const wholeTable = ctx.trackBlocks && isWholeTableSlice(deleted);
1526
+ if (!wholeTable && !hasInlineContent(deleted.content)) return;
1315
1527
  const $from = docBefore.resolve(from);
1316
1528
  const before = i === 0 ? t.before : null;
1317
1529
  const sel = before === oldState.doc ? oldState.selection : null;
@@ -1320,13 +1532,14 @@ function trackTransactions(transactions, oldState, newState, ctx) {
1320
1532
  slice: deleted,
1321
1533
  parentType: $from.node(Math.max(0, $from.depth - deleted.openStart)).type,
1322
1534
  pureDelete: slice.size === 0,
1535
+ wholeTable,
1323
1536
  backspace: single && slice.size === 0 && !!sel && sel.empty && sel.from === to
1324
1537
  });
1325
1538
  }
1326
1539
  });
1327
1540
  mapIndex += t.steps.length;
1328
1541
  });
1329
- if (inserted.length === 0 && restores.length === 0 && formatRanges.length === 0 && blocks.size === 0) {
1542
+ if (inserted.length === 0 && tableInserts.length === 0 && restores.length === 0 && formatRanges.length === 0 && blocks.size === 0) {
1330
1543
  return null;
1331
1544
  }
1332
1545
  const tr = newState.tr;
@@ -1338,24 +1551,84 @@ function trackTransactions(transactions, oldState, newState, ctx) {
1338
1551
  if (blocks.size) {
1339
1552
  changed = trackBlocks(tr, blocks, ctx) || changed;
1340
1553
  }
1554
+ const moves = ctx.moves;
1555
+ let insertAttrs = null;
1556
+ let deleteAttrs = null;
1557
+ const moveAttrs = (id) => ({
1558
+ changeId: id,
1559
+ authorId: ctx.author.id,
1560
+ authorName: ctx.author.name,
1561
+ authorColor: _nullishCoalesce(ctx.author.color, () => ( null)),
1562
+ createdAt: ctx.now(),
1563
+ [MOVE_ID_ATTRIBUTE]: id
1564
+ });
1565
+ if (moves && inserted.length) {
1566
+ const insertedText = normalizeMoveText(
1567
+ inserted.map((r) => rangeText(tr.doc, r.from, r.to)).join("")
1568
+ );
1569
+ const pending = moves.pending;
1570
+ if (moves.event === "paste" && pending && pending.authorId === ctx.author.id && insertedText === pending.text && linkMoveSource(tr, pending, ctx)) {
1571
+ insertAttrs = moveAttrs(pending.id);
1572
+ } else if (moves.event === "drop" && restores.length) {
1573
+ const raw = restores.map((r) => deletedText(r.slice, ctx)).join("\n");
1574
+ if (insertedText && normalizeMoveText(raw) === insertedText && moves.isMove(raw)) {
1575
+ insertAttrs = deleteAttrs = moveAttrs(ctx.generateId());
1576
+ }
1577
+ }
1578
+ }
1579
+ if (_optionalChain([moves, 'optionalAccess', _59 => _59.event]) === "cut" && restores.length) {
1580
+ deleteAttrs = newAttributes(ctx);
1581
+ const raw = restores.map((r) => deletedText(r.slice, ctx)).join("\n");
1582
+ if (normalizeMoveText(raw) && moves.isMove(raw)) {
1583
+ moves.cut = { id: deleteAttrs.changeId, text: normalizeMoveText(raw), authorId: ctx.author.id };
1584
+ }
1585
+ }
1341
1586
  inserted.forEach(({ from, to }) => {
1342
1587
  tr.removeMark(from, to, ctx.deletion);
1343
1588
  tr.removeMark(from, to, ctx.insertion);
1344
1589
  if (ctx.format) tr.removeMark(from, to, ctx.format);
1345
- const attrs = _nullishCoalesce(adjacentAttributes(tr.doc, from, to, ctx.insertion, ctx), () => ( newAttributes(ctx)));
1590
+ const attrs = _nullishCoalesce(_nullishCoalesce(insertAttrs, () => ( adjacentAttributes(tr.doc, from, to, ctx.insertion, ctx))), () => ( newAttributes(ctx)));
1346
1591
  tr.addMark(from, to, ctx.insertion.create(attrs));
1347
1592
  changed = true;
1348
1593
  });
1594
+ if (insertAttrs) changed = true;
1595
+ if (tableInserts.length) {
1596
+ const attrs = newAttributes(ctx);
1597
+ tableInserts.forEach(({ from, to }) => {
1598
+ const start = tr.mapping.map(from, 1);
1599
+ const end = tr.mapping.map(to, -1);
1600
+ const node = tr.doc.nodeAt(start);
1601
+ if (end <= start || !node || !isTableStructure(node) || node.nodeSize !== end - start) return;
1602
+ tr.removeMark(start, end, ctx.insertion);
1603
+ changed = markTableBlocks(tr, start, end, "insert", attrs) || changed;
1604
+ });
1605
+ }
1606
+ let tableDeleteAttrs = null;
1349
1607
  let cursor = null;
1350
1608
  restores.sort((a, b) => b.pos - a.pos).forEach((restore) => {
1351
1609
  const pos = tr.mapping.map(restore.pos, -1);
1352
- const attrs = _nullishCoalesce(adjacentAttributes(tr.doc, pos, pos, ctx.deletion, ctx), () => ( newAttributes(ctx)));
1610
+ const attrs = _nullishCoalesce(_nullishCoalesce(deleteAttrs, () => ( adjacentAttributes(tr.doc, pos, pos, ctx.deletion, ctx))), () => ( newAttributes(ctx)));
1611
+ if (restore.wholeTable && canMarkTableBlocks(restore.slice)) {
1612
+ if (isOwnTableInsertion(restore.slice, ctx)) return;
1613
+ tableDeleteAttrs = _nullishCoalesce(_nullishCoalesce(tableDeleteAttrs, () => ( deleteAttrs)), () => ( newAttributes(ctx)));
1614
+ const sizeBefore2 = tr.doc.content.size;
1615
+ try {
1616
+ tr.replace(pos, pos, restore.slice);
1617
+ } catch (e9) {
1618
+ return;
1619
+ }
1620
+ const end = pos + (tr.doc.content.size - sizeBefore2);
1621
+ markTableBlocks(tr, pos, end, "delete", tableDeleteAttrs);
1622
+ changed = true;
1623
+ return;
1624
+ }
1625
+ if (!hasInlineContent(restore.slice.content)) return;
1353
1626
  const marked = markDeletedSlice(restore.slice, restore.parentType, attrs, ctx);
1354
1627
  if (!marked || !marked.hasContent) return;
1355
1628
  const sizeBefore = tr.doc.content.size;
1356
1629
  try {
1357
1630
  tr.replace(pos, pos, marked.slice);
1358
- } catch (e8) {
1631
+ } catch (e10) {
1359
1632
  return;
1360
1633
  }
1361
1634
  changed = true;
@@ -1367,7 +1640,7 @@ function trackTransactions(transactions, oldState, newState, ctx) {
1367
1640
  if (cursor !== null) {
1368
1641
  try {
1369
1642
  tr.setSelection(_state.TextSelection.create(tr.doc, cursor));
1370
- } catch (e9) {
1643
+ } catch (e11) {
1371
1644
  }
1372
1645
  }
1373
1646
  tr.setMeta(TRACK_CHANGES_SKIP_META, true);
@@ -1377,10 +1650,10 @@ function buildSnapshot(state, author) {
1377
1650
  const plugin = trackChangesPluginKey.getState(state);
1378
1651
  const changes = getTrackedChanges(state.doc);
1379
1652
  return {
1380
- enabled: _nullishCoalesce(_optionalChain([plugin, 'optionalAccess', _53 => _53.enabled]), () => ( false)),
1381
- author: _nullishCoalesce(_optionalChain([plugin, 'optionalAccess', _54 => _54.author]), () => ( author)),
1653
+ enabled: _nullishCoalesce(_optionalChain([plugin, 'optionalAccess', _60 => _60.enabled]), () => ( false)),
1654
+ author: _nullishCoalesce(_optionalChain([plugin, 'optionalAccess', _61 => _61.author]), () => ( author)),
1382
1655
  changes,
1383
- currentChangeId: _nullishCoalesce(_optionalChain([getTrackedChangeAt, 'call', _55 => _55(state, state.selection.from, changes), 'optionalAccess', _56 => _56.id]), () => ( null))
1656
+ currentChangeId: _nullishCoalesce(_optionalChain([getTrackedChangeAt, 'call', _62 => _62(state, state.selection.from, changes), 'optionalAccess', _63 => _63.id]), () => ( null))
1384
1657
  };
1385
1658
  }
1386
1659
  function allowTrackingInCodeBlocks(schema) {
@@ -1415,7 +1688,10 @@ var TrackChanges = _core.Extension.create({
1415
1688
  trackCodeBlocks: true,
1416
1689
  blockTypes: ["paragraph", "heading", "codeBlock"],
1417
1690
  ignoredMarks: [],
1418
- ignoredBlockAttributes: ["id"]
1691
+ ignoredBlockAttributes: ["id"],
1692
+ trackMoves: true,
1693
+ isMove: isMoveSized,
1694
+ moveHTMLAttributes: {}
1419
1695
  };
1420
1696
  },
1421
1697
  addStorage() {
@@ -1429,13 +1705,13 @@ var TrackChanges = _core.Extension.create({
1429
1705
  };
1430
1706
  },
1431
1707
  addGlobalAttributes() {
1432
- if (_optionalChain([this, 'access', _57 => _57.options, 'optionalAccess', _58 => _58.trackBlocks]) === false) return [];
1433
- const blockClass = _nullishCoalesce(_optionalChain([this, 'access', _59 => _59.options, 'optionalAccess', _60 => _60.blockChangeClass]), () => ( ""));
1434
- const insertedClass = _nullishCoalesce(_optionalChain([this, 'access', _61 => _61.options, 'optionalAccess', _62 => _62.blockInsertedClass]), () => ( ""));
1435
- const deletedClass = _nullishCoalesce(_optionalChain([this, 'access', _63 => _63.options, 'optionalAccess', _64 => _64.blockDeletedClass]), () => ( ""));
1708
+ if (_optionalChain([this, 'access', _64 => _64.options, 'optionalAccess', _65 => _65.trackBlocks]) === false) return [];
1709
+ const blockClass = _nullishCoalesce(_optionalChain([this, 'access', _66 => _66.options, 'optionalAccess', _67 => _67.blockChangeClass]), () => ( ""));
1710
+ const insertedClass = _nullishCoalesce(_optionalChain([this, 'access', _68 => _68.options, 'optionalAccess', _69 => _69.blockInsertedClass]), () => ( ""));
1711
+ const deletedClass = _nullishCoalesce(_optionalChain([this, 'access', _70 => _70.options, 'optionalAccess', _71 => _71.blockDeletedClass]), () => ( ""));
1436
1712
  return [
1437
1713
  {
1438
- types: _nullishCoalesce(_optionalChain([this, 'access', _65 => _65.options, 'optionalAccess', _66 => _66.blockTypes]), () => ( ["paragraph", "heading", "codeBlock"])),
1714
+ types: _nullishCoalesce(_optionalChain([this, 'access', _72 => _72.options, 'optionalAccess', _73 => _73.blockTypes]), () => ( ["paragraph", "heading", "codeBlock"])),
1439
1715
  attributes: {
1440
1716
  [BLOCK_CHANGE_ATTRIBUTE]: {
1441
1717
  default: null,
@@ -1459,12 +1735,21 @@ var TrackChanges = _core.Extension.create({
1459
1735
  ];
1460
1736
  },
1461
1737
  addExtensions() {
1462
- const insertionAttrs = _nullishCoalesce(_optionalChain([this, 'access', _67 => _67.options, 'optionalAccess', _68 => _68.insertionHTMLAttributes]), () => ( {}));
1463
- const deletionAttrs = _nullishCoalesce(_optionalChain([this, 'access', _69 => _69.options, 'optionalAccess', _70 => _70.deletionHTMLAttributes]), () => ( {}));
1464
- const formatAttrs = _nullishCoalesce(_optionalChain([this, 'access', _71 => _71.options, 'optionalAccess', _72 => _72.formatChangeHTMLAttributes]), () => ( {}));
1738
+ const insertionAttrs = _nullishCoalesce(_optionalChain([this, 'access', _74 => _74.options, 'optionalAccess', _75 => _75.insertionHTMLAttributes]), () => ( {}));
1739
+ const deletionAttrs = _nullishCoalesce(_optionalChain([this, 'access', _76 => _76.options, 'optionalAccess', _77 => _77.deletionHTMLAttributes]), () => ( {}));
1740
+ const formatAttrs = _nullishCoalesce(_optionalChain([this, 'access', _78 => _78.options, 'optionalAccess', _79 => _79.formatChangeHTMLAttributes]), () => ( {}));
1741
+ const moveAttrs = _nullishCoalesce(_optionalChain([this, 'access', _80 => _80.options, 'optionalAccess', _81 => _81.moveHTMLAttributes]), () => ( {}));
1742
+ const markOptions = (attrs) => ({
1743
+ ...Object.keys(attrs).length ? { HTMLAttributes: attrs } : {},
1744
+ ...Object.keys(moveAttrs).length ? { moveHTMLAttributes: moveAttrs } : {}
1745
+ });
1746
+ const configured = (mark, attrs) => {
1747
+ const options = markOptions(attrs);
1748
+ return Object.keys(options).length ? mark.configure(options) : mark;
1749
+ };
1465
1750
  return [
1466
- Object.keys(insertionAttrs).length ? TrackedInsertion.configure({ HTMLAttributes: insertionAttrs }) : TrackedInsertion,
1467
- Object.keys(deletionAttrs).length ? TrackedDeletion.configure({ HTMLAttributes: deletionAttrs }) : TrackedDeletion,
1751
+ configured(TrackedInsertion, insertionAttrs),
1752
+ configured(TrackedDeletion, deletionAttrs),
1468
1753
  Object.keys(formatAttrs).length ? TrackedFormatChange.configure({ HTMLAttributes: formatAttrs }) : TrackedFormatChange
1469
1754
  ];
1470
1755
  },
@@ -1472,9 +1757,9 @@ var TrackChanges = _core.Extension.create({
1472
1757
  if (this.options.trackCodeBlocks) allowTrackingInCodeBlocks(this.editor.schema);
1473
1758
  },
1474
1759
  addCommands() {
1475
- const decide = (decision, id) => ({ state, tr, dispatch }) => {
1760
+ const decide = (decision, id, onlyMoves = false) => ({ state, tr, dispatch }) => {
1476
1761
  const all = getTrackedChanges(state.doc);
1477
- const changes = id === null ? all : all.filter((c) => c.id === id);
1762
+ const changes = id === null ? all : all.filter((c) => c.id === id && (!onlyMoves || c.type === "move"));
1478
1763
  if (changes.length === 0) return false;
1479
1764
  if (dispatch) {
1480
1765
  applyDecision(tr, changes, decision);
@@ -1511,11 +1796,22 @@ var TrackChanges = _core.Extension.create({
1511
1796
  return true;
1512
1797
  },
1513
1798
  acceptChange: (id) => decide("accept", id),
1799
+ acceptMove: (id) => decide("accept", id, true),
1800
+ rejectMove: (id) => decide("reject", id, true),
1514
1801
  rejectChange: (id) => decide("reject", id),
1515
1802
  acceptAllChanges: () => decide("accept", null),
1516
1803
  rejectAllChanges: () => decide("reject", null),
1517
1804
  selectNextChange: () => select(1),
1518
- selectPreviousChange: () => select(-1)
1805
+ selectPreviousChange: () => select(-1),
1806
+ selectChange: (id) => ({ state, tr, dispatch }) => {
1807
+ const change = getTrackedChanges(state.doc).find((c) => c.id === id);
1808
+ if (!change) return false;
1809
+ if (dispatch) {
1810
+ const [anchor, head] = selectionRange(change);
1811
+ tr.setSelection(_state.TextSelection.create(tr.doc, anchor, head)).scrollIntoView();
1812
+ }
1813
+ return true;
1814
+ }
1519
1815
  };
1520
1816
  },
1521
1817
  addProseMirrorPlugins() {
@@ -1526,6 +1822,8 @@ var TrackChanges = _core.Extension.create({
1526
1822
  let editorView = null;
1527
1823
  let pending = null;
1528
1824
  let flushTimer = null;
1825
+ let pendingMove = null;
1826
+ const isMove = _nullishCoalesce(options.isMove, () => ( isMoveSized));
1529
1827
  const scheduleFlush = () => {
1530
1828
  if (flushTimer) clearTimeout(flushTimer);
1531
1829
  flushTimer = setTimeout(() => {
@@ -1555,9 +1853,12 @@ var TrackChanges = _core.Extension.create({
1555
1853
  },
1556
1854
  appendTransaction: (transactions, oldState, newState) => {
1557
1855
  const plugin = trackChangesPluginKey.getState(oldState);
1558
- const tracking = !!_optionalChain([plugin, 'optionalAccess', _73 => _73.enabled]);
1559
- if (!tracking && !pending) return null;
1560
- if (_optionalChain([editorView, 'optionalAccess', _74 => _74.composing]) && transactions.some((t) => t.docChanged)) {
1856
+ const tracking = !!_optionalChain([plugin, 'optionalAccess', _82 => _82.enabled]);
1857
+ if (!tracking && !pending) {
1858
+ if (transactions.some((t) => t.docChanged)) pendingMove = null;
1859
+ return null;
1860
+ }
1861
+ if (_optionalChain([editorView, 'optionalAccess', _83 => _83.composing]) && transactions.some((t) => t.docChanged)) {
1561
1862
  if (tracking) {
1562
1863
  if (!pending) pending = { oldState, transactions: [] };
1563
1864
  pending.transactions.push(...transactions);
@@ -1572,8 +1873,18 @@ var TrackChanges = _core.Extension.create({
1572
1873
  pending = null;
1573
1874
  }
1574
1875
  if (!tracking && trs === transactions) return null;
1575
- const author = _nullishCoalesce(_optionalChain([plugin, 'optionalAccess', _75 => _75.author]), () => ( options.author));
1576
- return trackTransactions(trs, fromState, newState, {
1876
+ const author = _nullishCoalesce(_optionalChain([plugin, 'optionalAccess', _84 => _84.author]), () => ( options.author));
1877
+ const userTransactions = trs.filter((t) => !shouldSkip(t));
1878
+ let moves;
1879
+ if (userTransactions.length) {
1880
+ const uiEvent = userTransactions.length === 1 ? userTransactions[0].getMeta("uiEvent") : null;
1881
+ const event = uiEvent === "cut" || uiEvent === "paste" || uiEvent === "drop" ? uiEvent : null;
1882
+ if (options.trackMoves !== false) {
1883
+ moves = { event, pending: event === "paste" ? pendingMove : null, isMove };
1884
+ }
1885
+ pendingMove = null;
1886
+ }
1887
+ const result = trackTransactions(trs, fromState, newState, {
1577
1888
  author,
1578
1889
  now: options.now,
1579
1890
  generateId: options.generateId,
@@ -1582,8 +1893,11 @@ var TrackChanges = _core.Extension.create({
1582
1893
  format: options.trackFormatting !== false ? newState.schema.marks[FORMAT_CHANGE_MARK_NAME] : void 0,
1583
1894
  trackBlocks: options.trackBlocks !== false,
1584
1895
  ignoredMarks,
1585
- ignoredAttributes
1896
+ ignoredAttributes,
1897
+ moves
1586
1898
  });
1899
+ if (_optionalChain([moves, 'optionalAccess', _85 => _85.cut])) pendingMove = moves.cut;
1900
+ return result;
1587
1901
  },
1588
1902
  props: {
1589
1903
  transformPasted: (slice, view) => acceptSlice(slice, view.state.schema),
@@ -1639,5 +1953,10 @@ var TrackChanges = _core.Extension.create({
1639
1953
 
1640
1954
 
1641
1955
 
1642
- exports.createReviewId = createReviewId; exports.CommentStore = CommentStore; exports.createCommentStore = createCommentStore; exports.formatReviewTime = formatReviewTime; exports.INSERTION_MARK_NAME = INSERTION_MARK_NAME; exports.DELETION_MARK_NAME = DELETION_MARK_NAME; exports.FORMAT_CHANGE_MARK_NAME = FORMAT_CHANGE_MARK_NAME; exports.BLOCK_CHANGE_ATTRIBUTE = BLOCK_CHANGE_ATTRIBUTE; exports.TRACK_CHANGES_SKIP_META = TRACK_CHANGES_SKIP_META; exports.TrackChangesStore = TrackChangesStore; exports.trackChangesPluginKey = trackChangesPluginKey; exports.TrackedInsertion = TrackedInsertion; exports.TrackedDeletion = TrackedDeletion; exports.TrackedFormatChange = TrackedFormatChange; exports.describeFormatChange = describeFormatChange; exports.describeBlockChange = describeBlockChange; exports.getTrackedChanges = getTrackedChanges; exports.getTrackedChangeAt = getTrackedChangeAt; exports.isTrackChangesEnabled = isTrackChangesEnabled; exports.getTrackChangesStore = getTrackChangesStore; exports.resolveTrackedChanges = resolveTrackedChanges; exports.TrackChanges = TrackChanges;
1643
- //# sourceMappingURL=chunk-D27YFC46.cjs.map
1956
+
1957
+
1958
+
1959
+
1960
+
1961
+ exports.createReviewId = createReviewId; exports.CommentStore = CommentStore; exports.createCommentStore = createCommentStore; exports.formatReviewTime = formatReviewTime; exports.INSERTION_MARK_NAME = INSERTION_MARK_NAME; exports.DELETION_MARK_NAME = DELETION_MARK_NAME; exports.FORMAT_CHANGE_MARK_NAME = FORMAT_CHANGE_MARK_NAME; exports.BLOCK_CHANGE_ATTRIBUTE = BLOCK_CHANGE_ATTRIBUTE; exports.MOVE_ID_ATTRIBUTE = MOVE_ID_ATTRIBUTE; exports.TRACK_CHANGES_SKIP_META = TRACK_CHANGES_SKIP_META; exports.TrackChangesStore = TrackChangesStore; exports.trackChangesPluginKey = trackChangesPluginKey; exports.MOVE_TO_CLASS = MOVE_TO_CLASS; exports.MOVE_FROM_CLASS = MOVE_FROM_CLASS; exports.TrackedInsertion = TrackedInsertion; exports.TrackedDeletion = TrackedDeletion; exports.TrackedFormatChange = TrackedFormatChange; exports.describeFormatChange = describeFormatChange; exports.describeBlockChange = describeBlockChange; exports.trackedChangeLabel = trackedChangeLabel; exports.getTrackedChanges = getTrackedChanges; exports.getTrackedChangeAt = getTrackedChangeAt; exports.isTrackChangesEnabled = isTrackChangesEnabled; exports.getTrackChangesStore = getTrackChangesStore; exports.resolveTrackedChanges = resolveTrackedChanges; exports.isMoveSized = isMoveSized; exports.TrackChanges = TrackChanges;
1962
+ //# sourceMappingURL=chunk-IFHKKVXH.cjs.map