@portabletext/editor 1.50.3 → 1.50.5

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 (50) hide show
  1. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +4 -14
  2. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  3. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +4 -14
  4. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  5. package/lib/behaviors/index.d.cts +10 -1
  6. package/lib/behaviors/index.d.ts +10 -1
  7. package/lib/index.cjs +582 -253
  8. package/lib/index.cjs.map +1 -1
  9. package/lib/index.d.cts +11 -1
  10. package/lib/index.d.ts +11 -1
  11. package/lib/index.js +592 -262
  12. package/lib/index.js.map +1 -1
  13. package/lib/plugins/index.d.cts +10 -1
  14. package/lib/plugins/index.d.ts +10 -1
  15. package/lib/selectors/index.d.cts +10 -1
  16. package/lib/selectors/index.d.ts +10 -1
  17. package/lib/utils/index.d.cts +10 -1
  18. package/lib/utils/index.d.ts +10 -1
  19. package/package.json +4 -3
  20. package/src/behaviors/behavior.abstract.delete.ts +6 -2
  21. package/src/behaviors/behavior.abstract.ts +1 -1
  22. package/src/editor/PortableTextEditor.tsx +22 -22
  23. package/src/editor/create-slate-editor.tsx +11 -1
  24. package/src/editor/editor-selector.ts +11 -9
  25. package/src/editor/editor-snapshot.ts +13 -8
  26. package/src/editor/get-active-annotations.ts +15 -0
  27. package/src/editor/get-active-decorators.ts +23 -9
  28. package/src/editor/plugins/create-with-event-listeners.ts +9 -3
  29. package/src/editor/plugins/createWithEditableAPI.ts +16 -14
  30. package/src/editor/plugins/createWithPortableTextMarkModel.ts +26 -190
  31. package/src/editor/plugins/slate-plugin.update-mark-state.ts +21 -0
  32. package/src/editor/plugins/slate-plugin.update-value.ts +27 -0
  33. package/src/editor/plugins/with-plugins.ts +15 -1
  34. package/src/internal-utils/apply-operation-to-portable-text.test.ts +175 -0
  35. package/src/internal-utils/apply-operation-to-portable-text.ts +435 -0
  36. package/src/internal-utils/create-placeholder-block.ts +20 -0
  37. package/src/internal-utils/create-test-snapshot.ts +2 -1
  38. package/src/internal-utils/mark-state.ts +172 -0
  39. package/src/internal-utils/portable-text-node.ts +209 -0
  40. package/src/internal-utils/slate-utils.ts +44 -0
  41. package/src/operations/behavior.operation.decorator.add.ts +7 -11
  42. package/src/operations/behavior.operation.insert.text.ts +48 -8
  43. package/src/selectors/selector.get-active-annotations.ts +2 -1
  44. package/src/selectors/selector.is-active-annotation.ts +7 -39
  45. package/src/selectors/selector.is-active-decorator.ts +1 -1
  46. package/src/types/editor.ts +4 -0
  47. package/src/editor/get-value.ts +0 -18
  48. package/src/internal-utils/__tests__/patchToOperations.test.ts +0 -312
  49. package/src/internal-utils/slate-children-to-blocks.ts +0 -49
  50. package/src/selectors/selector.get-active-annotations.test.ts +0 -141
@@ -599,7 +599,6 @@ declare type EditorActor = ActorRefFrom<typeof editorMachine>
599
599
  * @public
600
600
  */
601
601
  declare type EditorContext = {
602
- activeDecorators: Array<string>
603
602
  converters: Array<Converter>
604
603
  keyGenerator: () => string
605
604
  readOnly: boolean
@@ -2520,6 +2519,8 @@ declare type EditorSnapshot = {
2520
2519
  * Do not rely on this externally
2521
2520
  */
2522
2521
  beta: {
2522
+ activeAnnotations: Array<string>
2523
+ activeDecorators: Array<string>
2523
2524
  hasTag: HasTag
2524
2525
  internalDrag:
2525
2526
  | {
@@ -2811,6 +2812,11 @@ export declare type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
2811
2812
  }) => string | undefined
2812
2813
  }
2813
2814
 
2815
+ declare type MarkState = {
2816
+ state: 'changed' | 'unchanged'
2817
+ marks: Array<string>
2818
+ }
2819
+
2814
2820
  declare type MIMEType = `${string}/${string}`
2815
2821
 
2816
2822
  declare type MouseBehaviorEvent = {
@@ -2950,6 +2956,9 @@ declare interface PortableTextSlateEditor extends ReactEditor {
2950
2956
  isTextBlock: (value: unknown) => value is PortableTextTextBlock
2951
2957
  isTextSpan: (value: unknown) => value is PortableTextSpan
2952
2958
  isListBlock: (value: unknown) => value is PortableTextListBlock
2959
+ value: Array<PortableTextBlock>
2960
+ decoratorState: Record<string, boolean | undefined>
2961
+ markState: MarkState | undefined
2953
2962
  /**
2954
2963
  * Use hotkeys
2955
2964
  */
@@ -599,7 +599,6 @@ declare type EditorActor = ActorRefFrom<typeof editorMachine>
599
599
  * @public
600
600
  */
601
601
  declare type EditorContext = {
602
- activeDecorators: Array<string>
603
602
  converters: Array<Converter>
604
603
  keyGenerator: () => string
605
604
  readOnly: boolean
@@ -2520,6 +2519,8 @@ declare type EditorSnapshot = {
2520
2519
  * Do not rely on this externally
2521
2520
  */
2522
2521
  beta: {
2522
+ activeAnnotations: Array<string>
2523
+ activeDecorators: Array<string>
2523
2524
  hasTag: HasTag
2524
2525
  internalDrag:
2525
2526
  | {
@@ -2811,6 +2812,11 @@ export declare type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
2811
2812
  }) => string | undefined
2812
2813
  }
2813
2814
 
2815
+ declare type MarkState = {
2816
+ state: 'changed' | 'unchanged'
2817
+ marks: Array<string>
2818
+ }
2819
+
2814
2820
  declare type MIMEType = `${string}/${string}`
2815
2821
 
2816
2822
  declare type MouseBehaviorEvent = {
@@ -2950,6 +2956,9 @@ declare interface PortableTextSlateEditor extends ReactEditor {
2950
2956
  isTextBlock: (value: unknown) => value is PortableTextTextBlock
2951
2957
  isTextSpan: (value: unknown) => value is PortableTextSpan
2952
2958
  isListBlock: (value: unknown) => value is PortableTextListBlock
2959
+ value: Array<PortableTextBlock>
2960
+ decoratorState: Record<string, boolean | undefined>
2961
+ markState: MarkState | undefined
2953
2962
  /**
2954
2963
  * Use hotkeys
2955
2964
  */
@@ -570,7 +570,6 @@ declare type EditorActor = ActorRefFrom<typeof editorMachine>
570
570
  * @public
571
571
  */
572
572
  declare type EditorContext = {
573
- activeDecorators: Array<string>
574
573
  converters: Array<Converter>
575
574
  keyGenerator: () => string
576
575
  readOnly: boolean
@@ -2428,6 +2427,8 @@ declare type EditorSnapshot = {
2428
2427
  * Do not rely on this externally
2429
2428
  */
2430
2429
  beta: {
2430
+ activeAnnotations: Array<string>
2431
+ activeDecorators: Array<string>
2431
2432
  hasTag: HasTag
2432
2433
  internalDrag:
2433
2434
  | {
@@ -2922,6 +2923,11 @@ declare type ListState = {
2922
2923
  index: number
2923
2924
  }
2924
2925
 
2926
+ declare type MarkState = {
2927
+ state: 'changed' | 'unchanged'
2928
+ marks: Array<string>
2929
+ }
2930
+
2925
2931
  declare type MIMEType = `${string}/${string}`
2926
2932
 
2927
2933
  declare type MouseBehaviorEvent = {
@@ -3049,6 +3055,9 @@ declare interface PortableTextSlateEditor extends ReactEditor {
3049
3055
  isTextBlock: (value: unknown) => value is PortableTextTextBlock
3050
3056
  isTextSpan: (value: unknown) => value is PortableTextSpan
3051
3057
  isListBlock: (value: unknown) => value is PortableTextListBlock
3058
+ value: Array<PortableTextBlock>
3059
+ decoratorState: Record<string, boolean | undefined>
3060
+ markState: MarkState | undefined
3052
3061
  /**
3053
3062
  * Use hotkeys
3054
3063
  */
@@ -570,7 +570,6 @@ declare type EditorActor = ActorRefFrom<typeof editorMachine>
570
570
  * @public
571
571
  */
572
572
  declare type EditorContext = {
573
- activeDecorators: Array<string>
574
573
  converters: Array<Converter>
575
574
  keyGenerator: () => string
576
575
  readOnly: boolean
@@ -2428,6 +2427,8 @@ declare type EditorSnapshot = {
2428
2427
  * Do not rely on this externally
2429
2428
  */
2430
2429
  beta: {
2430
+ activeAnnotations: Array<string>
2431
+ activeDecorators: Array<string>
2431
2432
  hasTag: HasTag
2432
2433
  internalDrag:
2433
2434
  | {
@@ -2922,6 +2923,11 @@ declare type ListState = {
2922
2923
  index: number
2923
2924
  }
2924
2925
 
2926
+ declare type MarkState = {
2927
+ state: 'changed' | 'unchanged'
2928
+ marks: Array<string>
2929
+ }
2930
+
2925
2931
  declare type MIMEType = `${string}/${string}`
2926
2932
 
2927
2933
  declare type MouseBehaviorEvent = {
@@ -3049,6 +3055,9 @@ declare interface PortableTextSlateEditor extends ReactEditor {
3049
3055
  isTextBlock: (value: unknown) => value is PortableTextTextBlock
3050
3056
  isTextSpan: (value: unknown) => value is PortableTextSpan
3051
3057
  isListBlock: (value: unknown) => value is PortableTextListBlock
3058
+ value: Array<PortableTextBlock>
3059
+ decoratorState: Record<string, boolean | undefined>
3060
+ markState: MarkState | undefined
3052
3061
  /**
3053
3062
  * Use hotkeys
3054
3063
  */
@@ -634,7 +634,6 @@ declare type EditorActor = ActorRefFrom<typeof editorMachine>
634
634
  * @public
635
635
  */
636
636
  declare type EditorContext = {
637
- activeDecorators: Array<string>
638
637
  converters: Array<Converter>
639
638
  keyGenerator: () => string
640
639
  readOnly: boolean
@@ -2487,6 +2486,8 @@ declare type EditorSnapshot = {
2487
2486
  * Do not rely on this externally
2488
2487
  */
2489
2488
  beta: {
2489
+ activeAnnotations: Array<string>
2490
+ activeDecorators: Array<string>
2490
2491
  hasTag: HasTag
2491
2492
  internalDrag:
2492
2493
  | {
@@ -2670,6 +2671,11 @@ declare type KeyboardBehaviorEvent =
2670
2671
  >
2671
2672
  }
2672
2673
 
2674
+ declare type MarkState = {
2675
+ state: 'changed' | 'unchanged'
2676
+ marks: Array<string>
2677
+ }
2678
+
2673
2679
  /**
2674
2680
  * @beta
2675
2681
  */
@@ -2810,6 +2816,9 @@ declare interface PortableTextSlateEditor extends ReactEditor {
2810
2816
  isTextBlock: (value: unknown) => value is PortableTextTextBlock
2811
2817
  isTextSpan: (value: unknown) => value is PortableTextSpan
2812
2818
  isListBlock: (value: unknown) => value is PortableTextListBlock
2819
+ value: Array<PortableTextBlock>
2820
+ decoratorState: Record<string, boolean | undefined>
2821
+ markState: MarkState | undefined
2813
2822
  /**
2814
2823
  * Use hotkeys
2815
2824
  */
@@ -634,7 +634,6 @@ declare type EditorActor = ActorRefFrom<typeof editorMachine>
634
634
  * @public
635
635
  */
636
636
  declare type EditorContext = {
637
- activeDecorators: Array<string>
638
637
  converters: Array<Converter>
639
638
  keyGenerator: () => string
640
639
  readOnly: boolean
@@ -2487,6 +2486,8 @@ declare type EditorSnapshot = {
2487
2486
  * Do not rely on this externally
2488
2487
  */
2489
2488
  beta: {
2489
+ activeAnnotations: Array<string>
2490
+ activeDecorators: Array<string>
2490
2491
  hasTag: HasTag
2491
2492
  internalDrag:
2492
2493
  | {
@@ -2670,6 +2671,11 @@ declare type KeyboardBehaviorEvent =
2670
2671
  >
2671
2672
  }
2672
2673
 
2674
+ declare type MarkState = {
2675
+ state: 'changed' | 'unchanged'
2676
+ marks: Array<string>
2677
+ }
2678
+
2673
2679
  /**
2674
2680
  * @beta
2675
2681
  */
@@ -2810,6 +2816,9 @@ declare interface PortableTextSlateEditor extends ReactEditor {
2810
2816
  isTextBlock: (value: unknown) => value is PortableTextTextBlock
2811
2817
  isTextSpan: (value: unknown) => value is PortableTextSpan
2812
2818
  isListBlock: (value: unknown) => value is PortableTextListBlock
2819
+ value: Array<PortableTextBlock>
2820
+ decoratorState: Record<string, boolean | undefined>
2821
+ markState: MarkState | undefined
2813
2822
  /**
2814
2823
  * Use hotkeys
2815
2824
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.50.3",
3
+ "version": "1.50.5",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -71,6 +71,7 @@
71
71
  "@xstate/react": "^5.0.4",
72
72
  "debug": "^4.4.1",
73
73
  "get-random-values-esm": "^1.0.2",
74
+ "immer": "^10.1.1",
74
75
  "lodash": "^4.17.21",
75
76
  "lodash.startcase": "^4.4.0",
76
77
  "react-compiler-runtime": "19.1.0-rc.1",
@@ -79,8 +80,8 @@
79
80
  "slate-react": "0.114.2",
80
81
  "use-effect-event": "^1.0.2",
81
82
  "xstate": "^5.19.3",
82
- "@portabletext/patches": "1.1.3",
83
- "@portabletext/block-tools": "1.1.27"
83
+ "@portabletext/block-tools": "1.1.27",
84
+ "@portabletext/patches": "1.1.3"
84
85
  },
85
86
  "devDependencies": {
86
87
  "@portabletext/toolkit": "^2.0.17",
@@ -17,12 +17,16 @@ export const abstractDeleteBehaviors = [
17
17
  }
18
18
 
19
19
  const trimmedSelection = selectors.getTrimmedSelection({
20
- beta: {hasTag: () => false, internalDrag: undefined},
20
+ beta: {
21
+ activeAnnotations: [],
22
+ activeDecorators: [],
23
+ hasTag: () => false,
24
+ internalDrag: undefined,
25
+ },
21
26
  context: {
22
27
  converters: [],
23
28
  schema: snapshot.context.schema,
24
29
  keyGenerator: snapshot.context.keyGenerator,
25
- activeDecorators: [],
26
30
  readOnly: false,
27
31
  value: snapshot.context.value,
28
32
  selection,
@@ -327,7 +327,7 @@ export const abstractBehaviors = [
327
327
  event.mimeType === 'text/plain' &&
328
328
  event.originEvent.type === 'clipboard.paste'
329
329
  ) {
330
- const activeDecorators = snapshot.context.activeDecorators
330
+ const activeDecorators = snapshot.beta.activeDecorators
331
331
  const activeAnnotations = selectors.getActiveAnnotations(snapshot)
332
332
 
333
333
  return {
@@ -138,6 +138,7 @@ export class PortableTextEditor extends Component<
138
138
  syncActor: SyncActor
139
139
  }
140
140
 
141
+ private subscriptions: Array<() => () => void> = []
141
142
  private unsubscribers: Array<() => void> = []
142
143
 
143
144
  constructor(props: PortableTextEditorProps) {
@@ -160,28 +161,7 @@ export class PortableTextEditor extends Component<
160
161
  schema: props.schemaType,
161
162
  })
162
163
 
163
- this.unsubscribers.push(
164
- (() => {
165
- const subscription = actors.relayActor.on('*', (event) => {
166
- const change = eventToChange(event)
167
-
168
- if (change) {
169
- props.onChange(change)
170
-
171
- this.change$.next(change)
172
- }
173
- })
174
-
175
- return () => {
176
- subscription.unsubscribe()
177
- }
178
- })(),
179
- )
180
-
181
- for (const subscription of subscriptions) {
182
- this.unsubscribers.push(subscription())
183
- }
184
-
164
+ this.subscriptions = subscriptions
185
165
  this.actors = actors
186
166
 
187
167
  this.editor = editor
@@ -198,6 +178,26 @@ export class PortableTextEditor extends Component<
198
178
  return
199
179
  }
200
180
 
181
+ for (const subscription of this.subscriptions) {
182
+ this.unsubscribers.push(subscription())
183
+ }
184
+
185
+ const relayActorSubscription = this.actors.relayActor.on('*', (event) => {
186
+ const change = eventToChange(event)
187
+
188
+ if (!change) {
189
+ return
190
+ }
191
+
192
+ if (!this.props.editor) {
193
+ this.props.onChange(change)
194
+ }
195
+
196
+ this.change$.next(change)
197
+ })
198
+
199
+ this.unsubscribers.push(relayActorSubscription.unsubscribe)
200
+
201
201
  this.actors.editorActor.start()
202
202
  this.actors.mutationActor.start()
203
203
  this.actors.relayActor.start()
@@ -1,6 +1,8 @@
1
1
  import {createEditor, type Descendant} from 'slate'
2
2
  import {withReact} from 'slate-react'
3
+ import {createPlaceholderBlock} from '../internal-utils/create-placeholder-block'
3
4
  import {debugWithName} from '../internal-utils/debug'
5
+ import {toSlateValue} from '../internal-utils/values'
4
6
  import {
5
7
  KEY_TO_SLATE_ELEMENT,
6
8
  KEY_TO_VALUE_ELEMENT,
@@ -35,7 +37,15 @@ export function createSlateEditor(config: SlateEditorConfig): SlateEditor {
35
37
  KEY_TO_VALUE_ELEMENT.set(instance, {})
36
38
  KEY_TO_SLATE_ELEMENT.set(instance, {})
37
39
 
38
- const initialValue = [instance.pteCreateTextBlock({decorators: []})]
40
+ instance.decoratorState = {}
41
+ instance.markState = undefined
42
+ instance.value = [
43
+ createPlaceholderBlock(config.editorActor.getSnapshot().context),
44
+ ]
45
+
46
+ const initialValue = toSlateValue(instance.value, {
47
+ schemaTypes: config.editorActor.getSnapshot().context.schema,
48
+ })
39
49
 
40
50
  const slateEditor: SlateEditor = {
41
51
  instance,
@@ -1,10 +1,10 @@
1
1
  import {useSelector} from '@xstate/react'
2
2
  import type {Editor} from '../editor'
3
- import {slateChildrenToBlocks} from '../internal-utils/slate-children-to-blocks'
4
3
  import type {PortableTextSlateEditor} from '../types/editor'
5
4
  import type {InternalEditor} from './create-editor'
6
5
  import type {EditorActor} from './editor-machine'
7
6
  import type {EditorSnapshot} from './editor-snapshot'
7
+ import {getActiveAnnotations} from './get-active-annotations'
8
8
  import {getActiveDecorators} from './get-active-decorators'
9
9
 
10
10
  function defaultCompare<T>(a: T, b: T) {
@@ -70,20 +70,22 @@ export function getEditorSnapshot({
70
70
  return {
71
71
  context: {
72
72
  converters: [...editorActorSnapshot.context.converters],
73
- activeDecorators: getActiveDecorators({
74
- schema: editorActorSnapshot.context.schema,
75
- slateEditorInstance,
76
- }),
77
73
  keyGenerator: editorActorSnapshot.context.keyGenerator,
78
74
  readOnly: editorActorSnapshot.matches({'edit mode': 'read only'}),
79
75
  schema: editorActorSnapshot.context.schema,
80
76
  selection: editorActorSnapshot.context.selection,
81
- value: slateChildrenToBlocks(
82
- editorActorSnapshot.context.schema,
83
- slateEditorInstance.children,
84
- ),
77
+ value: slateEditorInstance.value,
85
78
  },
86
79
  beta: {
80
+ activeAnnotations: getActiveAnnotations({
81
+ markState: slateEditorInstance.markState,
82
+ schema: editorActorSnapshot.context.schema,
83
+ }),
84
+ activeDecorators: getActiveDecorators({
85
+ decoratorState: slateEditorInstance.decoratorState,
86
+ markState: slateEditorInstance.markState,
87
+ schema: editorActorSnapshot.context.schema,
88
+ }),
87
89
  hasTag: (tag) => editorActorSnapshot.hasTag(tag),
88
90
  internalDrag: editorActorSnapshot.context.internalDrag,
89
91
  },
@@ -1,18 +1,17 @@
1
1
  import type {PortableTextBlock} from '@sanity/types'
2
2
  import type {Converter} from '../converters/converter.types'
3
3
  import type {EventPosition} from '../internal-utils/event-position'
4
- import {slateChildrenToBlocks} from '../internal-utils/slate-children-to-blocks'
5
4
  import {slateRangeToSelection} from '../internal-utils/slate-utils'
6
5
  import type {EditorSelection, PortableTextSlateEditor} from '../types/editor'
7
6
  import type {HasTag} from './editor-machine'
8
7
  import type {EditorSchema} from './editor-schema'
8
+ import {getActiveAnnotations} from './get-active-annotations'
9
9
  import {getActiveDecorators} from './get-active-decorators'
10
10
 
11
11
  /**
12
12
  * @public
13
13
  */
14
14
  export type EditorContext = {
15
- activeDecorators: Array<string>
16
15
  converters: Array<Converter>
17
16
  keyGenerator: () => string
18
17
  readOnly: boolean
@@ -31,6 +30,8 @@ export type EditorSnapshot = {
31
30
  * Do not rely on this externally
32
31
  */
33
32
  beta: {
33
+ activeAnnotations: Array<string>
34
+ activeDecorators: Array<string>
34
35
  hasTag: HasTag
35
36
  internalDrag:
36
37
  | {
@@ -61,7 +62,6 @@ export function createEditorSnapshot({
61
62
  }
62
63
  | undefined
63
64
  }) {
64
- const value = slateChildrenToBlocks(schema, editor.children)
65
65
  const selection = editor.selection
66
66
  ? slateRangeToSelection({
67
67
  schema,
@@ -71,21 +71,26 @@ export function createEditorSnapshot({
71
71
  : null
72
72
 
73
73
  const context = {
74
- activeDecorators: getActiveDecorators({
75
- schema,
76
- slateEditorInstance: editor,
77
- }),
78
74
  converters,
79
75
  keyGenerator,
80
76
  readOnly,
81
77
  schema,
82
78
  selection,
83
- value,
79
+ value: editor.value,
84
80
  } satisfies EditorContext
85
81
 
86
82
  return {
87
83
  context,
88
84
  beta: {
85
+ activeAnnotations: getActiveAnnotations({
86
+ markState: editor.markState,
87
+ schema,
88
+ }),
89
+ activeDecorators: getActiveDecorators({
90
+ decoratorState: editor.decoratorState,
91
+ markState: editor.markState,
92
+ schema,
93
+ }),
89
94
  hasTag,
90
95
  internalDrag,
91
96
  },
@@ -0,0 +1,15 @@
1
+ import type {MarkState} from '../internal-utils/mark-state'
2
+ import type {EditorSchema} from './editor-schema'
3
+
4
+ export function getActiveAnnotations({
5
+ markState,
6
+ schema,
7
+ }: {
8
+ markState: MarkState | undefined
9
+ schema: EditorSchema
10
+ }) {
11
+ return (markState?.marks ?? []).filter(
12
+ (mark) =>
13
+ !schema.decorators.map((decorator) => decorator.name).includes(mark),
14
+ )
15
+ }
@@ -1,20 +1,34 @@
1
- import {Editor} from 'slate'
2
- import type {PortableTextSlateEditor} from '../types/editor'
1
+ import type {MarkState} from '../internal-utils/mark-state'
3
2
  import type {EditorSchema} from './editor-schema'
4
3
 
5
4
  export function getActiveDecorators({
5
+ decoratorState,
6
+ markState,
6
7
  schema,
7
- slateEditorInstance,
8
8
  }: {
9
+ decoratorState: Record<string, boolean | undefined>
10
+ markState: MarkState | undefined
9
11
  schema: EditorSchema
10
- slateEditorInstance: PortableTextSlateEditor
11
12
  }) {
12
13
  const decorators = schema.decorators.map((decorator) => decorator.name)
13
14
 
14
- const marks =
15
- {
16
- ...(Editor.marks(slateEditorInstance) ?? {}),
17
- }.marks ?? []
15
+ const markStateDecorators = (markState?.marks ?? []).filter((mark) =>
16
+ decorators.includes(mark),
17
+ )
18
18
 
19
- return marks.filter((mark) => decorators.includes(mark))
19
+ let activeDecorators: Array<string> = markStateDecorators
20
+
21
+ for (const decorator in decoratorState) {
22
+ if (decoratorState[decorator] === false) {
23
+ activeDecorators = activeDecorators.filter(
24
+ (activeDecorator) => activeDecorator !== decorator,
25
+ )
26
+ } else if (decoratorState[decorator] === true) {
27
+ if (!activeDecorators.includes(decorator)) {
28
+ activeDecorators.push(decorator)
29
+ }
30
+ }
31
+ }
32
+
33
+ return activeDecorators
20
34
  }
@@ -11,7 +11,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
11
11
  return editor
12
12
  }
13
13
 
14
- const {insertText, select} = editor
14
+ const {select} = editor
15
15
 
16
16
  editor.deleteBackward = (unit) => {
17
17
  if (isApplyingBehaviorOperations(editor)) {
@@ -103,9 +103,15 @@ export function createWithEventListeners(editorActor: EditorActor) {
103
103
  return
104
104
  }
105
105
 
106
- editor.insertText = (text, options) => {
106
+ editor.insertText = (text) => {
107
107
  if (isApplyingBehaviorOperations(editor)) {
108
- insertText(text, options)
108
+ insertTextOperationImplementation({
109
+ context: {
110
+ keyGenerator: editorActor.getSnapshot().context.keyGenerator,
111
+ schema: editorActor.getSnapshot().context.schema,
112
+ },
113
+ operation: {type: 'insert.text', text, editor},
114
+ })
109
115
  return
110
116
  }
111
117
 
@@ -36,7 +36,7 @@ import type {
36
36
  PortableTextSlateEditor,
37
37
  } from '../../types/editor'
38
38
  import type {EditorActor} from '../editor-machine'
39
- import {isDecoratorActive} from './createWithPortableTextMarkModel'
39
+ import {getEditorSnapshot} from '../editor-selector'
40
40
 
41
41
  const debug = debugWithName('API:editable')
42
42
 
@@ -90,21 +90,23 @@ export function createEditableAPI(
90
90
  })
91
91
  },
92
92
  isMarkActive: (mark: string): boolean => {
93
- // Try/catch this, as Slate may error because the selection is currently wrong
94
- // TODO: catch only relevant error from Slate
95
- try {
96
- return isDecoratorActive({editor, decorator: mark})
97
- } catch (err) {
98
- console.warn(err)
99
- return false
100
- }
93
+ const snapshot = getEditorSnapshot({
94
+ editorActorSnapshot: editorActor.getSnapshot(),
95
+ slateEditorInstance: editor,
96
+ })
97
+
98
+ return snapshot.beta.activeDecorators.includes(mark)
101
99
  },
102
100
  marks: (): string[] => {
103
- return (
104
- {
105
- ...(Editor.marks(editor) || {}),
106
- }.marks || []
107
- )
101
+ const snapshot = getEditorSnapshot({
102
+ editorActorSnapshot: editorActor.getSnapshot(),
103
+ slateEditorInstance: editor,
104
+ })
105
+
106
+ return [
107
+ ...snapshot.beta.activeAnnotations,
108
+ ...snapshot.beta.activeDecorators,
109
+ ]
108
110
  },
109
111
  undo: (): void => {
110
112
  editorActor.send({