@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,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: ({context, event}) => {
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({context})
82
- const focusTextBlock = selectors.getFocusTextBlock({context})
83
- const focusSpan = selectors.getFocusSpan({context})
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({context})
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: ({context, event}) => {
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({context})
171
- const selectionCollapsed = selectors.isSelectionCollapsed({context})
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({context})
178
- const textBefore = getBlockTextBefore({context})
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: ({context, event}) => {
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({context})
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: ({context, event}) => {
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({context})
275
- const focusTextBlock = selectors.getFocusTextBlock({context})
276
- const focusSpan = selectors.getFocusSpan({context})
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({context})
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: ({context}) => {
355
- const selectionCollapsed = selectors.isSelectionCollapsed({context})
356
- const focusTextBlock = selectors.getFocusTextBlock({context})
357
- const focusSpan = selectors.getFocusSpan({context})
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: ({context, event}) => {
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({context})
399
- const focusTextBlock = selectors.getFocusTextBlock({context})
400
- const focusSpan = selectors.getFocusSpan({context})
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({context})
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
- context,
338
- event,
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
- context,
350
- event,
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
- }
@@ -28,7 +28,6 @@ export {
28
28
  type BehaviorActionIntendSet,
29
29
  type BehaviorEvent,
30
30
  type BehaviorGuard,
31
- type BlockOffset,
32
31
  type CustomBehaviorEvent,
33
32
  type NativeBehaviorEvent,
34
33
  type SyntheticBehaviorEvent,
@@ -2,8 +2,8 @@ import {defineConverter} from './converter.types'
2
2
 
3
3
  export const converterJson = defineConverter({
4
4
  mimeType: 'application/json',
5
- serialize: ({context, event}) => {
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
- context,
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: ({context, event}) => {
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
- context,
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 {createTestKeyGenerator} from '../internal-utils/test-key-generator'
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 createContext(schema: SchemaDefinition) {
12
- return {
13
- converters: coreConverters,
14
- activeDecorators: [],
15
- keyGenerator: createTestKeyGenerator(),
16
- schema: compileSchemaDefinition(schema),
17
- value: [],
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
- context: createContext(defineSchema({})),
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
- context: createContext(defineSchema({})),
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
- context: createContext(defineSchema({})),
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
- context: createContext(defineSchema({})),
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
- context: createContext(defineSchema({})),
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
- context: createContext(defineSchema({})),
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
- context: createContext(
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
- context: createContext(defineSchema({})),
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
- context: createContext(
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
- context: createContext(defineSchema({})),
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
- context: createContext(defineSchema({styles: [{name: 'h1'}]})),
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
- context: createContext(defineSchema({})),
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
- context: createContext(
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
- context: createContext(defineSchema({})),
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
- context: createContext(
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
- context: createContext(defineSchema({})),
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
- context: createContext(
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
- context: createContext(defineSchema({})),
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
- context: createContext(
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: ({context, event}) => {
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: ({context, event}) => {
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: {refreshKeys: true},
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
  })