@portabletext/editor 1.34.1 → 1.35.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 (131) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +57 -118
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +27 -67
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/{plugin.event-listener.cjs → editor-provider.cjs} +101 -87
  6. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -0
  7. package/lib/_chunks-cjs/selector.get-text-before.cjs +5 -7
  8. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  9. package/lib/_chunks-cjs/selector.is-active-style.cjs +22 -36
  10. package/lib/_chunks-cjs/selector.is-active-style.cjs.map +1 -1
  11. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +68 -153
  12. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -1
  13. package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +1 -1
  14. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  15. package/lib/_chunks-es/behavior.core.js +57 -118
  16. package/lib/_chunks-es/behavior.core.js.map +1 -1
  17. package/lib/_chunks-es/behavior.markdown.js +27 -67
  18. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  19. package/lib/_chunks-es/{plugin.event-listener.js → editor-provider.js} +102 -88
  20. package/lib/_chunks-es/editor-provider.js.map +1 -0
  21. package/lib/_chunks-es/selector.get-text-before.js +5 -7
  22. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  23. package/lib/_chunks-es/selector.is-active-style.js +22 -36
  24. package/lib/_chunks-es/selector.is-active-style.js.map +1 -1
  25. package/lib/_chunks-es/selector.is-at-the-start-of-block.js +68 -153
  26. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
  27. package/lib/_chunks-es/util.block-offsets-to-selection.js.map +1 -1
  28. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  29. package/lib/behaviors/index.cjs +18 -48
  30. package/lib/behaviors/index.cjs.map +1 -1
  31. package/lib/behaviors/index.d.cts +19392 -214
  32. package/lib/behaviors/index.d.ts +19392 -214
  33. package/lib/behaviors/index.js +18 -48
  34. package/lib/behaviors/index.js.map +1 -1
  35. package/lib/index.cjs +81 -51
  36. package/lib/index.cjs.map +1 -1
  37. package/lib/index.d.cts +334 -59
  38. package/lib/index.d.ts +334 -59
  39. package/lib/index.js +35 -4
  40. package/lib/index.js.map +1 -1
  41. package/lib/plugins/index.cjs +200 -189
  42. package/lib/plugins/index.cjs.map +1 -1
  43. package/lib/plugins/index.d.cts +344 -25
  44. package/lib/plugins/index.d.ts +344 -25
  45. package/lib/plugins/index.js +198 -187
  46. package/lib/plugins/index.js.map +1 -1
  47. package/lib/selectors/index.cjs +22 -50
  48. package/lib/selectors/index.cjs.map +1 -1
  49. package/lib/selectors/index.d.cts +19485 -174
  50. package/lib/selectors/index.d.ts +19485 -174
  51. package/lib/selectors/index.js +22 -50
  52. package/lib/selectors/index.js.map +1 -1
  53. package/lib/utils/index.cjs.map +1 -1
  54. package/lib/utils/index.d.cts +19518 -7
  55. package/lib/utils/index.d.ts +19518 -7
  56. package/lib/utils/index.js.map +1 -1
  57. package/package.json +7 -7
  58. package/src/behavior-actions/behavior.action.decorator.add.ts +1 -0
  59. package/src/behavior-actions/behavior.action.delete.text.ts +1 -0
  60. package/src/behaviors/behavior.code-editor.ts +6 -6
  61. package/src/behaviors/behavior.core.annotations.ts +5 -4
  62. package/src/behaviors/behavior.core.block-objects.ts +17 -17
  63. package/src/behaviors/behavior.core.decorators.ts +12 -8
  64. package/src/behaviors/behavior.core.insert-break.ts +27 -29
  65. package/src/behaviors/behavior.core.lists.ts +19 -19
  66. package/src/behaviors/behavior.decorator-pair.ts +201 -0
  67. package/src/behaviors/behavior.default.ts +35 -30
  68. package/src/behaviors/behavior.emoji-picker.ts +12 -12
  69. package/src/behaviors/behavior.links.ts +7 -7
  70. package/src/behaviors/behavior.markdown.ts +41 -42
  71. package/src/behaviors/behavior.types.ts +14 -17
  72. package/src/behaviors/index.ts +0 -1
  73. package/src/converters/converter.json.ts +6 -6
  74. package/src/converters/converter.portable-text.deserialize.test.ts +27 -29
  75. package/src/converters/converter.portable-text.ts +13 -7
  76. package/src/converters/converter.text-html.deserialize.test.ts +16 -18
  77. package/src/converters/converter.text-html.serialize.test.ts +56 -57
  78. package/src/converters/converter.text-html.ts +14 -10
  79. package/src/converters/converter.text-plain.test.ts +17 -17
  80. package/src/converters/converter.text-plain.ts +15 -11
  81. package/src/converters/converter.types.ts +5 -5
  82. package/src/editor/Editable.tsx +26 -0
  83. package/src/editor/editor-machine.ts +170 -142
  84. package/src/editor/editor-selector.ts +3 -0
  85. package/src/editor/editor-snapshot.ts +13 -0
  86. package/src/editor-event-listener.tsx +30 -0
  87. package/src/index.ts +3 -3
  88. package/src/internal-utils/create-test-snapshot.ts +23 -0
  89. package/src/internal-utils/get-text-to-emphasize.ts +29 -7
  90. package/src/plugins/plugin.decorator-shortcut.ts +235 -0
  91. package/src/plugins/plugin.markdown.tsx +56 -8
  92. package/src/plugins/plugin.one-line.tsx +17 -17
  93. package/src/selectors/selector.get-active-annotations.test.ts +4 -13
  94. package/src/selectors/selector.get-active-list-item.ts +4 -4
  95. package/src/selectors/selector.get-active-style.ts +6 -6
  96. package/src/selectors/selector.get-anchor-block.ts +5 -5
  97. package/src/selectors/selector.get-anchor-child.ts +5 -5
  98. package/src/selectors/selector.get-anchor-span.ts +2 -2
  99. package/src/selectors/selector.get-anchor-text-block.ts +2 -2
  100. package/src/selectors/selector.get-block-offsets.ts +8 -7
  101. package/src/selectors/selector.get-caret-word-selection.test.ts +3 -7
  102. package/src/selectors/selector.get-caret-word-selection.ts +19 -16
  103. package/src/selectors/selector.get-next-inline-object.ts +4 -4
  104. package/src/selectors/selector.get-previous-inline-object.ts +4 -4
  105. package/src/selectors/selector.get-selected-slice.ts +7 -4
  106. package/src/selectors/selector.get-selected-spans.test.ts +5 -9
  107. package/src/selectors/selector.get-selected-spans.ts +9 -9
  108. package/src/selectors/selector.get-selection-end-point.ts +5 -5
  109. package/src/selectors/selector.get-selection-start-point.ts +5 -5
  110. package/src/selectors/selector.get-selection-text.test.ts +5 -7
  111. package/src/selectors/selector.get-selection-text.ts +2 -2
  112. package/src/selectors/selector.get-selection.ts +2 -2
  113. package/src/selectors/selector.get-text-before.ts +8 -8
  114. package/src/selectors/selector.get-trimmed-selection.test.ts +3 -5
  115. package/src/selectors/selector.get-trimmed-selection.ts +15 -13
  116. package/src/selectors/selector.get-value.ts +4 -4
  117. package/src/selectors/selector.is-active-decorator.test.ts +5 -9
  118. package/src/selectors/selector.is-at-the-end-of-block.ts +6 -3
  119. package/src/selectors/selector.is-at-the-start-of-block.ts +3 -3
  120. package/src/selectors/selector.is-overlapping-selection.ts +8 -6
  121. package/src/selectors/selector.is-selection-collapsed.ts +6 -5
  122. package/src/selectors/selector.is-selection-expanded.ts +2 -2
  123. package/src/selectors/selectors.ts +59 -59
  124. package/src/types/block-offset.ts +9 -0
  125. package/src/utils/index.ts +0 -1
  126. package/src/utils/util.block-offset.ts +1 -1
  127. package/src/utils/util.block-offsets-to-selection.ts +1 -1
  128. package/src/utils/util.child-selection-point-to-block-offset.ts +1 -1
  129. package/lib/_chunks-cjs/plugin.event-listener.cjs.map +0 -1
  130. package/lib/_chunks-es/plugin.event-listener.js.map +0 -1
  131. package/src/behaviors/behavior.markdown-emphasis.ts +0 -437
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), plugin_eventListener = require("../_chunks-cjs/plugin.event-listener.cjs"), behavior_markdown = require("../_chunks-cjs/behavior.markdown.cjs"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), xstate = require("xstate"), selector_isAtTheStartOfBlock = require("../_chunks-cjs/selector.is-at-the-start-of-block.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), util_blockOffsetsToSelection = require("../_chunks-cjs/util.block-offsets-to-selection.cjs"), utils_index = require("../utils/index.cjs"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs"), behavior_core = require("../_chunks-cjs/behavior.core.cjs"), jsxRuntime = require("react/jsx-runtime");
3
+ var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), editorProvider = require("../_chunks-cjs/editor-provider.cjs"), useEffectEvent = require("use-effect-event"), jsxRuntime = require("react/jsx-runtime"), behavior_markdown = require("../_chunks-cjs/behavior.markdown.cjs"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), xstate = require("xstate"), selector_isAtTheStartOfBlock = require("../_chunks-cjs/selector.is-at-the-start-of-block.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), util_blockOffsetsToSelection = require("../_chunks-cjs/util.block-offsets-to-selection.cjs"), utils_index = require("../utils/index.cjs"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs"), behavior_core = require("../_chunks-cjs/behavior.core.cjs");
4
4
  function _interopDefaultCompat(e) {
5
5
  return e && typeof e == "object" && "default" in e ? e : { default: e };
6
6
  }
7
7
  var React__default = /* @__PURE__ */ _interopDefaultCompat(React), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual);
8
8
  function BehaviorPlugin(props) {
9
- const $ = reactCompilerRuntime.c(4), editor = plugin_eventListener.useEditor();
9
+ const $ = reactCompilerRuntime.c(4), editor = editorProvider.useEditor();
10
10
  let t0, t1;
11
11
  return $[0] !== editor || $[1] !== props.behaviors ? (t0 = () => {
12
12
  const unregisterBehaviors = props.behaviors.map((behavior) => editor.registerBehavior({
@@ -20,120 +20,91 @@ function BehaviorPlugin(props) {
20
20
  function _temp(unregister) {
21
21
  return unregister();
22
22
  }
23
+ function EventListenerPlugin(props) {
24
+ const $ = reactCompilerRuntime.c(5), editor = editorProvider.useEditor(), on = useEffectEvent.useEffectEvent(props.on);
25
+ let t0;
26
+ $[0] !== editor || $[1] !== on ? (t0 = () => {
27
+ const subscription = editor.on("*", on);
28
+ return () => {
29
+ subscription.unsubscribe();
30
+ };
31
+ }, $[0] = editor, $[1] = on, $[2] = t0) : t0 = $[2];
32
+ let t1;
33
+ return $[3] !== editor ? (t1 = [editor], $[3] = editor, $[4] = t1) : t1 = $[4], React.useEffect(t0, t1), null;
34
+ }
23
35
  const EditorRefPlugin = React__default.default.forwardRef((_, ref) => {
24
- const $ = reactCompilerRuntime.c(2), editor = plugin_eventListener.useEditor(), portableTextEditorRef = React__default.default.useRef(editor);
36
+ const $ = reactCompilerRuntime.c(2), editor = editorProvider.useEditor(), portableTextEditorRef = React__default.default.useRef(editor);
25
37
  let t0, t1;
26
38
  return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => portableTextEditorRef.current, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), React__default.default.useImperativeHandle(ref, t0, t1), null;
27
39
  });
28
40
  EditorRefPlugin.displayName = "EditorRefPlugin";
29
- const asteriskPairRegex = "(?<!\\*)\\*(?!\\s)([^*\\n]+?)(?<!\\s)\\*(?!\\*)", underscorePairRegex = "(?<!_)_(?!\\s)([^_\\n]+?)(?<!\\s)_(?!_)", italicRegex = new RegExp(`(${asteriskPairRegex}|${underscorePairRegex})$`), doubleAsteriskPairRegex = "(?<!\\*)\\*\\*(?!\\s)([^*\\n]+?)(?<!\\s)\\*\\*(?!\\*)", doubleUnderscorePairRegex = "(?<!_)__(?!\\s)([^_\\n]+?)(?<!\\s)__(?!_)", boldRegex = new RegExp(`(${doubleAsteriskPairRegex}|${doubleUnderscorePairRegex})$`);
30
- function getTextToItalic(text) {
31
- return text.match(italicRegex)?.at(0);
32
- }
33
- function getTextToBold(text) {
34
- return text.match(boldRegex)?.at(0);
35
- }
36
- function useMarkdownEmphasisBehaviors(props) {
37
- const $ = reactCompilerRuntime.c(10), editor = plugin_eventListener.useEditor();
38
- let t0;
39
- $[0] !== editor || $[1] !== props.config ? (t0 = props.config.boldDecorator?.({
40
- schema: editor.getSnapshot().context.schema
41
- }), $[0] = editor, $[1] = props.config, $[2] = t0) : t0 = $[2];
42
- let t1;
43
- $[3] !== editor || $[4] !== props.config ? (t1 = props.config.italicDecorator?.({
44
- schema: editor.getSnapshot().context.schema
45
- }), $[3] = editor, $[4] = props.config, $[5] = t1) : t1 = $[5];
46
- let t2;
47
- $[6] !== editor || $[7] !== t0 || $[8] !== t1 ? (t2 = {
48
- input: {
49
- editor,
50
- boldDecorator: t0,
51
- italicDecorator: t1
52
- }
53
- }, $[6] = editor, $[7] = t0, $[8] = t1, $[9] = t2) : t2 = $[9], react.useActorRef(emphasisMachine, t2);
41
+ function createPairRegex(char, amount) {
42
+ const prePrefix = `(?<!\\${char})`, prefix = `\\${char}`.repeat(Math.max(amount, 1)), postPrefix = "(?!\\s)", content = `([^${char}\\n]+?)`, preSuffix = "(?<!\\s)", suffix = `\\${char}`.repeat(Math.max(amount, 1)), postSuffix = `(?!\\${char})`;
43
+ return `${prePrefix}${prefix}${postPrefix}${content}${preSuffix}${suffix}${postSuffix}`;
54
44
  }
55
- const emphasisListener = ({
56
- sendBack,
57
- input
58
- }) => input.editor.registerBehavior({
59
- behavior: behavior_core.defineBehavior({
45
+ function createDecoratorPairBehavior(config) {
46
+ config.pair.amount < 1 && console.warn("The amount of characters in the pair should be greater than 0");
47
+ const pairRegex = createPairRegex(config.pair.char, config.pair.amount), regEx = new RegExp(`(${pairRegex})$`);
48
+ return behavior_core.defineBehavior({
60
49
  on: "insert.text",
61
50
  guard: ({
62
- context,
51
+ snapshot,
63
52
  event
64
53
  }) => {
65
- const boldDecorator = input.boldDecorator, italicDecorator = input.italicDecorator;
66
- if (boldDecorator === void 0 && italicDecorator === void 0)
54
+ if (config.pair.amount < 1)
55
+ return !1;
56
+ const decorator = config.decorator({
57
+ schema: snapshot.context.schema
58
+ });
59
+ if (decorator === void 0)
67
60
  return !1;
68
- const focusTextBlock = selector_isAtTheStartOfBlock.getFocusTextBlock({
69
- context
70
- }), selectionStartPoint = selector_isAtTheStartOfBlock.getSelectionStartPoint({
71
- context
72
- }), selectionStartOffset = selectionStartPoint ? util_sliceBlocks.spanSelectionPointToBlockOffset({
73
- value: context.value,
61
+ const focusTextBlock = selector_isAtTheStartOfBlock.getFocusTextBlock(snapshot), selectionStartPoint = selector_isAtTheStartOfBlock.getSelectionStartPoint(snapshot), selectionStartOffset = selectionStartPoint ? util_sliceBlocks.spanSelectionPointToBlockOffset({
62
+ value: snapshot.context.value,
74
63
  selectionPoint: selectionStartPoint
75
64
  }) : void 0;
76
65
  if (!focusTextBlock || !selectionStartOffset)
77
66
  return !1;
78
- const textBefore = selector_getTextBefore.getBlockTextBefore({
79
- context
80
- }), textToItalic = getTextToItalic(`${textBefore}${event.text}`);
81
- if (textToItalic !== void 0 && italicDecorator !== void 0) {
82
- const prefixOffsets = {
83
- anchor: {
84
- path: focusTextBlock.path,
85
- // Example: "foo *bar*".length - "*bar*".length = 4
86
- offset: `${textBefore}${event.text}`.length - textToItalic.length
87
- },
88
- focus: {
89
- path: focusTextBlock.path,
90
- // Example: "foo *bar*".length - "*bar*".length + 1 = 5
91
- offset: `${textBefore}${event.text}`.length - textToItalic.length + 1
92
- }
93
- }, suffixOffsets = {
94
- anchor: {
95
- path: focusTextBlock.path,
96
- // Example: "foo *bar|" (8) + "*".length - 1 = 8
97
- offset: selectionStartOffset.offset + event.text.length - 1
98
- },
99
- focus: {
100
- path: focusTextBlock.path,
101
- // Example: "foo *bar|" (8) + "*".length = 9
102
- offset: selectionStartOffset.offset + event.text.length
103
- }
104
- };
105
- return {
106
- prefixOffsets,
107
- suffixOffsets,
108
- decorator: italicDecorator
109
- };
110
- }
111
- const textToBold = getTextToBold(`${textBefore}${event.text}`);
112
- if (textToBold !== void 0 && boldDecorator !== void 0) {
113
- const prefixOffsets = {
114
- anchor: {
115
- path: focusTextBlock.path,
116
- // Example: "foo **bar**".length - "**bar**".length = 4
117
- offset: `${textBefore}${event.text}`.length - textToBold.length
118
- },
119
- focus: {
120
- path: focusTextBlock.path,
121
- // Example: "foo **bar**".length - "**bar**".length + 2 = 6
122
- offset: `${textBefore}${event.text}`.length - textToBold.length + 2
123
- }
124
- }, prefixSelection = util_blockOffsetsToSelection.blockOffsetsToSelection({
125
- value: context.value,
67
+ const newText = `${selector_getTextBefore.getBlockTextBefore(snapshot)}${event.text}`, textToDecorate = newText.match(regEx)?.at(0);
68
+ if (textToDecorate === void 0)
69
+ return !1;
70
+ const prefixOffsets = {
71
+ anchor: {
72
+ path: focusTextBlock.path,
73
+ // Example: "foo **bar**".length - "**bar**".length = 4
74
+ offset: newText.length - textToDecorate.length
75
+ },
76
+ focus: {
77
+ path: focusTextBlock.path,
78
+ // Example: "foo **bar**".length - "**bar**".length + "*".length * 2 = 6
79
+ offset: newText.length - textToDecorate.length + config.pair.char.length * config.pair.amount
80
+ }
81
+ }, suffixOffsets = {
82
+ anchor: {
83
+ path: focusTextBlock.path,
84
+ // Example: "foo **bar*|" (10) + "*".length - 2 = 9
85
+ offset: selectionStartOffset.offset + event.text.length - config.pair.char.length * config.pair.amount
86
+ },
87
+ focus: {
88
+ path: focusTextBlock.path,
89
+ // Example: "foo **bar*|" (10) + "*".length = 11
90
+ offset: selectionStartOffset.offset + event.text.length
91
+ }
92
+ };
93
+ if (prefixOffsets.focus.offset - prefixOffsets.anchor.offset > 1) {
94
+ const prefixSelection = util_blockOffsetsToSelection.blockOffsetsToSelection({
95
+ value: snapshot.context.value,
126
96
  offsets: prefixOffsets
127
97
  }), inlineObjectBeforePrefixFocus = selector_isAtTheStartOfBlock.getPreviousInlineObject({
98
+ ...snapshot,
128
99
  context: {
129
- ...context,
100
+ ...snapshot.context,
130
101
  selection: prefixSelection ? {
131
102
  anchor: prefixSelection.focus,
132
103
  focus: prefixSelection.focus
133
104
  } : null
134
105
  }
135
106
  }), inlineObjectBeforePrefixFocusOffset = inlineObjectBeforePrefixFocus ? utils_index.childSelectionPointToBlockOffset({
136
- value: context.value,
107
+ value: snapshot.context.value,
137
108
  selectionPoint: {
138
109
  path: inlineObjectBeforePrefixFocus.path,
139
110
  offset: 0
@@ -141,68 +112,95 @@ const emphasisListener = ({
141
112
  }) : void 0;
142
113
  if (inlineObjectBeforePrefixFocusOffset && inlineObjectBeforePrefixFocusOffset.offset > prefixOffsets.anchor.offset && inlineObjectBeforePrefixFocusOffset.offset < prefixOffsets.focus.offset)
143
114
  return !1;
144
- const suffixOffsets = {
145
- anchor: {
146
- path: focusTextBlock.path,
147
- // Example: "foo **bar*|" (10) + "*".length - 2 = 9
148
- offset: selectionStartOffset.offset + event.text.length - 2
149
- },
150
- focus: {
151
- path: focusTextBlock.path,
152
- // Example: "foo **bar*|" (10) + "*".length = 11
153
- offset: selectionStartOffset.offset + event.text.length
154
- }
155
- }, previousInlineObject = selector_isAtTheStartOfBlock.getPreviousInlineObject({
156
- context
157
- }), previousInlineObjectOffset = previousInlineObject ? utils_index.childSelectionPointToBlockOffset({
158
- value: context.value,
115
+ }
116
+ if (suffixOffsets.focus.offset - suffixOffsets.anchor.offset > 1) {
117
+ const previousInlineObject = selector_isAtTheStartOfBlock.getPreviousInlineObject(snapshot), previousInlineObjectOffset = previousInlineObject ? utils_index.childSelectionPointToBlockOffset({
118
+ value: snapshot.context.value,
159
119
  selectionPoint: {
160
120
  path: previousInlineObject.path,
161
121
  offset: 0
162
122
  }
163
123
  }) : void 0;
164
- return previousInlineObjectOffset && previousInlineObjectOffset.offset > suffixOffsets.anchor.offset && previousInlineObjectOffset.offset < suffixOffsets.focus.offset ? !1 : {
165
- prefixOffsets,
166
- suffixOffsets,
167
- decorator: boldDecorator
168
- };
124
+ if (previousInlineObjectOffset && previousInlineObjectOffset.offset > suffixOffsets.anchor.offset && previousInlineObjectOffset.offset < suffixOffsets.focus.offset)
125
+ return !1;
169
126
  }
170
- return !1;
127
+ return {
128
+ prefixOffsets,
129
+ suffixOffsets,
130
+ decorator
131
+ };
171
132
  },
172
- actions: [({
173
- event
174
- }) => [event], (_, {
175
- prefixOffsets,
176
- suffixOffsets,
177
- decorator
178
- }) => [{
179
- type: "decorator.add",
180
- decorator,
181
- offsets: {
182
- anchor: prefixOffsets.focus,
183
- focus: suffixOffsets.anchor
184
- }
185
- }, {
186
- type: "delete.text",
187
- ...suffixOffsets
188
- }, {
189
- type: "delete.text",
190
- ...prefixOffsets
191
- }, {
192
- type: "decorator.remove",
193
- decorator
194
- }, {
195
- type: "effect",
196
- effect: () => {
197
- sendBack({
198
- type: "emphasis.add",
199
- blockOffset: {
200
- ...suffixOffsets.anchor,
201
- offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset)
133
+ actions: [
134
+ // Insert the text as usual in its own undo step
135
+ ({
136
+ event
137
+ }) => [event],
138
+ (_, {
139
+ prefixOffsets,
140
+ suffixOffsets,
141
+ decorator
142
+ }) => [
143
+ // Decorate the text between the prefix and suffix
144
+ {
145
+ type: "decorator.add",
146
+ decorator,
147
+ offsets: {
148
+ anchor: prefixOffsets.focus,
149
+ focus: suffixOffsets.anchor
202
150
  }
203
- });
204
- }
205
- }]]
151
+ },
152
+ // Delete the suffix
153
+ {
154
+ type: "delete.text",
155
+ ...suffixOffsets
156
+ },
157
+ // Delete the prefix
158
+ {
159
+ type: "delete.text",
160
+ ...prefixOffsets
161
+ },
162
+ // Toggle the decorator off so the next inserted text isn't emphasized
163
+ {
164
+ type: "decorator.remove",
165
+ decorator
166
+ },
167
+ {
168
+ type: "effect",
169
+ effect: () => {
170
+ config.onDecorate({
171
+ ...suffixOffsets.anchor,
172
+ offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset)
173
+ });
174
+ }
175
+ }
176
+ ]
177
+ ]
178
+ });
179
+ }
180
+ function DecoratorShortcutPlugin(config) {
181
+ const $ = reactCompilerRuntime.c(4), editor = editorProvider.useEditor();
182
+ let t0;
183
+ return $[0] !== config.decorator || $[1] !== config.pair || $[2] !== editor ? (t0 = {
184
+ input: {
185
+ editor,
186
+ decorator: config.decorator,
187
+ pair: config.pair
188
+ }
189
+ }, $[0] = config.decorator, $[1] = config.pair, $[2] = editor, $[3] = t0) : t0 = $[3], react.useActorRef(decoratorPairMachine, t0), null;
190
+ }
191
+ const emphasisListener = ({
192
+ sendBack,
193
+ input
194
+ }) => input.editor.registerBehavior({
195
+ behavior: createDecoratorPairBehavior({
196
+ decorator: input.decorator,
197
+ pair: input.pair,
198
+ onDecorate: (offset) => {
199
+ sendBack({
200
+ type: "emphasis.add",
201
+ blockOffset: offset
202
+ });
203
+ }
206
204
  })
207
205
  }), selectionListenerCallback = ({
208
206
  sendBack,
@@ -211,7 +209,7 @@ const emphasisListener = ({
211
209
  behavior: behavior_core.defineBehavior({
212
210
  on: "select",
213
211
  guard: ({
214
- context,
212
+ snapshot,
215
213
  event
216
214
  }) => {
217
215
  if (!event.selection)
@@ -219,10 +217,10 @@ const emphasisListener = ({
219
217
  blockOffsets: void 0
220
218
  };
221
219
  const anchor = util_sliceBlocks.spanSelectionPointToBlockOffset({
222
- value: context.value,
220
+ value: snapshot.context.value,
223
221
  selectionPoint: event.selection.anchor
224
222
  }), focus = util_sliceBlocks.spanSelectionPointToBlockOffset({
225
- value: context.value,
223
+ value: snapshot.context.value,
226
224
  selectionPoint: event.selection.focus
227
225
  });
228
226
  return !anchor || !focus ? {
@@ -263,7 +261,7 @@ const emphasisListener = ({
263
261
  }
264
262
  }]]
265
263
  })
266
- }), emphasisMachine = xstate.setup({
264
+ }), decoratorPairMachine = xstate.setup({
267
265
  types: {
268
266
  context: {},
269
267
  input: {},
@@ -275,13 +273,13 @@ const emphasisListener = ({
275
273
  "selection listener": xstate.fromCallback(selectionListenerCallback)
276
274
  }
277
275
  }).createMachine({
278
- id: "emphasis",
276
+ id: "decorator pair",
279
277
  context: ({
280
278
  input
281
279
  }) => ({
282
- boldDecorator: input.boldDecorator,
283
- italicDecorator: input.italicDecorator,
284
- editor: input.editor
280
+ decorator: input.decorator,
281
+ editor: input.editor,
282
+ pair: input.pair
285
283
  }),
286
284
  initial: "idle",
287
285
  states: {
@@ -291,9 +289,9 @@ const emphasisListener = ({
291
289
  input: ({
292
290
  context
293
291
  }) => ({
292
+ decorator: context.decorator,
294
293
  editor: context.editor,
295
- boldDecorator: context.boldDecorator,
296
- italicDecorator: context.italicDecorator
294
+ pair: context.pair
297
295
  })
298
296
  }],
299
297
  on: {
@@ -345,10 +343,8 @@ const emphasisListener = ({
345
343
  }
346
344
  });
347
345
  function MarkdownPlugin(props) {
348
- const editor = plugin_eventListener.useEditor();
349
- return useMarkdownEmphasisBehaviors({
350
- config: props.config
351
- }), React.useEffect(() => {
346
+ const editor = editorProvider.useEditor();
347
+ return React.useEffect(() => {
352
348
  const unregisterBehaviors = behavior_markdown.createMarkdownBehaviors(props.config).map((behavior) => editor.registerBehavior({
353
349
  behavior
354
350
  }));
@@ -356,7 +352,36 @@ function MarkdownPlugin(props) {
356
352
  for (const unregisterBehavior of unregisterBehaviors)
357
353
  unregisterBehavior();
358
354
  };
359
- }, [editor, props.config]), null;
355
+ }, [editor, props.config]), /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
356
+ props.config.boldDecorator ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
357
+ /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: {
358
+ char: "*",
359
+ amount: 2
360
+ } }),
361
+ /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: {
362
+ char: "_",
363
+ amount: 2
364
+ } })
365
+ ] }) : null,
366
+ props.config.codeDecorator ? /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.codeDecorator, pair: {
367
+ char: "`",
368
+ amount: 1
369
+ } }) : null,
370
+ props.config.italicDecorator ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
371
+ /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: {
372
+ char: "*",
373
+ amount: 1
374
+ } }),
375
+ /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: {
376
+ char: "_",
377
+ amount: 1
378
+ } })
379
+ ] }) : null,
380
+ props.config.strikeThroughDecorator ? /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.strikeThroughDecorator, pair: {
381
+ char: "~",
382
+ amount: 2
383
+ } }) : null
384
+ ] });
360
385
  }
361
386
  const oneLineBehaviors = [
362
387
  /**
@@ -366,11 +391,9 @@ const oneLineBehaviors = [
366
391
  behavior_core.defineBehavior({
367
392
  on: "insert.break",
368
393
  guard: ({
369
- context
370
- }) => context.selection && selector_isAtTheStartOfBlock.isSelectionExpanded({
371
- context
372
- }) ? {
373
- selection: context.selection
394
+ snapshot
395
+ }) => snapshot.context.selection && selector_isAtTheStartOfBlock.isSelectionExpanded(snapshot) ? {
396
+ selection: snapshot.context.selection
374
397
  } : !1,
375
398
  actions: [(_, {
376
399
  selection
@@ -409,17 +432,11 @@ const oneLineBehaviors = [
409
432
  behavior_core.defineBehavior({
410
433
  on: "insert.block",
411
434
  guard: ({
412
- context,
435
+ snapshot,
413
436
  event
414
437
  }) => {
415
- const focusTextBlock = selector_isAtTheStartOfBlock.getFocusTextBlock({
416
- context
417
- }), selectionStartPoint = selector_isAtTheStartOfBlock.getSelectionStartPoint({
418
- context
419
- }), selectionEndPoint = selector_isAtTheStartOfBlock.getSelectionEndPoint({
420
- context
421
- });
422
- if (!focusTextBlock || !utils_index.isTextBlock(context, event.block) || !selectionStartPoint || !selectionEndPoint)
438
+ const focusTextBlock = selector_isAtTheStartOfBlock.getFocusTextBlock(snapshot), selectionStartPoint = selector_isAtTheStartOfBlock.getSelectionStartPoint(snapshot), selectionEndPoint = selector_isAtTheStartOfBlock.getSelectionEndPoint(snapshot);
439
+ if (!focusTextBlock || !utils_index.isTextBlock(snapshot.context, event.block) || !selectionStartPoint || !selectionEndPoint)
423
440
  return !1;
424
441
  const blockStartPoint = util_sliceBlocks.getBlockStartPoint(focusTextBlock), blockEndPoint = util_sliceBlocks.getBlockEndPoint(focusTextBlock), newFocus = util_sliceBlocks.getBlockEndPoint({
425
442
  node: event.block,
@@ -459,31 +476,25 @@ const oneLineBehaviors = [
459
476
  behavior_core.defineBehavior({
460
477
  on: "insert.block",
461
478
  guard: ({
462
- context,
479
+ snapshot,
463
480
  event
464
481
  }) => {
465
- const focusTextBlock = selector_isAtTheStartOfBlock.getFocusTextBlock({
466
- context
467
- }), selectionStartPoint = selector_isAtTheStartOfBlock.getSelectionStartPoint({
468
- context
469
- }), selectionEndPoint = selector_isAtTheStartOfBlock.getSelectionEndPoint({
470
- context
471
- });
472
- if (!focusTextBlock || !utils_index.isTextBlock(context, event.block) || !selectionStartPoint || !selectionEndPoint)
482
+ const focusTextBlock = selector_isAtTheStartOfBlock.getFocusTextBlock(snapshot), selectionStartPoint = selector_isAtTheStartOfBlock.getSelectionStartPoint(snapshot), selectionEndPoint = selector_isAtTheStartOfBlock.getSelectionEndPoint(snapshot);
483
+ if (!focusTextBlock || !utils_index.isTextBlock(snapshot.context, event.block) || !selectionStartPoint || !selectionEndPoint)
473
484
  return !1;
474
485
  const blockBeforeStartPoint = utils_index.splitTextBlock({
475
- context,
486
+ context: snapshot.context,
476
487
  block: focusTextBlock.node,
477
488
  point: selectionStartPoint
478
489
  })?.before, blockAfterEndPoint = utils_index.splitTextBlock({
479
- context,
490
+ context: snapshot.context,
480
491
  block: focusTextBlock.node,
481
492
  point: selectionEndPoint
482
493
  })?.after;
483
494
  if (!blockBeforeStartPoint || !blockAfterEndPoint)
484
495
  return !1;
485
496
  const targetBlock = utils_index.mergeTextBlocks({
486
- context,
497
+ context: snapshot.context,
487
498
  targetBlock: blockBeforeStartPoint,
488
499
  incomingBlock: event.block
489
500
  }), newFocus = util_sliceBlocks.getBlockEndPoint({
@@ -492,7 +503,7 @@ const oneLineBehaviors = [
492
503
  _key: targetBlock._key
493
504
  }]
494
505
  }), mergedBlock = utils_index.mergeTextBlocks({
495
- context,
506
+ context: snapshot.context,
496
507
  targetBlock,
497
508
  incomingBlock: blockAfterEndPoint
498
509
  });
@@ -589,9 +600,9 @@ function OneLinePlugin() {
589
600
  let t0;
590
601
  return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsxRuntime.jsx(BehaviorPlugin, { behaviors: oneLineBehaviors }), $[0] = t0) : t0 = $[0], t0;
591
602
  }
592
- exports.EventListenerPlugin = plugin_eventListener.EventListenerPlugin;
593
603
  exports.BehaviorPlugin = BehaviorPlugin;
594
604
  exports.EditorRefPlugin = EditorRefPlugin;
605
+ exports.EventListenerPlugin = EventListenerPlugin;
595
606
  exports.MarkdownPlugin = MarkdownPlugin;
596
607
  exports.OneLinePlugin = OneLinePlugin;
597
608
  //# sourceMappingURL=index.cjs.map