@portabletext/editor 1.25.0 → 1.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +131 -36
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs +8 -8
  4. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  5. package/lib/_chunks-cjs/{selector.is-active-style.cjs → selector.is-at-the-start-of-block.cjs} +29 -3
  6. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -0
  7. package/lib/_chunks-cjs/util.is-empty-text-block.cjs +2 -2
  8. package/lib/_chunks-cjs/util.is-empty-text-block.cjs.map +1 -1
  9. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +46 -0
  10. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs.map +1 -0
  11. package/lib/_chunks-cjs/util.reverse-selection.cjs +0 -16
  12. package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -1
  13. package/lib/_chunks-es/behavior.core.js +99 -4
  14. package/lib/_chunks-es/behavior.core.js.map +1 -1
  15. package/lib/_chunks-es/selector.get-text-before.js +2 -2
  16. package/lib/_chunks-es/{selector.is-active-style.js → selector.is-at-the-start-of-block.js} +29 -2
  17. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -0
  18. package/lib/_chunks-es/util.is-empty-text-block.js +1 -1
  19. package/lib/_chunks-es/util.is-equal-selection-points.js +47 -0
  20. package/lib/_chunks-es/util.is-equal-selection-points.js.map +1 -0
  21. package/lib/_chunks-es/util.reverse-selection.js +0 -16
  22. package/lib/_chunks-es/util.reverse-selection.js.map +1 -1
  23. package/lib/behaviors/index.cjs +27 -27
  24. package/lib/behaviors/index.cjs.map +1 -1
  25. package/lib/behaviors/index.d.cts +413 -0
  26. package/lib/behaviors/index.d.ts +413 -0
  27. package/lib/behaviors/index.js +1 -1
  28. package/lib/index.cjs +184 -116
  29. package/lib/index.cjs.map +1 -1
  30. package/lib/index.d.cts +1653 -222
  31. package/lib/index.d.ts +1653 -222
  32. package/lib/index.js +180 -112
  33. package/lib/index.js.map +1 -1
  34. package/lib/selectors/index.cjs +25 -23
  35. package/lib/selectors/index.cjs.map +1 -1
  36. package/lib/selectors/index.d.cts +16 -0
  37. package/lib/selectors/index.d.ts +16 -0
  38. package/lib/selectors/index.js +3 -1
  39. package/lib/utils/index.cjs +5 -3
  40. package/lib/utils/index.cjs.map +1 -1
  41. package/lib/utils/index.d.cts +19 -0
  42. package/lib/utils/index.d.ts +19 -0
  43. package/lib/utils/index.js +4 -2
  44. package/package.json +6 -6
  45. package/src/behavior-actions/behavior.action-utils.insert-block.ts +3 -3
  46. package/src/behavior-actions/behavior.action.block.set.ts +23 -0
  47. package/src/behavior-actions/behavior.action.block.unset.ts +21 -0
  48. package/src/behavior-actions/behavior.action.insert-break.ts +2 -69
  49. package/src/behavior-actions/behavior.action.insert.block.ts +33 -0
  50. package/src/behavior-actions/behavior.actions.ts +28 -9
  51. package/src/behaviors/behavior.core.insert-break.ts +122 -0
  52. package/src/behaviors/behavior.core.ts +6 -2
  53. package/src/behaviors/behavior.types.ts +16 -1
  54. package/src/converters/converter.json.ts +4 -4
  55. package/src/converters/converter.portable-text.deserialize.test.ts +1 -1
  56. package/src/converters/converter.portable-text.ts +9 -5
  57. package/src/converters/converter.text-html.deserialize.test.ts +1 -1
  58. package/src/converters/converter.text-html.serialize.test.ts +1 -1
  59. package/src/converters/converter.text-html.ts +4 -4
  60. package/src/converters/converter.text-plain.test.ts +1 -1
  61. package/src/converters/converter.text-plain.ts +3 -3
  62. package/src/converters/{converter.ts → converter.types.ts} +6 -0
  63. package/src/editor/__tests__/handleClick.test.tsx +2 -2
  64. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +1 -1
  65. package/src/editor/create-editor.ts +4 -1
  66. package/src/editor/editor-machine.ts +8 -2
  67. package/src/editor/editor-snapshot.ts +1 -1
  68. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +12 -12
  69. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +29 -36
  70. package/src/editor/plugins/create-with-event-listeners.ts +3 -0
  71. package/src/editor/plugins/createWithObjectKeys.ts +18 -2
  72. package/src/editor/plugins/createWithPortableTextMarkModel.ts +3 -0
  73. package/src/internal-utils/parse-blocks.ts +36 -6
  74. package/src/selectors/index.ts +2 -0
  75. package/src/selectors/selector.is-at-the-end-of-block.ts +22 -0
  76. package/src/selectors/selector.is-at-the-start-of-block.ts +25 -0
  77. package/src/selectors/selector.is-selection-collapsed.ts +6 -2
  78. package/src/utils/index.ts +2 -0
  79. package/src/utils/util.get-block-end-point.ts +34 -0
  80. package/src/utils/util.is-equal-selection-points.ts +13 -0
  81. package/lib/_chunks-cjs/selector.is-active-style.cjs.map +0 -1
  82. package/lib/_chunks-cjs/util.is-keyed-segment.cjs +0 -6
  83. package/lib/_chunks-cjs/util.is-keyed-segment.cjs.map +0 -1
  84. package/lib/_chunks-es/selector.is-active-style.js.map +0 -1
  85. package/lib/_chunks-es/util.is-keyed-segment.js +0 -7
  86. package/lib/_chunks-es/util.is-keyed-segment.js.map +0 -1
  87. /package/src/converters/{converters.ts → converters.core.ts} +0 -0
package/lib/index.js CHANGED
@@ -23,7 +23,7 @@ import { toHTML } from "@portabletext/to-html";
23
23
  import get from "lodash/get.js";
24
24
  import isUndefined from "lodash/isUndefined.js";
25
25
  import omitBy from "lodash/omitBy.js";
26
- import { createGuards } from "./_chunks-es/selector.is-active-style.js";
26
+ import { createGuards } from "./_chunks-es/selector.is-at-the-start-of-block.js";
27
27
  import { blockOffsetToSpanSelectionPoint } from "./_chunks-es/util.is-empty-text-block.js";
28
28
  import { coreBehaviors, isCustomBehaviorEvent, isHotkey } from "./_chunks-es/behavior.core.js";
29
29
  import getRandomValues from "get-random-values-esm";
@@ -2523,6 +2523,7 @@ function _temp(s) {
2523
2523
  }
2524
2524
  Synchronizer.displayName = "Synchronizer";
2525
2525
  const converterJson = {
2526
+ mimeType: "application/json",
2526
2527
  serialize: ({
2527
2528
  context,
2528
2529
  event
@@ -2558,8 +2559,7 @@ const converterJson = {
2558
2559
  mimeType: "application/json",
2559
2560
  reason: "No application/x-portable-text Converter found"
2560
2561
  };
2561
- },
2562
- mimeType: "application/json"
2562
+ }
2563
2563
  };
2564
2564
  function isTypedObject(object) {
2565
2565
  return isRecord(object) && typeof object._type == "string";
@@ -2569,18 +2569,34 @@ function isRecord(value) {
2569
2569
  }
2570
2570
  function parseBlock({
2571
2571
  context,
2572
- block
2572
+ block,
2573
+ options
2573
2574
  }) {
2574
2575
  if (!isTypedObject(block) || block._type !== context.schema.block.name && !context.schema.blockObjects.some((blockObject) => blockObject.name === block._type))
2575
2576
  return;
2576
- if (!isPortableTextTextBlock(block))
2577
+ if (block._type !== context.schema.block.name) {
2578
+ const _key = options.refreshKeys ? context.keyGenerator() : typeof block._key == "string" ? block._key : context.keyGenerator();
2577
2579
  return {
2578
2580
  ...block,
2579
- _key: context.keyGenerator()
2581
+ _key
2582
+ };
2583
+ }
2584
+ if (!isPortableTextTextBlock(block))
2585
+ return {
2586
+ _type: context.schema.block.name,
2587
+ _key: options.refreshKeys ? context.keyGenerator() : typeof block._key == "string" ? block._key : context.keyGenerator(),
2588
+ children: [{
2589
+ _key: context.keyGenerator(),
2590
+ _type: context.schema.span.name,
2591
+ text: "",
2592
+ marks: []
2593
+ }],
2594
+ markDefs: [],
2595
+ style: context.schema.styles[0].value
2580
2596
  };
2581
2597
  const markDefKeyMap = /* @__PURE__ */ new Map(), markDefs = (block.markDefs ?? []).flatMap((markDef) => {
2582
2598
  if (context.schema.annotations.some((annotation) => annotation.name === markDef._type)) {
2583
- const _key = context.keyGenerator();
2599
+ const _key = options.refreshKeys ? context.keyGenerator() : markDef._key;
2584
2600
  return markDefKeyMap.set(markDef._key, _key), [{
2585
2601
  ...markDef,
2586
2602
  _key
@@ -2595,17 +2611,17 @@ function parseBlock({
2595
2611
  if (!isPortableTextSpan$1(child))
2596
2612
  return [{
2597
2613
  ...child,
2598
- _key: context.keyGenerator()
2614
+ _key: options.refreshKeys ? context.keyGenerator() : child._key
2599
2615
  }];
2600
2616
  const marks = (child.marks ?? []).flatMap((mark) => markDefKeyMap.has(mark) ? [markDefKeyMap.get(mark)] : context.schema.decorators.some((decorator) => decorator.value === mark) ? [mark] : []);
2601
2617
  return [{
2602
2618
  ...child,
2603
- _key: context.keyGenerator(),
2619
+ _key: options.refreshKeys ? context.keyGenerator() : child._key,
2604
2620
  marks
2605
2621
  }];
2606
2622
  }), parsedBlock = {
2607
2623
  ...block,
2608
- _key: context.keyGenerator(),
2624
+ _key: options.refreshKeys ? context.keyGenerator() : block._key,
2609
2625
  children: children.length > 0 ? children : [{
2610
2626
  _key: context.keyGenerator(),
2611
2627
  _type: context.schema.span.name,
@@ -2621,6 +2637,7 @@ function parseBlock({
2621
2637
  return context.schema.lists.find((list) => list.value === block.listItem) || (delete parsedBlock.listItem, delete parsedBlock.level), parsedBlock;
2622
2638
  }
2623
2639
  const converterPortableText = {
2640
+ mimeType: "application/x-portable-text",
2624
2641
  serialize: ({
2625
2642
  context,
2626
2643
  event
@@ -2657,7 +2674,10 @@ const converterPortableText = {
2657
2674
  const parsedBlocks = blocks.flatMap((block) => {
2658
2675
  const parsedBlock = parseBlock({
2659
2676
  context,
2660
- block
2677
+ block,
2678
+ options: {
2679
+ refreshKeys: !0
2680
+ }
2661
2681
  });
2662
2682
  return parsedBlock ? [parsedBlock] : [];
2663
2683
  });
@@ -2670,9 +2690,9 @@ const converterPortableText = {
2670
2690
  data: parsedBlocks,
2671
2691
  mimeType: "application/x-portable-text"
2672
2692
  };
2673
- },
2674
- mimeType: "application/x-portable-text"
2693
+ }
2675
2694
  }, converterTextHtml = {
2695
+ mimeType: "text/html",
2676
2696
  serialize: ({
2677
2697
  context,
2678
2698
  event
@@ -2717,8 +2737,7 @@ const converterPortableText = {
2717
2737
  unstable_whitespaceOnPasteMode: context.schema.block.options.unstable_whitespaceOnPasteMode
2718
2738
  }),
2719
2739
  mimeType: "text/html"
2720
- }),
2721
- mimeType: "text/html"
2740
+ })
2722
2741
  }, converterTextPlain = {
2723
2742
  mimeType: "text/plain",
2724
2743
  serialize: ({
@@ -3013,6 +3032,8 @@ function createWithEventListeners(editorActor, subscriptions) {
3013
3032
  case "annotation.add":
3014
3033
  case "annotation.remove":
3015
3034
  case "annotation.toggle":
3035
+ case "block.set":
3036
+ case "block.unset":
3016
3037
  case "blur":
3017
3038
  case "data transfer.set":
3018
3039
  case "decorator.add":
@@ -3025,6 +3046,7 @@ function createWithEventListeners(editorActor, subscriptions) {
3025
3046
  case "deserialization.failure":
3026
3047
  case "deserialization.success":
3027
3048
  case "focus":
3049
+ case "insert.block":
3028
3050
  case "insert.block object":
3029
3051
  case "insert.inline object":
3030
3052
  case "insert.span":
@@ -3226,21 +3248,23 @@ function createWithObjectKeys(editorActor, schemaTypes) {
3226
3248
  return;
3227
3249
  }
3228
3250
  if (operation.type === "split_node") {
3251
+ const existingKeys = [...Node.descendants(editor)].map(([node]) => node._key);
3229
3252
  apply2({
3230
3253
  ...operation,
3231
3254
  properties: {
3232
3255
  ...operation.properties,
3233
- _key: editorActor.getSnapshot().context.keyGenerator()
3256
+ _key: operation.properties._key === void 0 || existingKeys.includes(operation.properties._key) ? editorActor.getSnapshot().context.keyGenerator() : operation.properties._key
3234
3257
  }
3235
3258
  });
3236
3259
  return;
3237
3260
  }
3238
3261
  if (operation.type === "insert_node" && !Editor.isEditor(operation.node)) {
3262
+ const existingKeys = [...Node.descendants(editor)].map(([node]) => node._key);
3239
3263
  apply2({
3240
3264
  ...operation,
3241
3265
  node: {
3242
3266
  ...operation.node,
3243
- _key: editorActor.getSnapshot().context.keyGenerator()
3267
+ _key: operation.node._key === void 0 || existingKeys.includes(operation.node._key) ? editorActor.getSnapshot().context.keyGenerator() : operation.node._key
3244
3268
  }
3245
3269
  });
3246
3270
  return;
@@ -3928,6 +3952,7 @@ function createWithPortableTextMarkModel(editorActor, types) {
3928
3952
  if (atTheEndOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsEnding.includes(mark))) {
3929
3953
  Transforms.insertNodes(editor, {
3930
3954
  ...op.node,
3955
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3931
3956
  marks: op.node.marks?.filter((mark) => !annotationsEnding.includes(mark)) ?? []
3932
3957
  });
3933
3958
  return;
@@ -3936,6 +3961,7 @@ function createWithPortableTextMarkModel(editorActor, types) {
3936
3961
  if (atTheStartOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsStarting.includes(mark))) {
3937
3962
  Transforms.insertNodes(editor, {
3938
3963
  ...op.node,
3964
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3939
3965
  marks: op.node.marks?.filter((mark) => !annotationsStarting.includes(mark)) ?? []
3940
3966
  });
3941
3967
  return;
@@ -3944,6 +3970,7 @@ function createWithPortableTextMarkModel(editorActor, types) {
3944
3970
  if (nextSpanDecorators.length > 0 && atTheEndOfAnnotation && !atTheStartOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.length === 0) {
3945
3971
  Transforms.insertNodes(editor, {
3946
3972
  ...op.node,
3973
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3947
3974
  marks: nextSpanDecorators
3948
3975
  });
3949
3976
  return;
@@ -5074,10 +5101,9 @@ function insertBlock({
5074
5101
  });
5075
5102
  } else placement === "before" ? Transforms.insertNodes(editor, block, {
5076
5103
  at: focusBlockPath
5077
- }) : Editor.insertNode(editor, block);
5078
- focusBlock && isEqualToEmptyEditor([focusBlock], schema) && Transforms.removeNodes(editor, {
5104
+ }) : (Editor.insertNode(editor, block), focusBlock && isEqualToEmptyEditor([focusBlock], schema) && Transforms.removeNodes(editor, {
5079
5105
  at: focusBlockPath
5080
- });
5106
+ }));
5081
5107
  } else {
5082
5108
  const lastBlock = Array.from(Editor.nodes(editor, {
5083
5109
  match: (n) => !Editor.isEditor(n),
@@ -5089,7 +5115,47 @@ function insertBlock({
5089
5115
  });
5090
5116
  }
5091
5117
  }
5092
- const dataTransferSetActionImplementation = ({
5118
+ const blockSetBehaviorActionImplementation = ({
5119
+ action
5120
+ }) => {
5121
+ const location = toSlateRange({
5122
+ anchor: {
5123
+ path: action.at,
5124
+ offset: 0
5125
+ },
5126
+ focus: {
5127
+ path: action.at,
5128
+ offset: 0
5129
+ }
5130
+ }, action.editor);
5131
+ if (!location)
5132
+ return;
5133
+ const {
5134
+ at,
5135
+ editor,
5136
+ type,
5137
+ ...payload
5138
+ } = action;
5139
+ Transforms.setNodes(action.editor, payload, {
5140
+ at: location
5141
+ });
5142
+ }, blockUnsetBehaviorActionImplementation = ({
5143
+ action
5144
+ }) => {
5145
+ const location = toSlateRange({
5146
+ anchor: {
5147
+ path: action.at,
5148
+ offset: 0
5149
+ },
5150
+ focus: {
5151
+ path: action.at,
5152
+ offset: 0
5153
+ }
5154
+ }, action.editor);
5155
+ location && Transforms.unsetNodes(action.editor, action.props, {
5156
+ at: location
5157
+ });
5158
+ }, dataTransferSetActionImplementation = ({
5093
5159
  action
5094
5160
  }) => {
5095
5161
  action.dataTransfer.setData(action.mimeType, action.data);
@@ -5146,96 +5212,54 @@ const dataTransferSetActionImplementation = ({
5146
5212
  const keyGenerator = context.keyGenerator, schema = context.schema, editor = action.editor;
5147
5213
  if (!editor.selection)
5148
5214
  return;
5149
- const [focusSpan] = Array.from(Editor.nodes(editor, {
5150
- mode: "lowest",
5151
- at: editor.selection.focus,
5152
- match: (n) => editor.isTextSpan(n),
5153
- voids: !1
5154
- }))[0] ?? [void 0], focusDecorators = focusSpan?.marks?.filter((mark) => schema.decorators.some((decorator) => decorator.value === mark)) ?? [], focusAnnotations = focusSpan?.marks?.filter((mark) => !schema.decorators.some((decorator) => decorator.value === mark)) ?? [], anchorBlockPath = editor.selection.anchor.path.slice(0, 1), focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
5155
- if (editor.isTextBlock(focusBlock)) {
5156
- const [start, end] = Range.edges(editor.selection), lastFocusBlockChild = focusBlock.children[focusBlock.children.length - 1], atTheEndOfBlock = isEqual(start, {
5157
- path: [...focusBlockPath, focusBlock.children.length - 1],
5158
- offset: editor.isTextSpan(lastFocusBlockChild) ? lastFocusBlockChild.text.length : 0
5159
- }), atTheStartOfBlock = isEqual(end, {
5160
- path: [...focusBlockPath, 0],
5161
- offset: 0
5162
- });
5163
- if (atTheEndOfBlock && Range.isCollapsed(editor.selection)) {
5164
- Editor.insertNode(editor, editor.pteCreateTextBlock({
5165
- decorators: [],
5166
- listItem: focusBlock.listItem,
5167
- level: focusBlock.level
5168
- }));
5169
- return;
5170
- }
5171
- if (atTheStartOfBlock && Range.isCollapsed(editor.selection)) {
5172
- Editor.insertNode(editor, editor.pteCreateTextBlock({
5173
- decorators: focusAnnotations.length === 0 ? focusDecorators : [],
5174
- listItem: focusBlock.listItem,
5175
- level: focusBlock.level
5176
- }));
5177
- const [nextBlockPath] = Path.next(focusBlockPath);
5178
- Transforms.select(editor, {
5215
+ const anchorBlockPath = editor.selection.anchor.path.slice(0, 1), focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
5216
+ if (editor.isTextBlock(focusBlock) && anchorBlockPath[0] === focusBlockPath[0]) {
5217
+ Editor.withoutNormalizing(editor, () => {
5218
+ if (!editor.selection)
5219
+ return;
5220
+ Transforms.splitNodes(editor, {
5221
+ at: editor.selection
5222
+ });
5223
+ const [nextNode, nextNodePath] = Editor.node(editor, Path.next(focusBlockPath), {
5224
+ depth: 1
5225
+ });
5226
+ if (Transforms.setSelection(editor, {
5179
5227
  anchor: {
5180
- path: [nextBlockPath, 0],
5228
+ path: [...nextNodePath, 0],
5181
5229
  offset: 0
5182
5230
  },
5183
5231
  focus: {
5184
- path: [nextBlockPath, 0],
5232
+ path: [...nextNodePath, 0],
5185
5233
  offset: 0
5186
5234
  }
5187
- });
5188
- return;
5189
- }
5190
- const selectionAcrossBlocks = anchorBlockPath[0] !== focusBlockPath[0];
5191
- if (!atTheStartOfBlock && !atTheEndOfBlock && !selectionAcrossBlocks) {
5192
- Editor.withoutNormalizing(editor, () => {
5193
- if (!editor.selection)
5194
- return;
5195
- Transforms.splitNodes(editor, {
5196
- at: editor.selection
5197
- });
5198
- const [nextNode, nextNodePath] = Editor.node(editor, Path.next(focusBlockPath), {
5199
- depth: 1
5200
- });
5201
- if (Transforms.setSelection(editor, {
5202
- anchor: {
5203
- path: [...nextNodePath, 0],
5204
- offset: 0
5205
- },
5206
- focus: {
5207
- path: [...nextNodePath, 0],
5208
- offset: 0
5209
- }
5210
- }), editor.isTextBlock(nextNode) && nextNode.markDefs && nextNode.markDefs.length > 0) {
5211
- const newMarkDefKeys = /* @__PURE__ */ new Map(), prevNodeSpans = Array.from(Node.children(editor, focusBlockPath)).map((entry) => entry[0]).filter((node) => editor.isTextSpan(node)), children = Node.children(editor, nextNodePath);
5212
- for (const [child, childPath] of children) {
5213
- if (!editor.isTextSpan(child))
5214
- continue;
5215
- const marks = child.marks ?? [];
5216
- for (const mark of marks)
5217
- schema.decorators.some((decorator) => decorator.value === mark) || prevNodeSpans.some((prevNodeSpan) => prevNodeSpan.marks?.includes(mark)) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
5218
- const newMarks = marks.map((mark) => newMarkDefKeys.get(mark) ?? mark);
5219
- isEqual(marks, newMarks) || Transforms.setNodes(editor, {
5220
- marks: newMarks
5221
- }, {
5222
- at: childPath
5223
- });
5224
- }
5225
- const newMarkDefs = nextNode.markDefs.map((markDef) => ({
5226
- ...markDef,
5227
- _key: newMarkDefKeys.get(markDef._key) ?? markDef._key
5228
- }));
5229
- isEqual(nextNode.markDefs, newMarkDefs) || Transforms.setNodes(editor, {
5230
- markDefs: newMarkDefs
5235
+ }), editor.isTextBlock(nextNode) && nextNode.markDefs && nextNode.markDefs.length > 0) {
5236
+ const newMarkDefKeys = /* @__PURE__ */ new Map(), prevNodeSpans = Array.from(Node.children(editor, focusBlockPath)).map((entry) => entry[0]).filter((node) => editor.isTextSpan(node)), children = Node.children(editor, nextNodePath);
5237
+ for (const [child, childPath] of children) {
5238
+ if (!editor.isTextSpan(child))
5239
+ continue;
5240
+ const marks = child.marks ?? [];
5241
+ for (const mark of marks)
5242
+ schema.decorators.some((decorator) => decorator.value === mark) || prevNodeSpans.some((prevNodeSpan) => prevNodeSpan.marks?.includes(mark)) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
5243
+ const newMarks = marks.map((mark) => newMarkDefKeys.get(mark) ?? mark);
5244
+ isEqual(marks, newMarks) || Transforms.setNodes(editor, {
5245
+ marks: newMarks
5231
5246
  }, {
5232
- at: nextNodePath,
5233
- match: (node) => editor.isTextBlock(node)
5247
+ at: childPath
5234
5248
  });
5235
5249
  }
5236
- }), editor.onChange();
5237
- return;
5238
- }
5250
+ const newMarkDefs = nextNode.markDefs.map((markDef) => ({
5251
+ ...markDef,
5252
+ _key: newMarkDefKeys.get(markDef._key) ?? markDef._key
5253
+ }));
5254
+ isEqual(nextNode.markDefs, newMarkDefs) || Transforms.setNodes(editor, {
5255
+ markDefs: newMarkDefs
5256
+ }, {
5257
+ at: nextNodePath,
5258
+ match: (node) => editor.isTextBlock(node)
5259
+ });
5260
+ }
5261
+ }), editor.onChange();
5262
+ return;
5239
5263
  }
5240
5264
  Transforms.splitNodes(editor, {
5241
5265
  always: !0
@@ -5316,6 +5340,30 @@ const dataTransferSetActionImplementation = ({
5316
5340
  text: action.text,
5317
5341
  marks: [...annotations?.map((annotation) => annotation._key) ?? [], ...action.decorators ?? []]
5318
5342
  });
5343
+ }, insertBlockActionImplementation = ({
5344
+ context,
5345
+ action
5346
+ }) => {
5347
+ const parsedBlock = parseBlock({
5348
+ block: action.block,
5349
+ context,
5350
+ options: {
5351
+ refreshKeys: !1
5352
+ }
5353
+ });
5354
+ if (!parsedBlock)
5355
+ throw new Error(`Failed to parse block ${JSON.stringify(action.block)}`);
5356
+ const fragment = toSlateValue([parsedBlock], {
5357
+ schemaTypes: context.schema
5358
+ })[0];
5359
+ if (!fragment)
5360
+ throw new Error(`Failed to convert block to Slate fragment ${JSON.stringify(parsedBlock)}`);
5361
+ insertBlock({
5362
+ block: fragment,
5363
+ placement: action.placement,
5364
+ editor: action.editor,
5365
+ schema: context.schema
5366
+ });
5319
5367
  }, textBlockSetActionImplementation = ({
5320
5368
  action
5321
5369
  }) => {
@@ -5362,6 +5410,8 @@ const dataTransferSetActionImplementation = ({
5362
5410
  "annotation.add": addAnnotationActionImplementation,
5363
5411
  "annotation.remove": removeAnnotationActionImplementation,
5364
5412
  "annotation.toggle": toggleAnnotationActionImplementation,
5413
+ "block.set": blockSetBehaviorActionImplementation,
5414
+ "block.unset": blockUnsetBehaviorActionImplementation,
5365
5415
  blur: ({
5366
5416
  action
5367
5417
  }) => {
@@ -5452,6 +5502,7 @@ const dataTransferSetActionImplementation = ({
5452
5502
  }
5453
5503
  });
5454
5504
  },
5505
+ "insert.block": insertBlockActionImplementation,
5455
5506
  "insert.blocks": insertBlocksActionImplementation,
5456
5507
  "insert.block object": insertBlockObjectActionImplementation,
5457
5508
  "insert.break": insertBreakActionImplementation,
@@ -5601,13 +5652,6 @@ function performAction({
5601
5652
  });
5602
5653
  break;
5603
5654
  }
5604
- case "select": {
5605
- behaviorActionImplementations.select({
5606
- context,
5607
- action
5608
- });
5609
- break;
5610
- }
5611
5655
  default:
5612
5656
  performDefaultAction({
5613
5657
  context,
@@ -5641,6 +5685,20 @@ function performDefaultAction({
5641
5685
  });
5642
5686
  break;
5643
5687
  }
5688
+ case "block.set": {
5689
+ behaviorActionImplementations["block.set"]({
5690
+ context,
5691
+ action
5692
+ });
5693
+ break;
5694
+ }
5695
+ case "block.unset": {
5696
+ behaviorActionImplementations["block.unset"]({
5697
+ context,
5698
+ action
5699
+ });
5700
+ break;
5701
+ }
5644
5702
  case "blur": {
5645
5703
  behaviorActionImplementations.blur({
5646
5704
  context,
@@ -5725,6 +5783,13 @@ function performDefaultAction({
5725
5783
  });
5726
5784
  break;
5727
5785
  }
5786
+ case "insert.block": {
5787
+ behaviorActionImplementations["insert.block"]({
5788
+ context,
5789
+ action
5790
+ });
5791
+ break;
5792
+ }
5728
5793
  case "insert.blocks": {
5729
5794
  behaviorActionImplementations["insert.blocks"]({
5730
5795
  context,
@@ -5886,13 +5951,11 @@ function performDefaultAction({
5886
5951
  });
5887
5952
  break;
5888
5953
  }
5889
- case "text block.unset": {
5954
+ default:
5890
5955
  behaviorActionImplementations["text block.unset"]({
5891
5956
  context,
5892
5957
  action
5893
5958
  });
5894
- break;
5895
- }
5896
5959
  }
5897
5960
  }
5898
5961
  function getActiveDecorators({
@@ -6273,6 +6336,11 @@ const editorMachine = setup({
6273
6336
  event
6274
6337
  }) => event)
6275
6338
  },
6339
+ "block.*": {
6340
+ actions: emit(({
6341
+ event
6342
+ }) => event)
6343
+ },
6276
6344
  blur: {
6277
6345
  actions: emit(({
6278
6346
  event