@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.
- package/lib/_chunks-cjs/behavior.core.cjs +57 -118
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/behavior.markdown.cjs +27 -67
- package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
- package/lib/_chunks-cjs/{plugin.event-listener.cjs → editor-provider.cjs} +101 -87
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -0
- package/lib/_chunks-cjs/selector.get-text-before.cjs +5 -7
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-active-style.cjs +22 -36
- package/lib/_chunks-cjs/selector.is-active-style.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +68 -153
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -1
- package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +1 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +57 -118
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +27 -67
- package/lib/_chunks-es/behavior.markdown.js.map +1 -1
- package/lib/_chunks-es/{plugin.event-listener.js → editor-provider.js} +102 -88
- package/lib/_chunks-es/editor-provider.js.map +1 -0
- package/lib/_chunks-es/selector.get-text-before.js +5 -7
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/selector.is-active-style.js +22 -36
- package/lib/_chunks-es/selector.is-active-style.js.map +1 -1
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js +68 -153
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
- package/lib/_chunks-es/util.block-offsets-to-selection.js.map +1 -1
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/behaviors/index.cjs +18 -48
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +19392 -214
- package/lib/behaviors/index.d.ts +19392 -214
- package/lib/behaviors/index.js +18 -48
- package/lib/behaviors/index.js.map +1 -1
- package/lib/index.cjs +81 -51
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +334 -59
- package/lib/index.d.ts +334 -59
- package/lib/index.js +35 -4
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +200 -189
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +344 -25
- package/lib/plugins/index.d.ts +344 -25
- package/lib/plugins/index.js +198 -187
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.cjs +22 -50
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +19485 -174
- package/lib/selectors/index.d.ts +19485 -174
- package/lib/selectors/index.js +22 -50
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +19518 -7
- package/lib/utils/index.d.ts +19518 -7
- package/lib/utils/index.js.map +1 -1
- package/package.json +7 -7
- package/src/behavior-actions/behavior.action.decorator.add.ts +1 -0
- package/src/behavior-actions/behavior.action.delete.text.ts +1 -0
- package/src/behaviors/behavior.code-editor.ts +6 -6
- package/src/behaviors/behavior.core.annotations.ts +5 -4
- package/src/behaviors/behavior.core.block-objects.ts +17 -17
- package/src/behaviors/behavior.core.decorators.ts +12 -8
- package/src/behaviors/behavior.core.insert-break.ts +27 -29
- package/src/behaviors/behavior.core.lists.ts +19 -19
- package/src/behaviors/behavior.decorator-pair.ts +201 -0
- package/src/behaviors/behavior.default.ts +35 -30
- package/src/behaviors/behavior.emoji-picker.ts +12 -12
- package/src/behaviors/behavior.links.ts +7 -7
- package/src/behaviors/behavior.markdown.ts +41 -42
- package/src/behaviors/behavior.types.ts +14 -17
- package/src/behaviors/index.ts +0 -1
- package/src/converters/converter.json.ts +6 -6
- package/src/converters/converter.portable-text.deserialize.test.ts +27 -29
- package/src/converters/converter.portable-text.ts +13 -7
- package/src/converters/converter.text-html.deserialize.test.ts +16 -18
- package/src/converters/converter.text-html.serialize.test.ts +56 -57
- package/src/converters/converter.text-html.ts +14 -10
- package/src/converters/converter.text-plain.test.ts +17 -17
- package/src/converters/converter.text-plain.ts +15 -11
- package/src/converters/converter.types.ts +5 -5
- package/src/editor/Editable.tsx +26 -0
- package/src/editor/editor-machine.ts +170 -142
- package/src/editor/editor-selector.ts +3 -0
- package/src/editor/editor-snapshot.ts +13 -0
- package/src/editor-event-listener.tsx +30 -0
- package/src/index.ts +3 -3
- package/src/internal-utils/create-test-snapshot.ts +23 -0
- package/src/internal-utils/get-text-to-emphasize.ts +29 -7
- package/src/plugins/plugin.decorator-shortcut.ts +235 -0
- package/src/plugins/plugin.markdown.tsx +56 -8
- package/src/plugins/plugin.one-line.tsx +17 -17
- package/src/selectors/selector.get-active-annotations.test.ts +4 -13
- package/src/selectors/selector.get-active-list-item.ts +4 -4
- package/src/selectors/selector.get-active-style.ts +6 -6
- package/src/selectors/selector.get-anchor-block.ts +5 -5
- package/src/selectors/selector.get-anchor-child.ts +5 -5
- package/src/selectors/selector.get-anchor-span.ts +2 -2
- package/src/selectors/selector.get-anchor-text-block.ts +2 -2
- package/src/selectors/selector.get-block-offsets.ts +8 -7
- package/src/selectors/selector.get-caret-word-selection.test.ts +3 -7
- package/src/selectors/selector.get-caret-word-selection.ts +19 -16
- package/src/selectors/selector.get-next-inline-object.ts +4 -4
- package/src/selectors/selector.get-previous-inline-object.ts +4 -4
- package/src/selectors/selector.get-selected-slice.ts +7 -4
- package/src/selectors/selector.get-selected-spans.test.ts +5 -9
- package/src/selectors/selector.get-selected-spans.ts +9 -9
- package/src/selectors/selector.get-selection-end-point.ts +5 -5
- package/src/selectors/selector.get-selection-start-point.ts +5 -5
- package/src/selectors/selector.get-selection-text.test.ts +5 -7
- package/src/selectors/selector.get-selection-text.ts +2 -2
- package/src/selectors/selector.get-selection.ts +2 -2
- package/src/selectors/selector.get-text-before.ts +8 -8
- package/src/selectors/selector.get-trimmed-selection.test.ts +3 -5
- package/src/selectors/selector.get-trimmed-selection.ts +15 -13
- package/src/selectors/selector.get-value.ts +4 -4
- package/src/selectors/selector.is-active-decorator.test.ts +5 -9
- package/src/selectors/selector.is-at-the-end-of-block.ts +6 -3
- package/src/selectors/selector.is-at-the-start-of-block.ts +3 -3
- package/src/selectors/selector.is-overlapping-selection.ts +8 -6
- package/src/selectors/selector.is-selection-collapsed.ts +6 -5
- package/src/selectors/selector.is-selection-expanded.ts +2 -2
- package/src/selectors/selectors.ts +59 -59
- package/src/types/block-offset.ts +9 -0
- package/src/utils/index.ts +0 -1
- package/src/utils/util.block-offset.ts +1 -1
- package/src/utils/util.block-offsets-to-selection.ts +1 -1
- package/src/utils/util.child-selection-point-to-block-offset.ts +1 -1
- package/lib/_chunks-cjs/plugin.event-listener.cjs.map +0 -1
- package/lib/_chunks-es/plugin.event-listener.js.map +0 -1
- package/src/behaviors/behavior.markdown-emphasis.ts +0 -437
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import {useActorRef} from '@xstate/react'
|
|
2
|
+
import {isEqual} from 'lodash'
|
|
3
|
+
import {
|
|
4
|
+
assign,
|
|
5
|
+
fromCallback,
|
|
6
|
+
setup,
|
|
7
|
+
type AnyEventObject,
|
|
8
|
+
type CallbackLogicFunction,
|
|
9
|
+
} from 'xstate'
|
|
10
|
+
import {createDecoratorPairBehavior} from '../behaviors/behavior.decorator-pair'
|
|
11
|
+
import {defineBehavior} from '../behaviors/behavior.types'
|
|
12
|
+
import type {Editor} from '../editor/create-editor'
|
|
13
|
+
import {useEditor} from '../editor/editor-provider'
|
|
14
|
+
import type {EditorSchema} from '../selectors'
|
|
15
|
+
import type {BlockOffset} from '../types/block-offset'
|
|
16
|
+
import * as utils from '../utils'
|
|
17
|
+
|
|
18
|
+
export function DecoratorShortcutPlugin(config: {
|
|
19
|
+
decorator: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
20
|
+
pair: {char: string; amount: number}
|
|
21
|
+
}) {
|
|
22
|
+
const editor = useEditor()
|
|
23
|
+
|
|
24
|
+
useActorRef(decoratorPairMachine, {
|
|
25
|
+
input: {
|
|
26
|
+
editor,
|
|
27
|
+
decorator: config.decorator,
|
|
28
|
+
pair: config.pair,
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type MarkdownEmphasisEvent =
|
|
36
|
+
| {
|
|
37
|
+
type: 'emphasis.add'
|
|
38
|
+
blockOffset: BlockOffset
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
type: 'selection'
|
|
42
|
+
blockOffsets?: {
|
|
43
|
+
anchor: BlockOffset
|
|
44
|
+
focus: BlockOffset
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
| {
|
|
48
|
+
type: 'delete.backward'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const emphasisListener: CallbackLogicFunction<
|
|
52
|
+
AnyEventObject,
|
|
53
|
+
MarkdownEmphasisEvent,
|
|
54
|
+
{
|
|
55
|
+
decorator: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
56
|
+
editor: Editor
|
|
57
|
+
pair: {char: string; amount: number}
|
|
58
|
+
}
|
|
59
|
+
> = ({sendBack, input}) => {
|
|
60
|
+
const unregister = input.editor.registerBehavior({
|
|
61
|
+
behavior: createDecoratorPairBehavior({
|
|
62
|
+
decorator: input.decorator,
|
|
63
|
+
pair: input.pair,
|
|
64
|
+
onDecorate: (offset) => {
|
|
65
|
+
sendBack({type: 'emphasis.add', blockOffset: offset})
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return unregister
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const selectionListenerCallback: CallbackLogicFunction<
|
|
74
|
+
AnyEventObject,
|
|
75
|
+
MarkdownEmphasisEvent,
|
|
76
|
+
{editor: Editor}
|
|
77
|
+
> = ({sendBack, input}) => {
|
|
78
|
+
const unregister = input.editor.registerBehavior({
|
|
79
|
+
behavior: defineBehavior({
|
|
80
|
+
on: 'select',
|
|
81
|
+
guard: ({snapshot, event}) => {
|
|
82
|
+
if (!event.selection) {
|
|
83
|
+
return {blockOffsets: undefined}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const anchor = utils.spanSelectionPointToBlockOffset({
|
|
87
|
+
value: snapshot.context.value,
|
|
88
|
+
selectionPoint: event.selection.anchor,
|
|
89
|
+
})
|
|
90
|
+
const focus = utils.spanSelectionPointToBlockOffset({
|
|
91
|
+
value: snapshot.context.value,
|
|
92
|
+
selectionPoint: event.selection.focus,
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
if (!anchor || !focus) {
|
|
96
|
+
return {blockOffsets: undefined}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
blockOffsets: {
|
|
101
|
+
anchor,
|
|
102
|
+
focus,
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
actions: [
|
|
107
|
+
(_, {blockOffsets}) => [
|
|
108
|
+
{
|
|
109
|
+
type: 'effect',
|
|
110
|
+
effect: () => {
|
|
111
|
+
sendBack({type: 'selection', blockOffsets})
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
],
|
|
116
|
+
}),
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
return unregister
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const deleteBackwardListenerCallback: CallbackLogicFunction<
|
|
123
|
+
AnyEventObject,
|
|
124
|
+
MarkdownEmphasisEvent,
|
|
125
|
+
{editor: Editor}
|
|
126
|
+
> = ({sendBack, input}) => {
|
|
127
|
+
const unregister = input.editor.registerBehavior({
|
|
128
|
+
behavior: defineBehavior({
|
|
129
|
+
on: 'delete.backward',
|
|
130
|
+
actions: [
|
|
131
|
+
() => [
|
|
132
|
+
{
|
|
133
|
+
type: 'history.undo',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
type: 'effect',
|
|
137
|
+
effect: () => {
|
|
138
|
+
sendBack({type: 'delete.backward'})
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
],
|
|
143
|
+
}),
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
return unregister
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const decoratorPairMachine = setup({
|
|
150
|
+
types: {
|
|
151
|
+
context: {} as {
|
|
152
|
+
decorator: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
153
|
+
editor: Editor
|
|
154
|
+
offsetAfterEmphasis?: BlockOffset
|
|
155
|
+
pair: {char: string; amount: number}
|
|
156
|
+
},
|
|
157
|
+
input: {} as {
|
|
158
|
+
decorator: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
159
|
+
editor: Editor
|
|
160
|
+
pair: {char: string; amount: number}
|
|
161
|
+
},
|
|
162
|
+
events: {} as MarkdownEmphasisEvent,
|
|
163
|
+
},
|
|
164
|
+
actors: {
|
|
165
|
+
'emphasis listener': fromCallback(emphasisListener),
|
|
166
|
+
'delete.backward listener': fromCallback(deleteBackwardListenerCallback),
|
|
167
|
+
'selection listener': fromCallback(selectionListenerCallback),
|
|
168
|
+
},
|
|
169
|
+
}).createMachine({
|
|
170
|
+
id: 'decorator pair',
|
|
171
|
+
context: ({input}) => ({
|
|
172
|
+
decorator: input.decorator,
|
|
173
|
+
editor: input.editor,
|
|
174
|
+
pair: input.pair,
|
|
175
|
+
}),
|
|
176
|
+
initial: 'idle',
|
|
177
|
+
states: {
|
|
178
|
+
'idle': {
|
|
179
|
+
invoke: [
|
|
180
|
+
{
|
|
181
|
+
src: 'emphasis listener',
|
|
182
|
+
input: ({context}) => ({
|
|
183
|
+
decorator: context.decorator,
|
|
184
|
+
editor: context.editor,
|
|
185
|
+
pair: context.pair,
|
|
186
|
+
}),
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
on: {
|
|
190
|
+
'emphasis.add': {
|
|
191
|
+
target: 'emphasis added',
|
|
192
|
+
actions: assign({
|
|
193
|
+
offsetAfterEmphasis: ({event}) => event.blockOffset,
|
|
194
|
+
}),
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
'emphasis added': {
|
|
199
|
+
exit: [
|
|
200
|
+
assign({
|
|
201
|
+
offsetAfterEmphasis: undefined,
|
|
202
|
+
}),
|
|
203
|
+
],
|
|
204
|
+
invoke: [
|
|
205
|
+
{
|
|
206
|
+
src: 'selection listener',
|
|
207
|
+
input: ({context}) => ({editor: context.editor}),
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
src: 'delete.backward listener',
|
|
211
|
+
input: ({context}) => ({editor: context.editor}),
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
on: {
|
|
215
|
+
'selection': {
|
|
216
|
+
target: 'idle',
|
|
217
|
+
guard: ({context, event}) => {
|
|
218
|
+
const selectionChanged = !isEqual(
|
|
219
|
+
{
|
|
220
|
+
anchor: context.offsetAfterEmphasis,
|
|
221
|
+
focus: context.offsetAfterEmphasis,
|
|
222
|
+
},
|
|
223
|
+
event.blockOffsets,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
return selectionChanged
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
'delete.backward': {
|
|
230
|
+
target: 'idle',
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
})
|
|
@@ -3,17 +3,23 @@ import {
|
|
|
3
3
|
createMarkdownBehaviors,
|
|
4
4
|
type MarkdownBehaviorsConfig,
|
|
5
5
|
} from '../behaviors/behavior.markdown'
|
|
6
|
-
import {
|
|
7
|
-
useMarkdownEmphasisBehaviors,
|
|
8
|
-
type MarkdownEmphasisBehaviorsConfig,
|
|
9
|
-
} from '../behaviors/behavior.markdown-emphasis'
|
|
6
|
+
import type {EditorSchema} from '../editor/define-schema'
|
|
10
7
|
import {useEditor} from '../editor/editor-provider'
|
|
8
|
+
import {DecoratorShortcutPlugin} from './plugin.decorator-shortcut'
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* @beta
|
|
14
12
|
*/
|
|
15
|
-
export type MarkdownPluginConfig = MarkdownBehaviorsConfig &
|
|
16
|
-
|
|
13
|
+
export type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
|
|
14
|
+
boldDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
15
|
+
codeDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
16
|
+
italicDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
|
|
17
|
+
strikeThroughDecorator?: ({
|
|
18
|
+
schema,
|
|
19
|
+
}: {
|
|
20
|
+
schema: EditorSchema
|
|
21
|
+
}) => string | undefined
|
|
22
|
+
}
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* @beta
|
|
@@ -32,8 +38,12 @@ export type MarkdownPluginConfig = MarkdownBehaviorsConfig &
|
|
|
32
38
|
* config={{
|
|
33
39
|
* boldDecorator: ({schema}) =>
|
|
34
40
|
* schema.decorators.find((decorator) => decorator.value === 'strong')?.value,
|
|
41
|
+
* codeDecorator: ({schema}) =>
|
|
42
|
+
* schema.decorators.find((decorator) => decorator.value === 'code')?.value,
|
|
35
43
|
* italicDecorator: ({schema}) =>
|
|
36
44
|
* schema.decorators.find((decorator) => decorator.value === 'em')?.value,
|
|
45
|
+
* strikeThroughDecorator: ({schema}) =>
|
|
46
|
+
* schema.decorators.find((decorator) => decorator.value === 'strike-through')?.value,
|
|
37
47
|
* horizontalRuleObject: ({schema}) => {
|
|
38
48
|
* const name = schema.blockObjects.find(
|
|
39
49
|
* (object) => object.name === 'break',
|
|
@@ -60,7 +70,6 @@ export type MarkdownPluginConfig = MarkdownBehaviorsConfig &
|
|
|
60
70
|
*/
|
|
61
71
|
export function MarkdownPlugin(props: {config: MarkdownPluginConfig}) {
|
|
62
72
|
const editor = useEditor()
|
|
63
|
-
useMarkdownEmphasisBehaviors({config: props.config})
|
|
64
73
|
|
|
65
74
|
useEffect(() => {
|
|
66
75
|
const behaviors = createMarkdownBehaviors(props.config)
|
|
@@ -76,5 +85,44 @@ export function MarkdownPlugin(props: {config: MarkdownPluginConfig}) {
|
|
|
76
85
|
}
|
|
77
86
|
}, [editor, props.config])
|
|
78
87
|
|
|
79
|
-
return
|
|
88
|
+
return (
|
|
89
|
+
<>
|
|
90
|
+
{props.config.boldDecorator ? (
|
|
91
|
+
<>
|
|
92
|
+
<DecoratorShortcutPlugin
|
|
93
|
+
decorator={props.config.boldDecorator}
|
|
94
|
+
pair={{char: '*', amount: 2}}
|
|
95
|
+
/>
|
|
96
|
+
<DecoratorShortcutPlugin
|
|
97
|
+
decorator={props.config.boldDecorator}
|
|
98
|
+
pair={{char: '_', amount: 2}}
|
|
99
|
+
/>
|
|
100
|
+
</>
|
|
101
|
+
) : null}
|
|
102
|
+
{props.config.codeDecorator ? (
|
|
103
|
+
<DecoratorShortcutPlugin
|
|
104
|
+
decorator={props.config.codeDecorator}
|
|
105
|
+
pair={{char: '`', amount: 1}}
|
|
106
|
+
/>
|
|
107
|
+
) : null}
|
|
108
|
+
{props.config.italicDecorator ? (
|
|
109
|
+
<>
|
|
110
|
+
<DecoratorShortcutPlugin
|
|
111
|
+
decorator={props.config.italicDecorator}
|
|
112
|
+
pair={{char: '*', amount: 1}}
|
|
113
|
+
/>
|
|
114
|
+
<DecoratorShortcutPlugin
|
|
115
|
+
decorator={props.config.italicDecorator}
|
|
116
|
+
pair={{char: '_', amount: 1}}
|
|
117
|
+
/>
|
|
118
|
+
</>
|
|
119
|
+
) : null}
|
|
120
|
+
{props.config.strikeThroughDecorator ? (
|
|
121
|
+
<DecoratorShortcutPlugin
|
|
122
|
+
decorator={props.config.strikeThroughDecorator}
|
|
123
|
+
pair={{char: '~', amount: 2}}
|
|
124
|
+
/>
|
|
125
|
+
) : null}
|
|
126
|
+
</>
|
|
127
|
+
)
|
|
80
128
|
}
|
|
@@ -10,9 +10,9 @@ const oneLineBehaviors = [
|
|
|
10
10
|
*/
|
|
11
11
|
defineBehavior({
|
|
12
12
|
on: 'insert.break',
|
|
13
|
-
guard: ({
|
|
14
|
-
context.selection && selectors.isSelectionExpanded(
|
|
15
|
-
? {selection: context.selection}
|
|
13
|
+
guard: ({snapshot}) =>
|
|
14
|
+
snapshot.context.selection && selectors.isSelectionExpanded(snapshot)
|
|
15
|
+
? {selection: snapshot.context.selection}
|
|
16
16
|
: false,
|
|
17
17
|
actions: [(_, {selection}) => [{type: 'delete', selection}]],
|
|
18
18
|
}),
|
|
@@ -40,14 +40,14 @@ const oneLineBehaviors = [
|
|
|
40
40
|
*/
|
|
41
41
|
defineBehavior({
|
|
42
42
|
on: 'insert.block',
|
|
43
|
-
guard: ({
|
|
44
|
-
const focusTextBlock = selectors.getFocusTextBlock(
|
|
45
|
-
const selectionStartPoint = selectors.getSelectionStartPoint(
|
|
46
|
-
const selectionEndPoint = selectors.getSelectionEndPoint(
|
|
43
|
+
guard: ({snapshot, event}) => {
|
|
44
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
45
|
+
const selectionStartPoint = selectors.getSelectionStartPoint(snapshot)
|
|
46
|
+
const selectionEndPoint = selectors.getSelectionEndPoint(snapshot)
|
|
47
47
|
|
|
48
48
|
if (
|
|
49
49
|
!focusTextBlock ||
|
|
50
|
-
!utils.isTextBlock(context, event.block) ||
|
|
50
|
+
!utils.isTextBlock(snapshot.context, event.block) ||
|
|
51
51
|
!selectionStartPoint ||
|
|
52
52
|
!selectionEndPoint
|
|
53
53
|
) {
|
|
@@ -90,14 +90,14 @@ const oneLineBehaviors = [
|
|
|
90
90
|
*/
|
|
91
91
|
defineBehavior({
|
|
92
92
|
on: 'insert.block',
|
|
93
|
-
guard: ({
|
|
94
|
-
const focusTextBlock = selectors.getFocusTextBlock(
|
|
95
|
-
const selectionStartPoint = selectors.getSelectionStartPoint(
|
|
96
|
-
const selectionEndPoint = selectors.getSelectionEndPoint(
|
|
93
|
+
guard: ({snapshot, event}) => {
|
|
94
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
95
|
+
const selectionStartPoint = selectors.getSelectionStartPoint(snapshot)
|
|
96
|
+
const selectionEndPoint = selectors.getSelectionEndPoint(snapshot)
|
|
97
97
|
|
|
98
98
|
if (
|
|
99
99
|
!focusTextBlock ||
|
|
100
|
-
!utils.isTextBlock(context, event.block) ||
|
|
100
|
+
!utils.isTextBlock(snapshot.context, event.block) ||
|
|
101
101
|
!selectionStartPoint ||
|
|
102
102
|
!selectionEndPoint
|
|
103
103
|
) {
|
|
@@ -105,12 +105,12 @@ const oneLineBehaviors = [
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
const blockBeforeStartPoint = utils.splitTextBlock({
|
|
108
|
-
context,
|
|
108
|
+
context: snapshot.context,
|
|
109
109
|
block: focusTextBlock.node,
|
|
110
110
|
point: selectionStartPoint,
|
|
111
111
|
})?.before
|
|
112
112
|
const blockAfterEndPoint = utils.splitTextBlock({
|
|
113
|
-
context,
|
|
113
|
+
context: snapshot.context,
|
|
114
114
|
block: focusTextBlock.node,
|
|
115
115
|
point: selectionEndPoint,
|
|
116
116
|
})?.after
|
|
@@ -120,7 +120,7 @@ const oneLineBehaviors = [
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
const targetBlock = utils.mergeTextBlocks({
|
|
123
|
-
context,
|
|
123
|
+
context: snapshot.context,
|
|
124
124
|
targetBlock: blockBeforeStartPoint,
|
|
125
125
|
incomingBlock: event.block,
|
|
126
126
|
})
|
|
@@ -131,7 +131,7 @@ const oneLineBehaviors = [
|
|
|
131
131
|
})
|
|
132
132
|
|
|
133
133
|
const mergedBlock = utils.mergeTextBlocks({
|
|
134
|
-
context,
|
|
134
|
+
context: snapshot.context,
|
|
135
135
|
targetBlock,
|
|
136
136
|
incomingBlock: blockAfterEndPoint,
|
|
137
137
|
})
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import type {PortableTextBlock} from '@sanity/types'
|
|
2
2
|
import {expect, test} from 'vitest'
|
|
3
|
-
import
|
|
4
|
-
import type {EditorSnapshot} from '../editor/editor-snapshot'
|
|
5
|
-
import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
|
|
3
|
+
import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
|
|
6
4
|
import type {EditorSelection} from '../utils'
|
|
7
5
|
import {getActiveAnnotations} from './selector.get-active-annotations'
|
|
8
6
|
|
|
9
|
-
function snapshot(
|
|
10
|
-
|
|
11
|
-
selection: EditorSelection,
|
|
12
|
-
): EditorSnapshot {
|
|
13
|
-
return {
|
|
7
|
+
function snapshot(value: Array<PortableTextBlock>, selection: EditorSelection) {
|
|
8
|
+
return createTestSnapshot({
|
|
14
9
|
context: {
|
|
15
|
-
converters: [],
|
|
16
|
-
schema: {} as EditorSchema,
|
|
17
|
-
keyGenerator: createTestKeyGenerator(),
|
|
18
|
-
activeDecorators: [],
|
|
19
10
|
value,
|
|
20
11
|
selection,
|
|
21
12
|
},
|
|
22
|
-
}
|
|
13
|
+
})
|
|
23
14
|
}
|
|
24
15
|
|
|
25
16
|
const link = {
|
|
@@ -8,13 +8,13 @@ import {getSelectedBlocks} from './selectors'
|
|
|
8
8
|
*/
|
|
9
9
|
export const getActiveListItem: EditorSelector<
|
|
10
10
|
PortableTextListBlock['listItem'] | undefined
|
|
11
|
-
> = (
|
|
12
|
-
if (!context.selection) {
|
|
11
|
+
> = (snapshot) => {
|
|
12
|
+
if (!snapshot.context.selection) {
|
|
13
13
|
return undefined
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const guards = createGuards(context)
|
|
17
|
-
const selectedBlocks = getSelectedBlocks(
|
|
16
|
+
const guards = createGuards(snapshot.context)
|
|
17
|
+
const selectedBlocks = getSelectedBlocks(snapshot).map((block) => block.node)
|
|
18
18
|
const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)
|
|
19
19
|
|
|
20
20
|
const firstTextBlock = selectedTextBlocks.at(0)
|
|
@@ -6,15 +6,15 @@ import {getSelectedBlocks} from './selectors'
|
|
|
6
6
|
/**
|
|
7
7
|
* @public
|
|
8
8
|
*/
|
|
9
|
-
export const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!context.selection) {
|
|
9
|
+
export const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = (
|
|
10
|
+
snapshot,
|
|
11
|
+
) => {
|
|
12
|
+
if (!snapshot.context.selection) {
|
|
13
13
|
return undefined
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const guards = createGuards(context)
|
|
17
|
-
const selectedBlocks = getSelectedBlocks(
|
|
16
|
+
const guards = createGuards(snapshot.context)
|
|
17
|
+
const selectedBlocks = getSelectedBlocks(snapshot).map((block) => block.node)
|
|
18
18
|
const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)
|
|
19
19
|
|
|
20
20
|
const firstTextBlock = selectedTextBlocks.at(0)
|
|
@@ -7,15 +7,15 @@ import {isKeyedSegment} from '../utils'
|
|
|
7
7
|
*/
|
|
8
8
|
export const getAnchorBlock: EditorSelector<
|
|
9
9
|
{node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
10
|
-
> = (
|
|
11
|
-
const key = context.selection
|
|
12
|
-
? isKeyedSegment(context.selection.anchor.path[0])
|
|
13
|
-
? context.selection.anchor.path[0]._key
|
|
10
|
+
> = (snapshot) => {
|
|
11
|
+
const key = snapshot.context.selection
|
|
12
|
+
? isKeyedSegment(snapshot.context.selection.anchor.path[0])
|
|
13
|
+
? snapshot.context.selection.anchor.path[0]._key
|
|
14
14
|
: undefined
|
|
15
15
|
: undefined
|
|
16
16
|
|
|
17
17
|
const node = key
|
|
18
|
-
? context.value.find((block) => block._key === key)
|
|
18
|
+
? snapshot.context.value.find((block) => block._key === key)
|
|
19
19
|
: undefined
|
|
20
20
|
|
|
21
21
|
return node && key ? {node, path: [{_key: key}]} : undefined
|
|
@@ -13,16 +13,16 @@ export const getAnchorChild: EditorSelector<
|
|
|
13
13
|
path: [KeyedSegment, 'children', KeyedSegment]
|
|
14
14
|
}
|
|
15
15
|
| undefined
|
|
16
|
-
> = (
|
|
17
|
-
const anchorBlock = getAnchorTextBlock(
|
|
16
|
+
> = (snapshot) => {
|
|
17
|
+
const anchorBlock = getAnchorTextBlock(snapshot)
|
|
18
18
|
|
|
19
19
|
if (!anchorBlock) {
|
|
20
20
|
return undefined
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const key = context.selection
|
|
24
|
-
? isKeyedSegment(context.selection.anchor.path[2])
|
|
25
|
-
? context.selection.anchor.path[2]._key
|
|
23
|
+
const key = snapshot.context.selection
|
|
24
|
+
? isKeyedSegment(snapshot.context.selection.anchor.path[2])
|
|
25
|
+
? snapshot.context.selection.anchor.path[2]._key
|
|
26
26
|
: undefined
|
|
27
27
|
: undefined
|
|
28
28
|
|
|
@@ -9,8 +9,8 @@ import {getAnchorChild} from './selector.get-anchor-child'
|
|
|
9
9
|
export const getAnchorSpan: EditorSelector<
|
|
10
10
|
| {node: PortableTextSpan; path: [KeyedSegment, 'children', KeyedSegment]}
|
|
11
11
|
| undefined
|
|
12
|
-
> = (
|
|
13
|
-
const anchorChild = getAnchorChild(
|
|
12
|
+
> = (snapshot) => {
|
|
13
|
+
const anchorChild = getAnchorChild(snapshot)
|
|
14
14
|
|
|
15
15
|
return anchorChild && isPortableTextSpan(anchorChild.node)
|
|
16
16
|
? {node: anchorChild.node, path: anchorChild.path}
|
|
@@ -11,8 +11,8 @@ import {getAnchorBlock} from './selector.get-anchor-block'
|
|
|
11
11
|
*/
|
|
12
12
|
export const getAnchorTextBlock: EditorSelector<
|
|
13
13
|
{node: PortableTextTextBlock; path: [KeyedSegment]} | undefined
|
|
14
|
-
> = (
|
|
15
|
-
const anchorBlock = getAnchorBlock(
|
|
14
|
+
> = (snapshot) => {
|
|
15
|
+
const anchorBlock = getAnchorBlock(snapshot)
|
|
16
16
|
|
|
17
17
|
return anchorBlock && isPortableTextTextBlock(anchorBlock.node)
|
|
18
18
|
? {node: anchorBlock.node, path: anchorBlock.path}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
2
|
+
import type {BlockOffset} from '../types/block-offset'
|
|
2
3
|
import * as utils from '../utils'
|
|
3
4
|
import {getSelectionEndPoint} from './selector.get-selection-end-point'
|
|
4
5
|
import {getSelectionStartPoint} from './selector.get-selection-start-point'
|
|
@@ -7,25 +8,25 @@ import {getSelectionStartPoint} from './selector.get-selection-start-point'
|
|
|
7
8
|
* @public
|
|
8
9
|
*/
|
|
9
10
|
export const getBlockOffsets: EditorSelector<
|
|
10
|
-
{start:
|
|
11
|
-
> = (
|
|
12
|
-
if (!context.selection) {
|
|
11
|
+
{start: BlockOffset; end: BlockOffset} | undefined
|
|
12
|
+
> = (snapshot) => {
|
|
13
|
+
if (!snapshot.context.selection) {
|
|
13
14
|
return undefined
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const selectionStartPoint = getSelectionStartPoint(
|
|
17
|
-
const selectionEndPoint = getSelectionEndPoint(
|
|
17
|
+
const selectionStartPoint = getSelectionStartPoint(snapshot)
|
|
18
|
+
const selectionEndPoint = getSelectionEndPoint(snapshot)
|
|
18
19
|
|
|
19
20
|
if (!selectionStartPoint || !selectionEndPoint) {
|
|
20
21
|
return undefined
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const start = utils.spanSelectionPointToBlockOffset({
|
|
24
|
-
value: context.value,
|
|
25
|
+
value: snapshot.context.value,
|
|
25
26
|
selectionPoint: selectionStartPoint,
|
|
26
27
|
})
|
|
27
28
|
const end = utils.spanSelectionPointToBlockOffset({
|
|
28
|
-
value: context.value,
|
|
29
|
+
value: snapshot.context.value,
|
|
29
30
|
selectionPoint: selectionEndPoint,
|
|
30
31
|
})
|
|
31
32
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type {PortableTextBlock} from '@sanity/types'
|
|
2
2
|
import {describe, expect, test} from 'vitest'
|
|
3
|
-
import {
|
|
4
|
-
import type {EditorSnapshot} from '../editor/editor-snapshot'
|
|
3
|
+
import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
|
|
5
4
|
import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
|
|
6
5
|
import type {EditorSelection} from '../utils'
|
|
7
6
|
import {getCaretWordSelection} from './selector.get-caret-word-selection'
|
|
@@ -9,16 +8,13 @@ import {getCaretWordSelection} from './selector.get-caret-word-selection'
|
|
|
9
8
|
const keyGenerator = createTestKeyGenerator()
|
|
10
9
|
|
|
11
10
|
function snapshot(value: Array<PortableTextBlock>, selection: EditorSelection) {
|
|
12
|
-
return {
|
|
11
|
+
return createTestSnapshot({
|
|
13
12
|
context: {
|
|
14
13
|
value,
|
|
15
14
|
selection,
|
|
16
15
|
keyGenerator,
|
|
17
|
-
activeDecorators: [],
|
|
18
|
-
converters: [],
|
|
19
|
-
schema: compileSchemaDefinition(defineSchema({})),
|
|
20
16
|
},
|
|
21
|
-
}
|
|
17
|
+
})
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
describe(getCaretWordSelection.name, () => {
|