@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
@@ -1,6 +1,6 @@
1
1
  import { defineBehavior, isHotkey } from "../_chunks-es/behavior.core.js";
2
2
  import { coreBehavior, coreBehaviors, raise } from "../_chunks-es/behavior.core.js";
3
- import { getFirstBlock, getSelectedBlocks, getLastBlock, getFocusTextBlock, isSelectionCollapsed, getFocusSpan, getFocusBlock } from "../_chunks-es/selector.is-active-style.js";
3
+ import { getFirstBlock, getSelectedBlocks, getLastBlock, getFocusTextBlock, isSelectionCollapsed, getFocusSpan, getFocusBlock } from "../_chunks-es/selector.is-at-the-start-of-block.js";
4
4
  import { createActor, setup, assign, assertEvent } from "xstate";
5
5
  import { getBlockTextBefore } from "../_chunks-es/selector.get-text-before.js";
6
6
  import { isPortableTextTextBlock } from "@sanity/types";
package/lib/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var schema = require("@sanity/schema"), types = require("@sanity/types"), startCase = require("lodash.startcase"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), noop = require("lodash/noop.js"), React = require("react"), slate = require("slate"), slateReact = require("slate-react"), debug$j = require("debug"), reactCompilerRuntime = require("react-compiler-runtime"), uniq = require("lodash/uniq.js"), rxjs = require("rxjs"), useEffectEvent = require("use-effect-event"), xstate = require("xstate"), patches = require("@portabletext/patches"), flatten = require("lodash/flatten.js"), isPlainObject = require("lodash/isPlainObject.js"), util_sliceBlocks = require("./_chunks-cjs/util.slice-blocks.cjs"), blockTools = require("@portabletext/block-tools"), toHtml = require("@portabletext/to-html"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), selector_isActiveStyle = require("./_chunks-cjs/selector.is-active-style.cjs"), util_isEmptyTextBlock = require("./_chunks-cjs/util.is-empty-text-block.cjs"), behavior_core = require("./_chunks-cjs/behavior.core.cjs"), getRandomValues = require("get-random-values-esm");
3
+ var schema = require("@sanity/schema"), types = require("@sanity/types"), startCase = require("lodash.startcase"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), noop = require("lodash/noop.js"), React = require("react"), slate = require("slate"), slateReact = require("slate-react"), debug$j = require("debug"), reactCompilerRuntime = require("react-compiler-runtime"), uniq = require("lodash/uniq.js"), rxjs = require("rxjs"), useEffectEvent = require("use-effect-event"), xstate = require("xstate"), patches = require("@portabletext/patches"), flatten = require("lodash/flatten.js"), isPlainObject = require("lodash/isPlainObject.js"), util_sliceBlocks = require("./_chunks-cjs/util.slice-blocks.cjs"), blockTools = require("@portabletext/block-tools"), toHtml = require("@portabletext/to-html"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), selector_isAtTheStartOfBlock = require("./_chunks-cjs/selector.is-at-the-start-of-block.cjs"), util_isEmptyTextBlock = require("./_chunks-cjs/util.is-empty-text-block.cjs"), behavior_core = require("./_chunks-cjs/behavior.core.cjs"), getRandomValues = require("get-random-values-esm");
4
4
  function _interopDefaultCompat(e) {
5
5
  return e && typeof e == "object" && "default" in e ? e : { default: e };
6
6
  }
@@ -2501,6 +2501,7 @@ function _temp(s) {
2501
2501
  }
2502
2502
  Synchronizer.displayName = "Synchronizer";
2503
2503
  const converterJson = {
2504
+ mimeType: "application/json",
2504
2505
  serialize: ({
2505
2506
  context,
2506
2507
  event
@@ -2536,8 +2537,7 @@ const converterJson = {
2536
2537
  mimeType: "application/json",
2537
2538
  reason: "No application/x-portable-text Converter found"
2538
2539
  };
2539
- },
2540
- mimeType: "application/json"
2540
+ }
2541
2541
  };
2542
2542
  function isTypedObject(object) {
2543
2543
  return isRecord(object) && typeof object._type == "string";
@@ -2547,18 +2547,34 @@ function isRecord(value) {
2547
2547
  }
2548
2548
  function parseBlock({
2549
2549
  context,
2550
- block
2550
+ block,
2551
+ options
2551
2552
  }) {
2552
2553
  if (!isTypedObject(block) || block._type !== context.schema.block.name && !context.schema.blockObjects.some((blockObject) => blockObject.name === block._type))
2553
2554
  return;
2554
- if (!types.isPortableTextTextBlock(block))
2555
+ if (block._type !== context.schema.block.name) {
2556
+ const _key = options.refreshKeys ? context.keyGenerator() : typeof block._key == "string" ? block._key : context.keyGenerator();
2555
2557
  return {
2556
2558
  ...block,
2557
- _key: context.keyGenerator()
2559
+ _key
2560
+ };
2561
+ }
2562
+ if (!types.isPortableTextTextBlock(block))
2563
+ return {
2564
+ _type: context.schema.block.name,
2565
+ _key: options.refreshKeys ? context.keyGenerator() : typeof block._key == "string" ? block._key : context.keyGenerator(),
2566
+ children: [{
2567
+ _key: context.keyGenerator(),
2568
+ _type: context.schema.span.name,
2569
+ text: "",
2570
+ marks: []
2571
+ }],
2572
+ markDefs: [],
2573
+ style: context.schema.styles[0].value
2558
2574
  };
2559
2575
  const markDefKeyMap = /* @__PURE__ */ new Map(), markDefs = (block.markDefs ?? []).flatMap((markDef) => {
2560
2576
  if (context.schema.annotations.some((annotation) => annotation.name === markDef._type)) {
2561
- const _key = context.keyGenerator();
2577
+ const _key = options.refreshKeys ? context.keyGenerator() : markDef._key;
2562
2578
  return markDefKeyMap.set(markDef._key, _key), [{
2563
2579
  ...markDef,
2564
2580
  _key
@@ -2573,17 +2589,17 @@ function parseBlock({
2573
2589
  if (!types.isPortableTextSpan(child))
2574
2590
  return [{
2575
2591
  ...child,
2576
- _key: context.keyGenerator()
2592
+ _key: options.refreshKeys ? context.keyGenerator() : child._key
2577
2593
  }];
2578
2594
  const marks = (child.marks ?? []).flatMap((mark) => markDefKeyMap.has(mark) ? [markDefKeyMap.get(mark)] : context.schema.decorators.some((decorator) => decorator.value === mark) ? [mark] : []);
2579
2595
  return [{
2580
2596
  ...child,
2581
- _key: context.keyGenerator(),
2597
+ _key: options.refreshKeys ? context.keyGenerator() : child._key,
2582
2598
  marks
2583
2599
  }];
2584
2600
  }), parsedBlock = {
2585
2601
  ...block,
2586
- _key: context.keyGenerator(),
2602
+ _key: options.refreshKeys ? context.keyGenerator() : block._key,
2587
2603
  children: children.length > 0 ? children : [{
2588
2604
  _key: context.keyGenerator(),
2589
2605
  _type: context.schema.span.name,
@@ -2599,6 +2615,7 @@ function parseBlock({
2599
2615
  return context.schema.lists.find((list) => list.value === block.listItem) || (delete parsedBlock.listItem, delete parsedBlock.level), parsedBlock;
2600
2616
  }
2601
2617
  const converterPortableText = {
2618
+ mimeType: "application/x-portable-text",
2602
2619
  serialize: ({
2603
2620
  context,
2604
2621
  event
@@ -2635,7 +2652,10 @@ const converterPortableText = {
2635
2652
  const parsedBlocks = blocks.flatMap((block) => {
2636
2653
  const parsedBlock = parseBlock({
2637
2654
  context,
2638
- block
2655
+ block,
2656
+ options: {
2657
+ refreshKeys: !0
2658
+ }
2639
2659
  });
2640
2660
  return parsedBlock ? [parsedBlock] : [];
2641
2661
  });
@@ -2648,9 +2668,9 @@ const converterPortableText = {
2648
2668
  data: parsedBlocks,
2649
2669
  mimeType: "application/x-portable-text"
2650
2670
  };
2651
- },
2652
- mimeType: "application/x-portable-text"
2671
+ }
2653
2672
  }, converterTextHtml = {
2673
+ mimeType: "text/html",
2654
2674
  serialize: ({
2655
2675
  context,
2656
2676
  event
@@ -2695,8 +2715,7 @@ const converterPortableText = {
2695
2715
  unstable_whitespaceOnPasteMode: context.schema.block.options.unstable_whitespaceOnPasteMode
2696
2716
  }),
2697
2717
  mimeType: "text/html"
2698
- }),
2699
- mimeType: "text/html"
2718
+ })
2700
2719
  }, converterTextPlain = {
2701
2720
  mimeType: "text/plain",
2702
2721
  serialize: ({
@@ -2991,6 +3010,8 @@ function createWithEventListeners(editorActor, subscriptions) {
2991
3010
  case "annotation.add":
2992
3011
  case "annotation.remove":
2993
3012
  case "annotation.toggle":
3013
+ case "block.set":
3014
+ case "block.unset":
2994
3015
  case "blur":
2995
3016
  case "data transfer.set":
2996
3017
  case "decorator.add":
@@ -3003,6 +3024,7 @@ function createWithEventListeners(editorActor, subscriptions) {
3003
3024
  case "deserialization.failure":
3004
3025
  case "deserialization.success":
3005
3026
  case "focus":
3027
+ case "insert.block":
3006
3028
  case "insert.block object":
3007
3029
  case "insert.inline object":
3008
3030
  case "insert.span":
@@ -3204,21 +3226,23 @@ function createWithObjectKeys(editorActor, schemaTypes) {
3204
3226
  return;
3205
3227
  }
3206
3228
  if (operation.type === "split_node") {
3229
+ const existingKeys = [...slate.Node.descendants(editor)].map(([node]) => node._key);
3207
3230
  apply2({
3208
3231
  ...operation,
3209
3232
  properties: {
3210
3233
  ...operation.properties,
3211
- _key: editorActor.getSnapshot().context.keyGenerator()
3234
+ _key: operation.properties._key === void 0 || existingKeys.includes(operation.properties._key) ? editorActor.getSnapshot().context.keyGenerator() : operation.properties._key
3212
3235
  }
3213
3236
  });
3214
3237
  return;
3215
3238
  }
3216
3239
  if (operation.type === "insert_node" && !slate.Editor.isEditor(operation.node)) {
3240
+ const existingKeys = [...slate.Node.descendants(editor)].map(([node]) => node._key);
3217
3241
  apply2({
3218
3242
  ...operation,
3219
3243
  node: {
3220
3244
  ...operation.node,
3221
- _key: editorActor.getSnapshot().context.keyGenerator()
3245
+ _key: operation.node._key === void 0 || existingKeys.includes(operation.node._key) ? editorActor.getSnapshot().context.keyGenerator() : operation.node._key
3222
3246
  }
3223
3247
  });
3224
3248
  return;
@@ -3906,6 +3930,7 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3906
3930
  if (atTheEndOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsEnding.includes(mark))) {
3907
3931
  slate.Transforms.insertNodes(editor, {
3908
3932
  ...op.node,
3933
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3909
3934
  marks: op.node.marks?.filter((mark) => !annotationsEnding.includes(mark)) ?? []
3910
3935
  });
3911
3936
  return;
@@ -3914,6 +3939,7 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3914
3939
  if (atTheStartOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsStarting.includes(mark))) {
3915
3940
  slate.Transforms.insertNodes(editor, {
3916
3941
  ...op.node,
3942
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3917
3943
  marks: op.node.marks?.filter((mark) => !annotationsStarting.includes(mark)) ?? []
3918
3944
  });
3919
3945
  return;
@@ -3922,6 +3948,7 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3922
3948
  if (nextSpanDecorators.length > 0 && atTheEndOfAnnotation && !atTheStartOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.length === 0) {
3923
3949
  slate.Transforms.insertNodes(editor, {
3924
3950
  ...op.node,
3951
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3925
3952
  marks: nextSpanDecorators
3926
3953
  });
3927
3954
  return;
@@ -4431,7 +4458,7 @@ const toggleListItemActionImplementation = ({
4431
4458
  }) => {
4432
4459
  if (!action.editor.selection)
4433
4460
  return;
4434
- const guards = selector_isActiveStyle.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4461
+ const guards = selector_isAtTheStartOfBlock.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4435
4462
  at: action.editor.selection,
4436
4463
  match: (node) => guards.isListBlock(node)
4437
4464
  })];
@@ -4445,7 +4472,7 @@ const toggleListItemActionImplementation = ({
4445
4472
  }) => {
4446
4473
  if (!action.editor.selection)
4447
4474
  return;
4448
- const guards = selector_isActiveStyle.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4475
+ const guards = selector_isAtTheStartOfBlock.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4449
4476
  at: action.editor.selection,
4450
4477
  match: (node) => guards.isTextBlock(node)
4451
4478
  })];
@@ -4495,7 +4522,7 @@ const toggleStyleActionImplementation = ({
4495
4522
  }) => {
4496
4523
  if (!action.editor.selection)
4497
4524
  return;
4498
- const defaultStyle = context.schema.styles[0].value, guards = selector_isActiveStyle.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4525
+ const defaultStyle = context.schema.styles[0].value, guards = selector_isAtTheStartOfBlock.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4499
4526
  at: action.editor.selection,
4500
4527
  match: (node) => guards.isTextBlock(node)
4501
4528
  })];
@@ -4511,7 +4538,7 @@ const toggleStyleActionImplementation = ({
4511
4538
  }) => {
4512
4539
  if (!action.editor.selection)
4513
4540
  return;
4514
- const guards = selector_isActiveStyle.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4541
+ const guards = selector_isAtTheStartOfBlock.createGuards(context), selectedBlocks = [...slate.Editor.nodes(action.editor, {
4515
4542
  at: action.editor.selection,
4516
4543
  match: (node) => guards.isTextBlock(node)
4517
4544
  })];
@@ -5052,10 +5079,9 @@ function insertBlock({
5052
5079
  });
5053
5080
  } else placement === "before" ? slate.Transforms.insertNodes(editor, block, {
5054
5081
  at: focusBlockPath
5055
- }) : slate.Editor.insertNode(editor, block);
5056
- focusBlock && isEqualToEmptyEditor([focusBlock], schema2) && slate.Transforms.removeNodes(editor, {
5082
+ }) : (slate.Editor.insertNode(editor, block), focusBlock && isEqualToEmptyEditor([focusBlock], schema2) && slate.Transforms.removeNodes(editor, {
5057
5083
  at: focusBlockPath
5058
- });
5084
+ }));
5059
5085
  } else {
5060
5086
  const lastBlock = Array.from(slate.Editor.nodes(editor, {
5061
5087
  match: (n) => !slate.Editor.isEditor(n),
@@ -5067,7 +5093,47 @@ function insertBlock({
5067
5093
  });
5068
5094
  }
5069
5095
  }
5070
- const dataTransferSetActionImplementation = ({
5096
+ const blockSetBehaviorActionImplementation = ({
5097
+ action
5098
+ }) => {
5099
+ const location = toSlateRange({
5100
+ anchor: {
5101
+ path: action.at,
5102
+ offset: 0
5103
+ },
5104
+ focus: {
5105
+ path: action.at,
5106
+ offset: 0
5107
+ }
5108
+ }, action.editor);
5109
+ if (!location)
5110
+ return;
5111
+ const {
5112
+ at,
5113
+ editor,
5114
+ type,
5115
+ ...payload
5116
+ } = action;
5117
+ slate.Transforms.setNodes(action.editor, payload, {
5118
+ at: location
5119
+ });
5120
+ }, blockUnsetBehaviorActionImplementation = ({
5121
+ action
5122
+ }) => {
5123
+ const location = toSlateRange({
5124
+ anchor: {
5125
+ path: action.at,
5126
+ offset: 0
5127
+ },
5128
+ focus: {
5129
+ path: action.at,
5130
+ offset: 0
5131
+ }
5132
+ }, action.editor);
5133
+ location && slate.Transforms.unsetNodes(action.editor, action.props, {
5134
+ at: location
5135
+ });
5136
+ }, dataTransferSetActionImplementation = ({
5071
5137
  action
5072
5138
  }) => {
5073
5139
  action.dataTransfer.setData(action.mimeType, action.data);
@@ -5124,96 +5190,54 @@ const dataTransferSetActionImplementation = ({
5124
5190
  const keyGenerator = context.keyGenerator, schema2 = context.schema, editor = action.editor;
5125
5191
  if (!editor.selection)
5126
5192
  return;
5127
- const [focusSpan] = Array.from(slate.Editor.nodes(editor, {
5128
- mode: "lowest",
5129
- at: editor.selection.focus,
5130
- match: (n) => editor.isTextSpan(n),
5131
- voids: !1
5132
- }))[0] ?? [void 0], focusDecorators = focusSpan?.marks?.filter((mark) => schema2.decorators.some((decorator) => decorator.value === mark)) ?? [], focusAnnotations = focusSpan?.marks?.filter((mark) => !schema2.decorators.some((decorator) => decorator.value === mark)) ?? [], anchorBlockPath = editor.selection.anchor.path.slice(0, 1), focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = slate.Node.descendant(editor, focusBlockPath);
5133
- if (editor.isTextBlock(focusBlock)) {
5134
- const [start, end] = slate.Range.edges(editor.selection), lastFocusBlockChild = focusBlock.children[focusBlock.children.length - 1], atTheEndOfBlock = isEqual__default.default(start, {
5135
- path: [...focusBlockPath, focusBlock.children.length - 1],
5136
- offset: editor.isTextSpan(lastFocusBlockChild) ? lastFocusBlockChild.text.length : 0
5137
- }), atTheStartOfBlock = isEqual__default.default(end, {
5138
- path: [...focusBlockPath, 0],
5139
- offset: 0
5140
- });
5141
- if (atTheEndOfBlock && slate.Range.isCollapsed(editor.selection)) {
5142
- slate.Editor.insertNode(editor, editor.pteCreateTextBlock({
5143
- decorators: [],
5144
- listItem: focusBlock.listItem,
5145
- level: focusBlock.level
5146
- }));
5147
- return;
5148
- }
5149
- if (atTheStartOfBlock && slate.Range.isCollapsed(editor.selection)) {
5150
- slate.Editor.insertNode(editor, editor.pteCreateTextBlock({
5151
- decorators: focusAnnotations.length === 0 ? focusDecorators : [],
5152
- listItem: focusBlock.listItem,
5153
- level: focusBlock.level
5154
- }));
5155
- const [nextBlockPath] = slate.Path.next(focusBlockPath);
5156
- slate.Transforms.select(editor, {
5193
+ const anchorBlockPath = editor.selection.anchor.path.slice(0, 1), focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = slate.Node.descendant(editor, focusBlockPath);
5194
+ if (editor.isTextBlock(focusBlock) && anchorBlockPath[0] === focusBlockPath[0]) {
5195
+ slate.Editor.withoutNormalizing(editor, () => {
5196
+ if (!editor.selection)
5197
+ return;
5198
+ slate.Transforms.splitNodes(editor, {
5199
+ at: editor.selection
5200
+ });
5201
+ const [nextNode, nextNodePath] = slate.Editor.node(editor, slate.Path.next(focusBlockPath), {
5202
+ depth: 1
5203
+ });
5204
+ if (slate.Transforms.setSelection(editor, {
5157
5205
  anchor: {
5158
- path: [nextBlockPath, 0],
5206
+ path: [...nextNodePath, 0],
5159
5207
  offset: 0
5160
5208
  },
5161
5209
  focus: {
5162
- path: [nextBlockPath, 0],
5210
+ path: [...nextNodePath, 0],
5163
5211
  offset: 0
5164
5212
  }
5165
- });
5166
- return;
5167
- }
5168
- const selectionAcrossBlocks = anchorBlockPath[0] !== focusBlockPath[0];
5169
- if (!atTheStartOfBlock && !atTheEndOfBlock && !selectionAcrossBlocks) {
5170
- slate.Editor.withoutNormalizing(editor, () => {
5171
- if (!editor.selection)
5172
- return;
5173
- slate.Transforms.splitNodes(editor, {
5174
- at: editor.selection
5175
- });
5176
- const [nextNode, nextNodePath] = slate.Editor.node(editor, slate.Path.next(focusBlockPath), {
5177
- depth: 1
5178
- });
5179
- if (slate.Transforms.setSelection(editor, {
5180
- anchor: {
5181
- path: [...nextNodePath, 0],
5182
- offset: 0
5183
- },
5184
- focus: {
5185
- path: [...nextNodePath, 0],
5186
- offset: 0
5187
- }
5188
- }), editor.isTextBlock(nextNode) && nextNode.markDefs && nextNode.markDefs.length > 0) {
5189
- const newMarkDefKeys = /* @__PURE__ */ new Map(), prevNodeSpans = Array.from(slate.Node.children(editor, focusBlockPath)).map((entry) => entry[0]).filter((node) => editor.isTextSpan(node)), children = slate.Node.children(editor, nextNodePath);
5190
- for (const [child, childPath] of children) {
5191
- if (!editor.isTextSpan(child))
5192
- continue;
5193
- const marks = child.marks ?? [];
5194
- for (const mark of marks)
5195
- schema2.decorators.some((decorator) => decorator.value === mark) || prevNodeSpans.some((prevNodeSpan) => prevNodeSpan.marks?.includes(mark)) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
5196
- const newMarks = marks.map((mark) => newMarkDefKeys.get(mark) ?? mark);
5197
- isEqual__default.default(marks, newMarks) || slate.Transforms.setNodes(editor, {
5198
- marks: newMarks
5199
- }, {
5200
- at: childPath
5201
- });
5202
- }
5203
- const newMarkDefs = nextNode.markDefs.map((markDef) => ({
5204
- ...markDef,
5205
- _key: newMarkDefKeys.get(markDef._key) ?? markDef._key
5206
- }));
5207
- isEqual__default.default(nextNode.markDefs, newMarkDefs) || slate.Transforms.setNodes(editor, {
5208
- markDefs: newMarkDefs
5213
+ }), editor.isTextBlock(nextNode) && nextNode.markDefs && nextNode.markDefs.length > 0) {
5214
+ const newMarkDefKeys = /* @__PURE__ */ new Map(), prevNodeSpans = Array.from(slate.Node.children(editor, focusBlockPath)).map((entry) => entry[0]).filter((node) => editor.isTextSpan(node)), children = slate.Node.children(editor, nextNodePath);
5215
+ for (const [child, childPath] of children) {
5216
+ if (!editor.isTextSpan(child))
5217
+ continue;
5218
+ const marks = child.marks ?? [];
5219
+ for (const mark of marks)
5220
+ schema2.decorators.some((decorator) => decorator.value === mark) || prevNodeSpans.some((prevNodeSpan) => prevNodeSpan.marks?.includes(mark)) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
5221
+ const newMarks = marks.map((mark) => newMarkDefKeys.get(mark) ?? mark);
5222
+ isEqual__default.default(marks, newMarks) || slate.Transforms.setNodes(editor, {
5223
+ marks: newMarks
5209
5224
  }, {
5210
- at: nextNodePath,
5211
- match: (node) => editor.isTextBlock(node)
5225
+ at: childPath
5212
5226
  });
5213
5227
  }
5214
- }), editor.onChange();
5215
- return;
5216
- }
5228
+ const newMarkDefs = nextNode.markDefs.map((markDef) => ({
5229
+ ...markDef,
5230
+ _key: newMarkDefKeys.get(markDef._key) ?? markDef._key
5231
+ }));
5232
+ isEqual__default.default(nextNode.markDefs, newMarkDefs) || slate.Transforms.setNodes(editor, {
5233
+ markDefs: newMarkDefs
5234
+ }, {
5235
+ at: nextNodePath,
5236
+ match: (node) => editor.isTextBlock(node)
5237
+ });
5238
+ }
5239
+ }), editor.onChange();
5240
+ return;
5217
5241
  }
5218
5242
  slate.Transforms.splitNodes(editor, {
5219
5243
  always: !0
@@ -5294,6 +5318,30 @@ const dataTransferSetActionImplementation = ({
5294
5318
  text: action.text,
5295
5319
  marks: [...annotations?.map((annotation) => annotation._key) ?? [], ...action.decorators ?? []]
5296
5320
  });
5321
+ }, insertBlockActionImplementation = ({
5322
+ context,
5323
+ action
5324
+ }) => {
5325
+ const parsedBlock = parseBlock({
5326
+ block: action.block,
5327
+ context,
5328
+ options: {
5329
+ refreshKeys: !1
5330
+ }
5331
+ });
5332
+ if (!parsedBlock)
5333
+ throw new Error(`Failed to parse block ${JSON.stringify(action.block)}`);
5334
+ const fragment = toSlateValue([parsedBlock], {
5335
+ schemaTypes: context.schema
5336
+ })[0];
5337
+ if (!fragment)
5338
+ throw new Error(`Failed to convert block to Slate fragment ${JSON.stringify(parsedBlock)}`);
5339
+ insertBlock({
5340
+ block: fragment,
5341
+ placement: action.placement,
5342
+ editor: action.editor,
5343
+ schema: context.schema
5344
+ });
5297
5345
  }, textBlockSetActionImplementation = ({
5298
5346
  action
5299
5347
  }) => {
@@ -5340,6 +5388,8 @@ const dataTransferSetActionImplementation = ({
5340
5388
  "annotation.add": addAnnotationActionImplementation,
5341
5389
  "annotation.remove": removeAnnotationActionImplementation,
5342
5390
  "annotation.toggle": toggleAnnotationActionImplementation,
5391
+ "block.set": blockSetBehaviorActionImplementation,
5392
+ "block.unset": blockUnsetBehaviorActionImplementation,
5343
5393
  blur: ({
5344
5394
  action
5345
5395
  }) => {
@@ -5430,6 +5480,7 @@ const dataTransferSetActionImplementation = ({
5430
5480
  }
5431
5481
  });
5432
5482
  },
5483
+ "insert.block": insertBlockActionImplementation,
5433
5484
  "insert.blocks": insertBlocksActionImplementation,
5434
5485
  "insert.block object": insertBlockObjectActionImplementation,
5435
5486
  "insert.break": insertBreakActionImplementation,
@@ -5579,13 +5630,6 @@ function performAction({
5579
5630
  });
5580
5631
  break;
5581
5632
  }
5582
- case "select": {
5583
- behaviorActionImplementations.select({
5584
- context,
5585
- action
5586
- });
5587
- break;
5588
- }
5589
5633
  default:
5590
5634
  performDefaultAction({
5591
5635
  context,
@@ -5619,6 +5663,20 @@ function performDefaultAction({
5619
5663
  });
5620
5664
  break;
5621
5665
  }
5666
+ case "block.set": {
5667
+ behaviorActionImplementations["block.set"]({
5668
+ context,
5669
+ action
5670
+ });
5671
+ break;
5672
+ }
5673
+ case "block.unset": {
5674
+ behaviorActionImplementations["block.unset"]({
5675
+ context,
5676
+ action
5677
+ });
5678
+ break;
5679
+ }
5622
5680
  case "blur": {
5623
5681
  behaviorActionImplementations.blur({
5624
5682
  context,
@@ -5703,6 +5761,13 @@ function performDefaultAction({
5703
5761
  });
5704
5762
  break;
5705
5763
  }
5764
+ case "insert.block": {
5765
+ behaviorActionImplementations["insert.block"]({
5766
+ context,
5767
+ action
5768
+ });
5769
+ break;
5770
+ }
5706
5771
  case "insert.blocks": {
5707
5772
  behaviorActionImplementations["insert.blocks"]({
5708
5773
  context,
@@ -5864,13 +5929,11 @@ function performDefaultAction({
5864
5929
  });
5865
5930
  break;
5866
5931
  }
5867
- case "text block.unset": {
5932
+ default:
5868
5933
  behaviorActionImplementations["text block.unset"]({
5869
5934
  context,
5870
5935
  action
5871
5936
  });
5872
- break;
5873
- }
5874
5937
  }
5875
5938
  }
5876
5939
  function getActiveDecorators({
@@ -6251,6 +6314,11 @@ const editorMachine = xstate.setup({
6251
6314
  event
6252
6315
  }) => event)
6253
6316
  },
6317
+ "block.*": {
6318
+ actions: xstate.emit(({
6319
+ event
6320
+ }) => event)
6321
+ },
6254
6322
  blur: {
6255
6323
  actions: xstate.emit(({
6256
6324
  event