@portabletext/editor 1.32.0 → 1.33.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 (69) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +4 -4
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +19 -11
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/plugin.event-listener.cjs +127 -88
  6. package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -1
  7. package/lib/_chunks-cjs/selector.get-trimmed-selection.cjs +97 -0
  8. package/lib/_chunks-cjs/selector.get-trimmed-selection.cjs.map +1 -0
  9. package/lib/_chunks-cjs/{parse-blocks.cjs → util.block-offsets-to-selection.cjs} +21 -2
  10. package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +1 -0
  11. package/lib/_chunks-cjs/util.reverse-selection.cjs +11 -0
  12. package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -1
  13. package/lib/_chunks-es/behavior.core.js +1 -1
  14. package/lib/_chunks-es/behavior.core.js.map +1 -1
  15. package/lib/_chunks-es/behavior.markdown.js +18 -11
  16. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  17. package/lib/_chunks-es/plugin.event-listener.js +127 -87
  18. package/lib/_chunks-es/plugin.event-listener.js.map +1 -1
  19. package/lib/_chunks-es/selector.get-trimmed-selection.js +100 -0
  20. package/lib/_chunks-es/selector.get-trimmed-selection.js.map +1 -0
  21. package/lib/_chunks-es/{parse-blocks.js → util.block-offsets-to-selection.js} +21 -1
  22. package/lib/_chunks-es/util.block-offsets-to-selection.js.map +1 -0
  23. package/lib/_chunks-es/util.reverse-selection.js +11 -0
  24. package/lib/_chunks-es/util.reverse-selection.js.map +1 -1
  25. package/lib/behaviors/index.d.cts +1 -0
  26. package/lib/behaviors/index.d.ts +1 -0
  27. package/lib/index.d.cts +60 -0
  28. package/lib/index.d.ts +60 -0
  29. package/lib/plugins/index.cjs +295 -3
  30. package/lib/plugins/index.cjs.map +1 -1
  31. package/lib/plugins/index.d.cts +74 -1
  32. package/lib/plugins/index.d.ts +74 -1
  33. package/lib/plugins/index.js +300 -4
  34. package/lib/plugins/index.js.map +1 -1
  35. package/lib/selectors/index.cjs +51 -1
  36. package/lib/selectors/index.cjs.map +1 -1
  37. package/lib/selectors/index.d.cts +67 -0
  38. package/lib/selectors/index.d.ts +67 -0
  39. package/lib/selectors/index.js +53 -2
  40. package/lib/selectors/index.js.map +1 -1
  41. package/lib/utils/index.cjs +5 -4
  42. package/lib/utils/index.cjs.map +1 -1
  43. package/lib/utils/index.d.cts +16 -0
  44. package/lib/utils/index.d.ts +16 -0
  45. package/lib/utils/index.js +4 -3
  46. package/package.json +2 -2
  47. package/src/behavior-actions/behavior.action.decorator.add.ts +161 -0
  48. package/src/behavior-actions/behavior.action.delete.text.ts +54 -0
  49. package/src/behavior-actions/behavior.actions.ts +5 -43
  50. package/src/behaviors/behavior.markdown-emphasis.ts +395 -0
  51. package/src/behaviors/behavior.markdown.ts +11 -4
  52. package/src/behaviors/behavior.types.ts +1 -0
  53. package/src/editor/plugins/createWithPortableTextMarkModel.ts +2 -97
  54. package/src/plugins/plugin.markdown.tsx +11 -1
  55. package/src/selectors/index.ts +5 -0
  56. package/src/selectors/selector.get-anchor-block.ts +22 -0
  57. package/src/selectors/selector.get-anchor-child.ts +36 -0
  58. package/src/selectors/selector.get-anchor-span.ts +18 -0
  59. package/src/selectors/selector.get-anchor-text-block.ts +20 -0
  60. package/src/selectors/selector.get-trimmed-selection.test.ts +658 -0
  61. package/src/selectors/selector.get-trimmed-selection.ts +175 -0
  62. package/src/utils/index.ts +1 -0
  63. package/src/utils/util.block-offsets-to-selection.ts +36 -0
  64. package/lib/_chunks-cjs/parse-blocks.cjs.map +0 -1
  65. package/lib/_chunks-cjs/util.is-empty-text-block.cjs +0 -14
  66. package/lib/_chunks-cjs/util.is-empty-text-block.cjs.map +0 -1
  67. package/lib/_chunks-es/parse-blocks.js.map +0 -1
  68. package/lib/_chunks-es/util.is-empty-text-block.js +0 -15
  69. package/lib/_chunks-es/util.is-empty-text-block.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), useEffectEvent = require("use-effect-event"), jsxRuntime = require("react/jsx-runtime"), slateReact = require("slate-react"), react = require("@xstate/react"), debug$e = require("debug"), slate = require("slate"), xstate = require("xstate"), isEqual = require("lodash/isEqual.js"), patches = require("@portabletext/patches"), types = require("@sanity/types"), flatten = require("lodash/flatten.js"), isPlainObject = require("lodash/isPlainObject.js"), uniq = require("lodash/uniq.js"), getRandomValues = require("get-random-values-esm"), parseBlocks = require("./parse-blocks.cjs"), util_sliceBlocks = require("./util.slice-blocks.cjs"), blockTools = require("@portabletext/block-tools"), toHtml = require("@portabletext/to-html"), schema = require("@sanity/schema"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), selector_isAtTheStartOfBlock = require("./selector.is-at-the-start-of-block.cjs"), util_reverseSelection = require("./util.reverse-selection.cjs"), startCase = require("lodash.startcase"), behavior_core = require("./behavior.core.cjs"), rxjs = require("rxjs");
2
+ var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), useEffectEvent = require("use-effect-event"), jsxRuntime = require("react/jsx-runtime"), slateReact = require("slate-react"), react = require("@xstate/react"), debug$e = require("debug"), slate = require("slate"), xstate = require("xstate"), isEqual = require("lodash/isEqual.js"), patches = require("@portabletext/patches"), types = require("@sanity/types"), flatten = require("lodash/flatten.js"), isPlainObject = require("lodash/isPlainObject.js"), uniq = require("lodash/uniq.js"), getRandomValues = require("get-random-values-esm"), util_blockOffsetsToSelection = require("./util.block-offsets-to-selection.cjs"), util_sliceBlocks = require("./util.slice-blocks.cjs"), blockTools = require("@portabletext/block-tools"), toHtml = require("@portabletext/to-html"), schema = require("@sanity/schema"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), selector_isAtTheStartOfBlock = require("./selector.is-at-the-start-of-block.cjs"), util_reverseSelection = require("./util.reverse-selection.cjs"), selector_getTrimmedSelection = require("./selector.get-trimmed-selection.cjs"), startCase = require("lodash.startcase"), behavior_core = require("./behavior.core.cjs"), rxjs = require("rxjs");
3
3
  function _interopDefaultCompat(e) {
4
4
  return e && typeof e == "object" && "default" in e ? e : { default: e };
5
5
  }
@@ -2326,7 +2326,7 @@ const converterJson = {
2326
2326
  reason: "Data is not an array"
2327
2327
  };
2328
2328
  const parsedBlocks = blocks.flatMap((block) => {
2329
- const parsedBlock = parseBlocks.parseBlock({
2329
+ const parsedBlock = util_blockOffsetsToSelection.parseBlock({
2330
2330
  context,
2331
2331
  block,
2332
2332
  options: {
@@ -2872,6 +2872,95 @@ function isPortableTextBlock(node) {
2872
2872
  node.children.every((child) => typeof child == "object" && "_type" in child)
2873
2873
  );
2874
2874
  }
2875
+ const decoratorAddActionImplementation = ({
2876
+ context,
2877
+ action
2878
+ }) => {
2879
+ const editor = action.editor, mark = action.decorator, selection = action.selection ? toSlateRange(action.selection, action.editor) ?? editor.selection : editor.selection;
2880
+ if (!selection)
2881
+ return;
2882
+ const value = fromSlateValue(editor.children, context.schema.block.name, KEY_TO_VALUE_ELEMENT.get(editor)), editorSelection = toPortableTextRange(value, selection, context.schema), anchorOffset = editorSelection ? util_reverseSelection.spanSelectionPointToBlockOffset({
2883
+ value,
2884
+ selectionPoint: editorSelection.anchor
2885
+ }) : void 0, focusOffset = editorSelection ? util_reverseSelection.spanSelectionPointToBlockOffset({
2886
+ value,
2887
+ selectionPoint: editorSelection.focus
2888
+ }) : void 0;
2889
+ if (!anchorOffset || !focusOffset)
2890
+ throw new Error("Unable to find anchor or focus offset");
2891
+ if (slate.Range.isExpanded(selection)) {
2892
+ slate.Transforms.setNodes(editor, {}, {
2893
+ at: selection,
2894
+ match: slate.Text.isText,
2895
+ split: !0,
2896
+ hanging: !0
2897
+ });
2898
+ const newValue = fromSlateValue(editor.children, context.schema.block.name, KEY_TO_VALUE_ELEMENT.get(editor)), newSelection = util_blockOffsetsToSelection.blockOffsetsToSelection({
2899
+ value: newValue,
2900
+ offsets: {
2901
+ anchor: anchorOffset,
2902
+ focus: focusOffset
2903
+ },
2904
+ backward: editorSelection?.backward
2905
+ }), trimmedSelection = selector_getTrimmedSelection.getTrimmedSelection({
2906
+ context: {
2907
+ activeDecorators: [],
2908
+ converters: [],
2909
+ keyGenerator: context.keyGenerator,
2910
+ schema: context.schema,
2911
+ selection: newSelection,
2912
+ value: newValue
2913
+ }
2914
+ });
2915
+ if (!trimmedSelection)
2916
+ throw new Error("Unable to find trimmed selection");
2917
+ const newRange = toSlateRange(trimmedSelection, editor);
2918
+ if (!newRange)
2919
+ throw new Error("Unable to find new selection");
2920
+ const splitTextNodes = slate.Range.isRange(newRange) ? [...slate.Editor.nodes(editor, {
2921
+ at: newRange,
2922
+ match: (node) => slate.Text.isText(node)
2923
+ })] : [];
2924
+ for (const [node, path] of splitTextNodes) {
2925
+ const marks = [...(Array.isArray(node.marks) ? node.marks : []).filter((eMark) => eMark !== mark), mark];
2926
+ slate.Transforms.setNodes(editor, {
2927
+ marks
2928
+ }, {
2929
+ at: path,
2930
+ match: slate.Text.isText,
2931
+ split: !0,
2932
+ hanging: !0
2933
+ });
2934
+ }
2935
+ } else {
2936
+ const [block, blockPath] = slate.Editor.node(editor, selection, {
2937
+ depth: 1
2938
+ }), lonelyEmptySpan = editor.isTextBlock(block) && block.children.length === 1 && editor.isTextSpan(block.children[0]) && block.children[0].text === "" ? block.children[0] : void 0;
2939
+ if (lonelyEmptySpan) {
2940
+ const existingMarks = lonelyEmptySpan.marks ?? [], existingMarksWithoutDecorator = existingMarks.filter((existingMark) => existingMark !== mark);
2941
+ slate.Transforms.setNodes(editor, {
2942
+ marks: existingMarks.length === existingMarksWithoutDecorator.length ? [...existingMarks, mark] : existingMarksWithoutDecorator
2943
+ }, {
2944
+ at: blockPath,
2945
+ match: (node) => editor.isTextSpan(node)
2946
+ });
2947
+ } else {
2948
+ const existingMarks = {
2949
+ ...slate.Editor.marks(editor) || {}
2950
+ }.marks || [], marks = {
2951
+ ...slate.Editor.marks(editor) || {},
2952
+ marks: [...existingMarks, mark]
2953
+ };
2954
+ editor.marks = marks;
2955
+ }
2956
+ }
2957
+ if (editor.selection) {
2958
+ const selection2 = editor.selection;
2959
+ editor.selection = {
2960
+ ...selection2
2961
+ };
2962
+ }
2963
+ };
2875
2964
  function getPreviousSpan({
2876
2965
  editor,
2877
2966
  blockPath,
@@ -3255,62 +3344,7 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3255
3344
  }, editor;
3256
3345
  };
3257
3346
  }
3258
- const addDecoratorActionImplementation = ({
3259
- action
3260
- }) => {
3261
- const editor = action.editor, mark = action.decorator;
3262
- if (editor.selection) {
3263
- if (slate.Range.isExpanded(editor.selection)) {
3264
- slate.Transforms.setNodes(editor, {}, {
3265
- match: slate.Text.isText,
3266
- split: !0,
3267
- hanging: !0
3268
- });
3269
- const splitTextNodes = slate.Range.isRange(editor.selection) ? [...slate.Editor.nodes(editor, {
3270
- at: editor.selection,
3271
- match: slate.Text.isText
3272
- })] : [];
3273
- splitTextNodes.length > 1 && splitTextNodes.every((node) => node[0].marks?.includes(mark)) ? editor.removeMark(mark) : splitTextNodes.forEach(([node, path]) => {
3274
- const marks = [...(Array.isArray(node.marks) ? node.marks : []).filter((eMark) => eMark !== mark), mark];
3275
- slate.Transforms.setNodes(editor, {
3276
- marks
3277
- }, {
3278
- at: path,
3279
- match: slate.Text.isText,
3280
- split: !0,
3281
- hanging: !0
3282
- });
3283
- });
3284
- } else {
3285
- const [block, blockPath] = slate.Editor.node(editor, editor.selection, {
3286
- depth: 1
3287
- }), lonelyEmptySpan = editor.isTextBlock(block) && block.children.length === 1 && editor.isTextSpan(block.children[0]) && block.children[0].text === "" ? block.children[0] : void 0;
3288
- if (lonelyEmptySpan) {
3289
- const existingMarks = lonelyEmptySpan.marks ?? [], existingMarksWithoutDecorator = existingMarks.filter((existingMark) => existingMark !== mark);
3290
- slate.Transforms.setNodes(editor, {
3291
- marks: existingMarks.length === existingMarksWithoutDecorator.length ? [...existingMarks, mark] : existingMarksWithoutDecorator
3292
- }, {
3293
- at: blockPath,
3294
- match: (node) => editor.isTextSpan(node)
3295
- });
3296
- } else {
3297
- const existingMarks = {
3298
- ...slate.Editor.marks(editor) || {}
3299
- }.marks || [], marks = {
3300
- ...slate.Editor.marks(editor) || {},
3301
- marks: [...existingMarks, mark]
3302
- };
3303
- editor.marks = marks;
3304
- }
3305
- }
3306
- if (editor.selection) {
3307
- const selection = editor.selection;
3308
- editor.selection = {
3309
- ...selection
3310
- };
3311
- }
3312
- }
3313
- }, removeDecoratorActionImplementation = ({
3347
+ const removeDecoratorActionImplementation = ({
3314
3348
  action
3315
3349
  }) => {
3316
3350
  const editor = action.editor, mark = action.decorator, {
@@ -3398,7 +3432,7 @@ const toggleDecoratorActionImplementation = ({
3398
3432
  editor: action.editor,
3399
3433
  decorator: action.decorator
3400
3434
  }
3401
- }) : addDecoratorActionImplementation({
3435
+ }) : decoratorAddActionImplementation({
3402
3436
  context,
3403
3437
  action: {
3404
3438
  type: "decorator.add",
@@ -3998,6 +4032,37 @@ const blockSetBehaviorActionImplementation = ({
3998
4032
  if (!range)
3999
4033
  throw new Error(`Failed to get Slate Range for selection ${JSON.stringify(action.selection)}`);
4000
4034
  slate.select(action.editor, range), slate.deleteFragment(action.editor);
4035
+ }, deleteTextActionImplementation = ({
4036
+ context,
4037
+ action
4038
+ }) => {
4039
+ const value = fromSlateValue(action.editor.children, context.schema.block.name, KEY_TO_VALUE_ELEMENT.get(action.editor)), selection = util_blockOffsetsToSelection.blockOffsetsToSelection({
4040
+ value,
4041
+ offsets: {
4042
+ anchor: action.anchor,
4043
+ focus: action.focus
4044
+ }
4045
+ });
4046
+ if (!selection)
4047
+ throw new Error("Unable to find selection from block offsets");
4048
+ const trimmedSelection = selector_getTrimmedSelection.getTrimmedSelection({
4049
+ context: {
4050
+ converters: [],
4051
+ schema: context.schema,
4052
+ keyGenerator: context.keyGenerator,
4053
+ activeDecorators: [],
4054
+ value,
4055
+ selection
4056
+ }
4057
+ });
4058
+ if (!trimmedSelection)
4059
+ throw new Error("Unable to find trimmed selection");
4060
+ const range = toSlateRange(trimmedSelection, action.editor);
4061
+ if (!range)
4062
+ throw new Error("Unable to find Slate range from trimmed selection");
4063
+ slate.Transforms.delete(action.editor, {
4064
+ at: range
4065
+ });
4001
4066
  }, insertBlockObjectActionImplementation = ({
4002
4067
  context,
4003
4068
  action
@@ -4113,7 +4178,7 @@ const blockSetBehaviorActionImplementation = ({
4113
4178
  context,
4114
4179
  action
4115
4180
  }) => {
4116
- const parsedBlock = parseBlocks.parseBlock({
4181
+ const parsedBlock = util_blockOffsetsToSelection.parseBlock({
4117
4182
  block: action.block,
4118
4183
  context,
4119
4184
  options: {
@@ -4187,7 +4252,7 @@ const blockSetBehaviorActionImplementation = ({
4187
4252
  slateReact.ReactEditor.blur(action.editor);
4188
4253
  },
4189
4254
  "data transfer.set": dataTransferSetActionImplementation,
4190
- "decorator.add": addDecoratorActionImplementation,
4255
+ "decorator.add": decoratorAddActionImplementation,
4191
4256
  "decorator.remove": removeDecoratorActionImplementation,
4192
4257
  "decorator.toggle": toggleDecoratorActionImplementation,
4193
4258
  focus: ({
@@ -4227,33 +4292,7 @@ const blockSetBehaviorActionImplementation = ({
4227
4292
  at: range
4228
4293
  });
4229
4294
  },
4230
- "delete.text": ({
4231
- context,
4232
- action
4233
- }) => {
4234
- const value = fromSlateValue(action.editor.children, context.schema.block.name, KEY_TO_VALUE_ELEMENT.get(action.editor)), anchor = util_reverseSelection.blockOffsetToSpanSelectionPoint({
4235
- value,
4236
- blockOffset: action.anchor
4237
- }), focus = util_reverseSelection.blockOffsetToSpanSelectionPoint({
4238
- value,
4239
- blockOffset: action.focus
4240
- });
4241
- if (!anchor || !focus) {
4242
- console.error("Unable to find anchor or focus selection point");
4243
- return;
4244
- }
4245
- const range = toSlateRange({
4246
- anchor,
4247
- focus
4248
- }, action.editor);
4249
- if (!range) {
4250
- console.error("Unable to find Slate range from selection points");
4251
- return;
4252
- }
4253
- slate.Transforms.delete(action.editor, {
4254
- at: range
4255
- });
4256
- },
4295
+ "delete.text": deleteTextActionImplementation,
4257
4296
  "deserialization.failure": ({
4258
4297
  action
4259
4298
  }) => {