@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
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {isPortableTextTextBlock} from '@sanity/types'
|
|
2
2
|
import type {EditorSchema} from '../editor/define-schema'
|
|
3
3
|
import * as selectors from '../selectors'
|
|
4
|
-
import {getBlockTextBefore} from '../selectors/selector.get-text-before'
|
|
5
4
|
import {spanSelectionPointToBlockOffset} from '../utils/util.block-offset'
|
|
6
5
|
import {getTextBlockText} from '../utils/util.get-text-block-text'
|
|
7
6
|
import {defineBehavior} from './behavior.types'
|
|
@@ -71,31 +70,31 @@ export type MarkdownBehaviorsConfig = {
|
|
|
71
70
|
export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
72
71
|
const automaticBlockquoteOnSpace = defineBehavior({
|
|
73
72
|
on: 'insert.text',
|
|
74
|
-
guard: ({
|
|
73
|
+
guard: ({snapshot, event}) => {
|
|
75
74
|
const isSpace = event.text === ' '
|
|
76
75
|
|
|
77
76
|
if (!isSpace) {
|
|
78
77
|
return false
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
const selectionCollapsed = selectors.isSelectionCollapsed(
|
|
82
|
-
const focusTextBlock = selectors.getFocusTextBlock(
|
|
83
|
-
const focusSpan = selectors.getFocusSpan(
|
|
80
|
+
const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)
|
|
81
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
82
|
+
const focusSpan = selectors.getFocusSpan(snapshot)
|
|
84
83
|
|
|
85
84
|
if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
|
|
86
85
|
return false
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
const previousInlineObject = selectors.getPreviousInlineObject(
|
|
88
|
+
const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
|
|
90
89
|
const blockOffset = spanSelectionPointToBlockOffset({
|
|
91
|
-
value: context.value,
|
|
90
|
+
value: snapshot.context.value,
|
|
92
91
|
selectionPoint: {
|
|
93
92
|
path: [
|
|
94
93
|
{_key: focusTextBlock.node._key},
|
|
95
94
|
'children',
|
|
96
95
|
{_key: focusSpan.node._key},
|
|
97
96
|
],
|
|
98
|
-
offset: context.selection?.focus.offset ?? 0,
|
|
97
|
+
offset: snapshot.context.selection?.focus.offset ?? 0,
|
|
99
98
|
},
|
|
100
99
|
})
|
|
101
100
|
|
|
@@ -106,7 +105,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
106
105
|
const blockText = getTextBlockText(focusTextBlock.node)
|
|
107
106
|
const caretAtTheEndOfQuote = blockOffset.offset === 1
|
|
108
107
|
const looksLikeMarkdownQuote = /^>/.test(blockText)
|
|
109
|
-
const blockquoteStyle = config.blockquoteStyle?.(context)
|
|
108
|
+
const blockquoteStyle = config.blockquoteStyle?.(snapshot.context)
|
|
110
109
|
|
|
111
110
|
if (
|
|
112
111
|
caretAtTheEndOfQuote &&
|
|
@@ -152,7 +151,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
152
151
|
})
|
|
153
152
|
const automaticHr = defineBehavior({
|
|
154
153
|
on: 'insert.text',
|
|
155
|
-
guard: ({
|
|
154
|
+
guard: ({snapshot, event}) => {
|
|
156
155
|
const hrCharacter =
|
|
157
156
|
event.text === '-'
|
|
158
157
|
? '-'
|
|
@@ -166,16 +165,16 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
166
165
|
return false
|
|
167
166
|
}
|
|
168
167
|
|
|
169
|
-
const hrObject = config.horizontalRuleObject?.(context)
|
|
170
|
-
const focusBlock = selectors.getFocusTextBlock(
|
|
171
|
-
const selectionCollapsed = selectors.isSelectionCollapsed(
|
|
168
|
+
const hrObject = config.horizontalRuleObject?.(snapshot.context)
|
|
169
|
+
const focusBlock = selectors.getFocusTextBlock(snapshot)
|
|
170
|
+
const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)
|
|
172
171
|
|
|
173
172
|
if (!hrObject || !focusBlock || !selectionCollapsed) {
|
|
174
173
|
return false
|
|
175
174
|
}
|
|
176
175
|
|
|
177
|
-
const previousInlineObject = selectors.getPreviousInlineObject(
|
|
178
|
-
const textBefore = getBlockTextBefore(
|
|
176
|
+
const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
|
|
177
|
+
const textBefore = selectors.getBlockTextBefore(snapshot)
|
|
179
178
|
const hrBlockOffsets = {
|
|
180
179
|
anchor: {
|
|
181
180
|
path: focusBlock.path,
|
|
@@ -218,12 +217,12 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
218
217
|
})
|
|
219
218
|
const automaticHrOnPaste = defineBehavior({
|
|
220
219
|
on: 'paste',
|
|
221
|
-
guard: ({
|
|
220
|
+
guard: ({snapshot, event}) => {
|
|
222
221
|
const text = event.data.getData('text/plain')
|
|
223
222
|
const hrRegExp = /^(---)$|(___)$|(\*\*\*)$/gm
|
|
224
223
|
const hrCharacters = text.match(hrRegExp)?.[0]
|
|
225
|
-
const hrObject = config.horizontalRuleObject?.(context)
|
|
226
|
-
const focusBlock = selectors.getFocusBlock(
|
|
224
|
+
const hrObject = config.horizontalRuleObject?.(snapshot.context)
|
|
225
|
+
const focusBlock = selectors.getFocusBlock(snapshot)
|
|
227
226
|
|
|
228
227
|
if (!hrCharacters || !hrObject || !focusBlock) {
|
|
229
228
|
return false
|
|
@@ -264,30 +263,30 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
264
263
|
})
|
|
265
264
|
const automaticHeadingOnSpace = defineBehavior({
|
|
266
265
|
on: 'insert.text',
|
|
267
|
-
guard: ({
|
|
266
|
+
guard: ({snapshot, event}) => {
|
|
268
267
|
const isSpace = event.text === ' '
|
|
269
268
|
|
|
270
269
|
if (!isSpace) {
|
|
271
270
|
return false
|
|
272
271
|
}
|
|
273
272
|
|
|
274
|
-
const selectionCollapsed = selectors.isSelectionCollapsed(
|
|
275
|
-
const focusTextBlock = selectors.getFocusTextBlock(
|
|
276
|
-
const focusSpan = selectors.getFocusSpan(
|
|
273
|
+
const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)
|
|
274
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
275
|
+
const focusSpan = selectors.getFocusSpan(snapshot)
|
|
277
276
|
|
|
278
277
|
if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
|
|
279
278
|
return false
|
|
280
279
|
}
|
|
281
280
|
|
|
282
281
|
const blockOffset = spanSelectionPointToBlockOffset({
|
|
283
|
-
value: context.value,
|
|
282
|
+
value: snapshot.context.value,
|
|
284
283
|
selectionPoint: {
|
|
285
284
|
path: [
|
|
286
285
|
{_key: focusTextBlock.node._key},
|
|
287
286
|
'children',
|
|
288
287
|
{_key: focusSpan.node._key},
|
|
289
288
|
],
|
|
290
|
-
offset: context.selection?.focus.offset ?? 0,
|
|
289
|
+
offset: snapshot.context.selection?.focus.offset ?? 0,
|
|
291
290
|
},
|
|
292
291
|
})
|
|
293
292
|
|
|
@@ -295,7 +294,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
295
294
|
return false
|
|
296
295
|
}
|
|
297
296
|
|
|
298
|
-
const previousInlineObject = selectors.getPreviousInlineObject(
|
|
297
|
+
const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
|
|
299
298
|
const blockText = getTextBlockText(focusTextBlock.node)
|
|
300
299
|
const markdownHeadingSearch = /^#+/.exec(blockText)
|
|
301
300
|
const level = markdownHeadingSearch
|
|
@@ -309,7 +308,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
309
308
|
|
|
310
309
|
const style =
|
|
311
310
|
level !== undefined
|
|
312
|
-
? config.headingStyle?.({schema: context.schema, level})
|
|
311
|
+
? config.headingStyle?.({schema: snapshot.context.schema, level})
|
|
313
312
|
: undefined
|
|
314
313
|
|
|
315
314
|
if (level !== undefined && style !== undefined) {
|
|
@@ -351,10 +350,10 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
351
350
|
})
|
|
352
351
|
const clearStyleOnBackspace = defineBehavior({
|
|
353
352
|
on: 'delete.backward',
|
|
354
|
-
guard: ({
|
|
355
|
-
const selectionCollapsed = selectors.isSelectionCollapsed(
|
|
356
|
-
const focusTextBlock = selectors.getFocusTextBlock(
|
|
357
|
-
const focusSpan = selectors.getFocusSpan(
|
|
353
|
+
guard: ({snapshot}) => {
|
|
354
|
+
const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)
|
|
355
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
356
|
+
const focusSpan = selectors.getFocusSpan(snapshot)
|
|
358
357
|
|
|
359
358
|
if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
|
|
360
359
|
return false
|
|
@@ -362,9 +361,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
362
361
|
|
|
363
362
|
const atTheBeginningOfBLock =
|
|
364
363
|
focusTextBlock.node.children[0]._key === focusSpan.node._key &&
|
|
365
|
-
context.selection?.focus.offset === 0
|
|
364
|
+
snapshot.context.selection?.focus.offset === 0
|
|
366
365
|
|
|
367
|
-
const defaultStyle = config.defaultStyle?.(context)
|
|
366
|
+
const defaultStyle = config.defaultStyle?.(snapshot.context)
|
|
368
367
|
|
|
369
368
|
if (
|
|
370
369
|
atTheBeginningOfBLock &&
|
|
@@ -388,31 +387,31 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
388
387
|
})
|
|
389
388
|
const automaticListOnSpace = defineBehavior({
|
|
390
389
|
on: 'insert.text',
|
|
391
|
-
guard: ({
|
|
390
|
+
guard: ({snapshot, event}) => {
|
|
392
391
|
const isSpace = event.text === ' '
|
|
393
392
|
|
|
394
393
|
if (!isSpace) {
|
|
395
394
|
return false
|
|
396
395
|
}
|
|
397
396
|
|
|
398
|
-
const selectionCollapsed = selectors.isSelectionCollapsed(
|
|
399
|
-
const focusTextBlock = selectors.getFocusTextBlock(
|
|
400
|
-
const focusSpan = selectors.getFocusSpan(
|
|
397
|
+
const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)
|
|
398
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
399
|
+
const focusSpan = selectors.getFocusSpan(snapshot)
|
|
401
400
|
|
|
402
401
|
if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
|
|
403
402
|
return false
|
|
404
403
|
}
|
|
405
404
|
|
|
406
|
-
const previousInlineObject = selectors.getPreviousInlineObject(
|
|
405
|
+
const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
|
|
407
406
|
const blockOffset = spanSelectionPointToBlockOffset({
|
|
408
|
-
value: context.value,
|
|
407
|
+
value: snapshot.context.value,
|
|
409
408
|
selectionPoint: {
|
|
410
409
|
path: [
|
|
411
410
|
{_key: focusTextBlock.node._key},
|
|
412
411
|
'children',
|
|
413
412
|
{_key: focusSpan.node._key},
|
|
414
413
|
],
|
|
415
|
-
offset: context.selection?.focus.offset ?? 0,
|
|
414
|
+
offset: snapshot.context.selection?.focus.offset ?? 0,
|
|
416
415
|
},
|
|
417
416
|
})
|
|
418
417
|
|
|
@@ -421,9 +420,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
421
420
|
}
|
|
422
421
|
|
|
423
422
|
const blockText = getTextBlockText(focusTextBlock.node)
|
|
424
|
-
const defaultStyle = config.defaultStyle?.(context)
|
|
423
|
+
const defaultStyle = config.defaultStyle?.(snapshot.context)
|
|
425
424
|
const looksLikeUnorderedList = /^(-|\*)/.test(blockText)
|
|
426
|
-
const unorderedListStyle = config.unorderedListStyle?.(context)
|
|
425
|
+
const unorderedListStyle = config.unorderedListStyle?.(snapshot.context)
|
|
427
426
|
const caretAtTheEndOfUnorderedList = blockOffset.offset === 1
|
|
428
427
|
|
|
429
428
|
if (
|
|
@@ -441,7 +440,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
441
440
|
}
|
|
442
441
|
|
|
443
442
|
const looksLikeOrderedList = /^1\./.test(blockText)
|
|
444
|
-
const orderedListStyle = config.orderedListStyle?.(context)
|
|
443
|
+
const orderedListStyle = config.orderedListStyle?.(snapshot.context)
|
|
445
444
|
const caretAtTheEndOfOrderedList = blockOffset.offset === 2
|
|
446
445
|
|
|
447
446
|
if (
|
|
@@ -6,9 +6,10 @@ import type {
|
|
|
6
6
|
import type {TextUnit} from 'slate'
|
|
7
7
|
import type {TextInsertTextOptions} from 'slate/dist/interfaces/transforms/text'
|
|
8
8
|
import type {ConverterEvent} from '../converters/converter.types'
|
|
9
|
-
import type {EditorContext} from '../editor/editor-snapshot'
|
|
9
|
+
import type {EditorContext, EditorSnapshot} from '../editor/editor-snapshot'
|
|
10
10
|
import type {MIMEType} from '../internal-utils/mime-type'
|
|
11
11
|
import type {OmitFromUnion, PickFromUnion} from '../type-utils'
|
|
12
|
+
import type {BlockOffset} from '../types/block-offset'
|
|
12
13
|
import type {EditorSelection, PortableTextSlateEditor} from '../types/editor'
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -333,11 +334,13 @@ export type Behavior<
|
|
|
333
334
|
/**
|
|
334
335
|
* @beta
|
|
335
336
|
*/
|
|
336
|
-
export type BehaviorGuard<TBehaviorEvent, TGuardResponse> = ({
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
337
|
+
export type BehaviorGuard<TBehaviorEvent, TGuardResponse> = (payload: {
|
|
338
|
+
/**
|
|
339
|
+
* @deprecated
|
|
340
|
+
* Use `snapshot` instead
|
|
341
|
+
*/
|
|
340
342
|
context: EditorContext
|
|
343
|
+
snapshot: EditorSnapshot
|
|
341
344
|
event: TBehaviorEvent
|
|
342
345
|
}) => TGuardResponse | false
|
|
343
346
|
|
|
@@ -345,11 +348,13 @@ export type BehaviorGuard<TBehaviorEvent, TGuardResponse> = ({
|
|
|
345
348
|
* @beta
|
|
346
349
|
*/
|
|
347
350
|
export type BehaviorActionIntendSet<TBehaviorEvent, TGuardResponse> = (
|
|
348
|
-
{
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
351
|
+
payload: {
|
|
352
|
+
/**
|
|
353
|
+
* @deprecated
|
|
354
|
+
* Use `snapshot` instead
|
|
355
|
+
*/
|
|
352
356
|
context: EditorContext
|
|
357
|
+
snapshot: EditorSnapshot
|
|
353
358
|
event: TBehaviorEvent
|
|
354
359
|
},
|
|
355
360
|
guardResponse: TGuardResponse,
|
|
@@ -400,11 +405,3 @@ export function defineBehavior<
|
|
|
400
405
|
): Behavior {
|
|
401
406
|
return behavior as unknown as Behavior
|
|
402
407
|
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* @beta
|
|
406
|
-
*/
|
|
407
|
-
export type BlockOffset = {
|
|
408
|
-
path: [KeyedSegment]
|
|
409
|
-
offset: number
|
|
410
|
-
}
|
package/src/behaviors/index.ts
CHANGED
|
@@ -2,8 +2,8 @@ import {defineConverter} from './converter.types'
|
|
|
2
2
|
|
|
3
3
|
export const converterJson = defineConverter({
|
|
4
4
|
mimeType: 'application/json',
|
|
5
|
-
serialize: ({
|
|
6
|
-
const portableTextConverter = context.converters.find(
|
|
5
|
+
serialize: ({snapshot, event}) => {
|
|
6
|
+
const portableTextConverter = snapshot.context.converters.find(
|
|
7
7
|
(converter) => converter.mimeType === 'application/x-portable-text',
|
|
8
8
|
)
|
|
9
9
|
|
|
@@ -17,7 +17,7 @@ export const converterJson = defineConverter({
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const serializationEvent = portableTextConverter.serialize({
|
|
20
|
-
|
|
20
|
+
snapshot,
|
|
21
21
|
event,
|
|
22
22
|
})
|
|
23
23
|
|
|
@@ -27,8 +27,8 @@ export const converterJson = defineConverter({
|
|
|
27
27
|
originEvent: event.originEvent,
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
|
-
deserialize: ({
|
|
31
|
-
const portableTextConverter = context.converters.find(
|
|
30
|
+
deserialize: ({snapshot, event}) => {
|
|
31
|
+
const portableTextConverter = snapshot.context.converters.find(
|
|
32
32
|
(converter) => converter.mimeType === 'application/x-portable-text',
|
|
33
33
|
)
|
|
34
34
|
|
|
@@ -41,7 +41,7 @@ export const converterJson = defineConverter({
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const deserializationEvent = portableTextConverter.deserialize({
|
|
44
|
-
|
|
44
|
+
snapshot,
|
|
45
45
|
event,
|
|
46
46
|
})
|
|
47
47
|
|
|
@@ -4,26 +4,24 @@ import {
|
|
|
4
4
|
defineSchema,
|
|
5
5
|
type SchemaDefinition,
|
|
6
6
|
} from '../editor/define-schema'
|
|
7
|
-
import {
|
|
7
|
+
import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
|
|
8
8
|
import {converterPortableText} from './converter.portable-text'
|
|
9
9
|
import {coreConverters} from './converters.core'
|
|
10
10
|
|
|
11
|
-
function
|
|
12
|
-
return {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
selection: null,
|
|
19
|
-
}
|
|
11
|
+
function createSnapshot(schema: SchemaDefinition) {
|
|
12
|
+
return createTestSnapshot({
|
|
13
|
+
context: {
|
|
14
|
+
converters: coreConverters,
|
|
15
|
+
schema: compileSchemaDefinition(schema),
|
|
16
|
+
},
|
|
17
|
+
})
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
describe(converterPortableText.deserialize, () => {
|
|
23
21
|
test('non-array', () => {
|
|
24
22
|
expect(
|
|
25
23
|
converterPortableText.deserialize({
|
|
26
|
-
|
|
24
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
27
25
|
event: {
|
|
28
26
|
type: 'deserialize',
|
|
29
27
|
data: JSON.stringify(''),
|
|
@@ -37,7 +35,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
37
35
|
test('empty array', () => {
|
|
38
36
|
expect(
|
|
39
37
|
converterPortableText.deserialize({
|
|
40
|
-
|
|
38
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
41
39
|
event: {
|
|
42
40
|
type: 'deserialize',
|
|
43
41
|
data: JSON.stringify([]),
|
|
@@ -51,7 +49,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
51
49
|
test('no known array entries', () => {
|
|
52
50
|
expect(
|
|
53
51
|
converterPortableText.deserialize({
|
|
54
|
-
|
|
52
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
55
53
|
event: {
|
|
56
54
|
type: 'deserialize',
|
|
57
55
|
data: JSON.stringify([{foo: 'bar'}]),
|
|
@@ -65,7 +63,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
65
63
|
test('some known array entries', () => {
|
|
66
64
|
expect(
|
|
67
65
|
converterPortableText.deserialize({
|
|
68
|
-
|
|
66
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
69
67
|
event: {
|
|
70
68
|
type: 'deserialize',
|
|
71
69
|
data: JSON.stringify([{_type: 'block', children: []}, {foo: 'bar'}]),
|
|
@@ -93,7 +91,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
93
91
|
test('no marks or markDefs', () => {
|
|
94
92
|
expect(
|
|
95
93
|
converterPortableText.deserialize({
|
|
96
|
-
|
|
94
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
97
95
|
event: {
|
|
98
96
|
type: 'deserialize',
|
|
99
97
|
data: JSON.stringify([
|
|
@@ -129,7 +127,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
129
127
|
test('unknown block object', () => {
|
|
130
128
|
expect(
|
|
131
129
|
converterPortableText.deserialize({
|
|
132
|
-
|
|
130
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
133
131
|
event: {
|
|
134
132
|
type: 'deserialize',
|
|
135
133
|
data: JSON.stringify([{_type: 'foo'}]),
|
|
@@ -143,7 +141,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
143
141
|
test('known block object', () => {
|
|
144
142
|
expect(
|
|
145
143
|
converterPortableText.deserialize({
|
|
146
|
-
|
|
144
|
+
snapshot: createSnapshot(
|
|
147
145
|
defineSchema({
|
|
148
146
|
blockObjects: [{name: 'image'}],
|
|
149
147
|
}),
|
|
@@ -173,7 +171,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
173
171
|
test('unknown inline object', () => {
|
|
174
172
|
expect(
|
|
175
173
|
converterPortableText.deserialize({
|
|
176
|
-
|
|
174
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
177
175
|
event: {
|
|
178
176
|
type: 'deserialize',
|
|
179
177
|
data: JSON.stringify([
|
|
@@ -204,7 +202,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
204
202
|
test('known inline object', () => {
|
|
205
203
|
expect(
|
|
206
204
|
converterPortableText.deserialize({
|
|
207
|
-
|
|
205
|
+
snapshot: createSnapshot(
|
|
208
206
|
defineSchema({
|
|
209
207
|
inlineObjects: [{name: 'stock-ticker'}],
|
|
210
208
|
}),
|
|
@@ -231,7 +229,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
231
229
|
|
|
232
230
|
test('no style', () => {
|
|
233
231
|
const deserializedEvent = converterPortableText.deserialize({
|
|
234
|
-
|
|
232
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
235
233
|
event: {
|
|
236
234
|
type: 'deserialize',
|
|
237
235
|
data: JSON.stringify([
|
|
@@ -267,7 +265,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
267
265
|
|
|
268
266
|
test('default style', () => {
|
|
269
267
|
const deserializedEvent = converterPortableText.deserialize({
|
|
270
|
-
|
|
268
|
+
snapshot: createSnapshot(defineSchema({styles: [{name: 'h1'}]})),
|
|
271
269
|
event: {
|
|
272
270
|
type: 'deserialize',
|
|
273
271
|
data: JSON.stringify([
|
|
@@ -303,7 +301,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
303
301
|
|
|
304
302
|
test('unknown style', () => {
|
|
305
303
|
const deserializedEvent = converterPortableText.deserialize({
|
|
306
|
-
|
|
304
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
307
305
|
event: {
|
|
308
306
|
type: 'deserialize',
|
|
309
307
|
data: JSON.stringify([
|
|
@@ -340,7 +338,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
340
338
|
|
|
341
339
|
test('known style', () => {
|
|
342
340
|
const deserializedEvent = converterPortableText.deserialize({
|
|
343
|
-
|
|
341
|
+
snapshot: createSnapshot(
|
|
344
342
|
defineSchema({
|
|
345
343
|
styles: [{name: 'h1'}],
|
|
346
344
|
}),
|
|
@@ -381,7 +379,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
381
379
|
|
|
382
380
|
test('unknown listItem', () => {
|
|
383
381
|
const deserializedEvent = converterPortableText.deserialize({
|
|
384
|
-
|
|
382
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
385
383
|
event: {
|
|
386
384
|
type: 'deserialize',
|
|
387
385
|
data: JSON.stringify([
|
|
@@ -420,7 +418,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
420
418
|
|
|
421
419
|
test('known listItem', () => {
|
|
422
420
|
const deserializedEvent = converterPortableText.deserialize({
|
|
423
|
-
|
|
421
|
+
snapshot: createSnapshot(
|
|
424
422
|
defineSchema({
|
|
425
423
|
lists: [{name: 'bullet'}],
|
|
426
424
|
}),
|
|
@@ -465,7 +463,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
465
463
|
test('unknown annotations', () => {
|
|
466
464
|
expect(
|
|
467
465
|
converterPortableText.deserialize({
|
|
468
|
-
|
|
466
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
469
467
|
event: {
|
|
470
468
|
type: 'deserialize',
|
|
471
469
|
data: JSON.stringify([
|
|
@@ -523,7 +521,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
523
521
|
test('known annotations', () => {
|
|
524
522
|
expect(
|
|
525
523
|
converterPortableText.deserialize({
|
|
526
|
-
|
|
524
|
+
snapshot: createSnapshot(
|
|
527
525
|
defineSchema({
|
|
528
526
|
annotations: [{name: 'link'}],
|
|
529
527
|
}),
|
|
@@ -592,7 +590,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
592
590
|
test('unknown decorators', () => {
|
|
593
591
|
expect(
|
|
594
592
|
converterPortableText.deserialize({
|
|
595
|
-
|
|
593
|
+
snapshot: createSnapshot(defineSchema({})),
|
|
596
594
|
event: {
|
|
597
595
|
type: 'deserialize',
|
|
598
596
|
data: JSON.stringify([
|
|
@@ -638,7 +636,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
638
636
|
test('known decorators', () => {
|
|
639
637
|
expect(
|
|
640
638
|
converterPortableText.deserialize({
|
|
641
|
-
|
|
639
|
+
snapshot: createSnapshot(
|
|
642
640
|
defineSchema({
|
|
643
641
|
decorators: [{name: 'strong'}],
|
|
644
642
|
}),
|
|
@@ -4,8 +4,8 @@ import {defineConverter} from './converter.types'
|
|
|
4
4
|
|
|
5
5
|
export const converterPortableText = defineConverter({
|
|
6
6
|
mimeType: 'application/x-portable-text',
|
|
7
|
-
serialize: ({
|
|
8
|
-
if (!context.selection) {
|
|
7
|
+
serialize: ({snapshot, event}) => {
|
|
8
|
+
if (!snapshot.context.selection) {
|
|
9
9
|
return {
|
|
10
10
|
type: 'serialization.failure',
|
|
11
11
|
mimeType: 'application/x-portable-text',
|
|
@@ -15,8 +15,8 @@ export const converterPortableText = defineConverter({
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const blocks = sliceBlocks({
|
|
18
|
-
blocks: context.value,
|
|
19
|
-
selection: context.selection,
|
|
18
|
+
blocks: snapshot.context.value,
|
|
19
|
+
selection: snapshot.context.selection,
|
|
20
20
|
})
|
|
21
21
|
|
|
22
22
|
return {
|
|
@@ -26,7 +26,7 @@ export const converterPortableText = defineConverter({
|
|
|
26
26
|
originEvent: event.originEvent,
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
-
deserialize: ({
|
|
29
|
+
deserialize: ({snapshot, event}) => {
|
|
30
30
|
const blocks = JSON.parse(event.data)
|
|
31
31
|
|
|
32
32
|
if (!Array.isArray(blocks)) {
|
|
@@ -39,9 +39,15 @@ export const converterPortableText = defineConverter({
|
|
|
39
39
|
|
|
40
40
|
const parsedBlocks = blocks.flatMap((block) => {
|
|
41
41
|
const parsedBlock = parseBlock({
|
|
42
|
-
context,
|
|
42
|
+
context: snapshot.context,
|
|
43
43
|
block,
|
|
44
|
-
options: {
|
|
44
|
+
options: {
|
|
45
|
+
/**
|
|
46
|
+
* If we are dragging internally then we would like to keep the
|
|
47
|
+
* dropped portable text as is.
|
|
48
|
+
*/
|
|
49
|
+
refreshKeys: !snapshot.beta.hasTag?.('dragging internally'),
|
|
50
|
+
},
|
|
45
51
|
})
|
|
46
52
|
return parsedBlock ? [parsedBlock] : []
|
|
47
53
|
})
|