@portabletext/editor 1.40.2 → 1.40.3

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 (58) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +37 -16
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +22 -10
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/editor-provider.cjs +27 -67
  6. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  7. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +26 -0
  8. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -0
  9. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +1 -0
  10. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
  11. package/lib/_chunks-es/behavior.core.js +37 -16
  12. package/lib/_chunks-es/behavior.core.js.map +1 -1
  13. package/lib/_chunks-es/behavior.markdown.js +22 -10
  14. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  15. package/lib/_chunks-es/editor-provider.js +27 -67
  16. package/lib/_chunks-es/editor-provider.js.map +1 -1
  17. package/lib/_chunks-es/util.merge-text-blocks.js +27 -0
  18. package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -0
  19. package/lib/_chunks-es/util.selection-point-to-block-offset.js +1 -0
  20. package/lib/behaviors/index.d.cts +3881 -5053
  21. package/lib/behaviors/index.d.ts +3881 -5053
  22. package/lib/index.d.cts +3402 -4440
  23. package/lib/index.d.ts +3402 -4440
  24. package/lib/plugins/index.cjs +9 -127
  25. package/lib/plugins/index.cjs.map +1 -1
  26. package/lib/plugins/index.d.cts +3404 -4441
  27. package/lib/plugins/index.d.ts +3404 -4441
  28. package/lib/plugins/index.js +11 -129
  29. package/lib/plugins/index.js.map +1 -1
  30. package/lib/selectors/index.d.cts +3401 -4440
  31. package/lib/selectors/index.d.ts +3401 -4440
  32. package/lib/utils/index.cjs +45 -4
  33. package/lib/utils/index.cjs.map +1 -1
  34. package/lib/utils/index.d.cts +3402 -4441
  35. package/lib/utils/index.d.ts +3402 -4441
  36. package/lib/utils/index.js +45 -3
  37. package/lib/utils/index.js.map +1 -1
  38. package/package.json +7 -7
  39. package/src/behavior-actions/behavior.action.delete.block.ts +2 -2
  40. package/src/behavior-actions/behavior.actions.ts +0 -18
  41. package/src/behaviors/behavior.core.block-objects.ts +57 -7
  42. package/src/behaviors/behavior.core.insert-break.ts +0 -4
  43. package/src/behaviors/behavior.default.ts +1 -1
  44. package/src/behaviors/behavior.markdown.ts +22 -10
  45. package/src/behaviors/behavior.types.ts +171 -138
  46. package/src/editor/create-editor.ts +2 -0
  47. package/src/editor/editor-machine.ts +28 -28
  48. package/src/editor/plugins/create-with-event-listeners.ts +15 -0
  49. package/src/editor/plugins/createWithEditableAPI.ts +4 -4
  50. package/src/plugins/plugin.one-line.tsx +10 -128
  51. package/src/types/block-with-optional-key.ts +13 -0
  52. package/src/utils/util.is-text-block.ts +4 -3
  53. package/lib/_chunks-cjs/util.split-text-block.cjs +0 -68
  54. package/lib/_chunks-cjs/util.split-text-block.cjs.map +0 -1
  55. package/lib/_chunks-es/util.split-text-block.js +0 -70
  56. package/lib/_chunks-es/util.split-text-block.js.map +0 -1
  57. package/src/behavior-actions/behavior.action.insert.block-object.ts +0 -20
  58. package/src/behavior-actions/behavior.action.insert.text-block.ts +0 -33
@@ -22,6 +22,7 @@ import {
22
22
  type Behavior,
23
23
  type CustomBehaviorEvent,
24
24
  type DataBehaviorEvent,
25
+ type ExternalBehaviorEvent,
25
26
  type InternalBehaviorAction,
26
27
  type NativeBehaviorEvent,
27
28
  type SyntheticBehaviorEvent,
@@ -203,6 +204,7 @@ export type InternalEditorEvent =
203
204
  nativeEvent?: {preventDefault: () => void}
204
205
  }
205
206
  | CustomBehaviorEvent
207
+ | ExternalBehaviorEvent
206
208
  | ExternalEditorEvent
207
209
  | MutationEvent
208
210
  | InternalPatchEvent
@@ -222,6 +224,7 @@ export type InternalEditorEvent =
222
224
  */
223
225
  export type InternalEditorEmittedEvent =
224
226
  | EditorEmittedEvent
227
+ | ExternalBehaviorEvent
225
228
  | InternalPatchEvent
226
229
  | PatchesEvent
227
230
  | UnsetEvent
@@ -352,40 +355,37 @@ export const editorMachine = setup({
352
355
  ...context.behaviors.values(),
353
356
  ...defaultBehaviors,
354
357
  ].filter((behavior) => {
358
+ // Catches all events
355
359
  if (behavior.on === '*') {
356
360
  return true
357
361
  }
358
362
 
359
- if (isClipboardBehaviorEvent(event.behaviorEvent)) {
360
- return (
361
- behavior.on === 'clipboard.*' ||
362
- behavior.on === event.behaviorEvent.type
363
- )
364
- }
365
-
366
- if (isDragBehaviorEvent(event.behaviorEvent)) {
367
- return (
368
- behavior.on === 'drag.*' ||
369
- behavior.on === event.behaviorEvent.type
370
- )
371
- }
372
-
373
- if (isInputBehaviorEvent(event.behaviorEvent)) {
374
- return behavior.on === 'input.*'
375
- }
376
-
377
- if (isKeyboardBehaviorEvent(event.behaviorEvent)) {
378
- return (
379
- behavior.on === 'keyboard.*' ||
380
- behavior.on === event.behaviorEvent.type
381
- )
363
+ const [listenedNamespace] =
364
+ behavior.on.includes('*') && behavior.on.includes('.')
365
+ ? behavior.on.split('.')
366
+ : [undefined]
367
+ const [eventNamespace] = event.behaviorEvent.type.includes('.')
368
+ ? event.behaviorEvent.type.split('.')
369
+ : [undefined]
370
+
371
+ // Handles scenarios like a Behavior listening for `select.*` and the event
372
+ // `select.block` is fired.
373
+ if (
374
+ listenedNamespace !== undefined &&
375
+ eventNamespace !== undefined &&
376
+ listenedNamespace === eventNamespace
377
+ ) {
378
+ return true
382
379
  }
383
380
 
384
- if (isMouseBehaviorEvent(event.behaviorEvent)) {
385
- return (
386
- behavior.on === 'mouse.*' ||
387
- behavior.on === event.behaviorEvent.type
388
- )
381
+ // Handles scenarios like a Behavior listening for `select.*` and the event
382
+ // `select` is fired.
383
+ if (
384
+ listenedNamespace !== undefined &&
385
+ eventNamespace === undefined &&
386
+ listenedNamespace === event.behaviorEvent.type
387
+ ) {
388
+ return true
389
389
  }
390
390
 
391
391
  return behavior.on === event.behaviorEvent.type
@@ -46,6 +46,21 @@ export function createWithEventListeners(
46
46
  })
47
47
  break
48
48
 
49
+ case 'insert.block object':
50
+ editorActor.send({
51
+ type: 'behavior event',
52
+ behaviorEvent: {
53
+ type: 'insert.block',
54
+ block: {
55
+ _type: event.blockObject.name,
56
+ ...(event.blockObject.value ?? {}),
57
+ },
58
+ placement: event.placement,
59
+ },
60
+ editor,
61
+ })
62
+ break
63
+
49
64
  default:
50
65
  editorActor.send({
51
66
  type: 'behavior event',
@@ -276,10 +276,10 @@ export function createEditableAPI(
276
276
  editorActor.send({
277
277
  type: 'behavior event',
278
278
  behaviorEvent: {
279
- type: 'insert.block object',
280
- blockObject: {
281
- name: type.name,
282
- value,
279
+ type: 'insert.block',
280
+ block: {
281
+ _type: type.name,
282
+ ...(value ? value : {}),
283
283
  },
284
284
  placement: 'auto',
285
285
  },
@@ -32,58 +32,6 @@ const oneLineBehaviors = [
32
32
  event.placement === 'before' || event.placement === 'after',
33
33
  actions: [() => [{type: 'noop'}]],
34
34
  }),
35
- /**
36
- * Other cases of `insert.block` are allowed.
37
- *
38
- * If a text block is inserted and the focus block is fully selected, then
39
- * the focus block can be replaced with the inserted block.
40
- */
41
- defineBehavior({
42
- on: 'insert.block',
43
- guard: ({snapshot, event}) => {
44
- const focusTextBlock = selectors.getFocusTextBlock(snapshot)
45
- const selectionStartPoint = selectors.getSelectionStartPoint(snapshot)
46
- const selectionEndPoint = selectors.getSelectionEndPoint(snapshot)
47
-
48
- if (
49
- !focusTextBlock ||
50
- !utils.isTextBlock(snapshot.context, event.block) ||
51
- !selectionStartPoint ||
52
- !selectionEndPoint
53
- ) {
54
- return false
55
- }
56
-
57
- const blockStartPoint = utils.getBlockStartPoint(focusTextBlock)
58
- const blockEndPoint = utils.getBlockEndPoint(focusTextBlock)
59
- const newFocus = utils.getBlockEndPoint({
60
- node: event.block,
61
- path: [{_key: event.block._key}],
62
- })
63
-
64
- if (
65
- utils.isEqualSelectionPoints(blockStartPoint, selectionStartPoint) &&
66
- utils.isEqualSelectionPoints(blockEndPoint, selectionEndPoint)
67
- ) {
68
- return {focusTextBlock, newFocus}
69
- }
70
-
71
- return false
72
- },
73
- actions: [
74
- ({event}, {focusTextBlock, newFocus}) => [
75
- {type: 'delete.block', blockPath: focusTextBlock.path},
76
- {type: 'insert.block', block: event.block, placement: 'auto'},
77
- {
78
- type: 'select',
79
- selection: {
80
- anchor: newFocus,
81
- focus: newFocus,
82
- },
83
- },
84
- ],
85
- ],
86
- }),
87
35
  /**
88
36
  * An ordinary `insert.block` is acceptable if it's a text block. In that
89
37
  * case it will get merged into the existing text block.
@@ -92,62 +40,23 @@ const oneLineBehaviors = [
92
40
  on: 'insert.block',
93
41
  guard: ({snapshot, event}) => {
94
42
  const focusTextBlock = selectors.getFocusTextBlock(snapshot)
95
- const selectionStartPoint = selectors.getSelectionStartPoint(snapshot)
96
- const selectionEndPoint = selectors.getSelectionEndPoint(snapshot)
97
43
 
98
44
  if (
99
45
  !focusTextBlock ||
100
- !utils.isTextBlock(snapshot.context, event.block) ||
101
- !selectionStartPoint ||
102
- !selectionEndPoint
46
+ !utils.isTextBlock(snapshot.context, event.block)
103
47
  ) {
104
48
  return false
105
49
  }
106
50
 
107
- const blockBeforeStartPoint = utils.splitTextBlock({
108
- context: snapshot.context,
109
- block: focusTextBlock.node,
110
- point: selectionStartPoint,
111
- })?.before
112
- const blockAfterEndPoint = utils.splitTextBlock({
113
- context: snapshot.context,
114
- block: focusTextBlock.node,
115
- point: selectionEndPoint,
116
- })?.after
117
-
118
- if (!blockBeforeStartPoint || !blockAfterEndPoint) {
119
- return false
120
- }
121
-
122
- const targetBlock = utils.mergeTextBlocks({
123
- context: snapshot.context,
124
- targetBlock: blockBeforeStartPoint,
125
- incomingBlock: event.block,
126
- })
127
-
128
- const newFocus = utils.getBlockEndPoint({
129
- node: targetBlock,
130
- path: [{_key: targetBlock._key}],
131
- })
132
-
133
- const mergedBlock = utils.mergeTextBlocks({
134
- context: snapshot.context,
135
- targetBlock,
136
- incomingBlock: blockAfterEndPoint,
137
- })
138
-
139
- return {focusTextBlock, mergedBlock, newFocus}
51
+ return true
140
52
  },
141
53
  actions: [
142
- (_, {focusTextBlock, mergedBlock, newFocus}) => [
143
- {type: 'delete.block', blockPath: focusTextBlock.path},
144
- {type: 'insert.block', block: mergedBlock, placement: 'auto'},
54
+ ({event}) => [
145
55
  {
146
- type: 'select',
147
- selection: {
148
- anchor: newFocus,
149
- focus: newFocus,
150
- },
56
+ type: 'insert.block',
57
+ block: event.block,
58
+ placement: 'auto',
59
+ select: 'end',
151
60
  },
152
61
  ],
153
62
  ],
@@ -166,12 +75,12 @@ const oneLineBehaviors = [
166
75
  */
167
76
  defineBehavior({
168
77
  on: 'insert.blocks',
169
- guard: ({context, event}) => {
78
+ guard: ({snapshot, event}) => {
170
79
  return event.blocks
171
- .filter((block) => utils.isTextBlock(context, block))
80
+ .filter((block) => utils.isTextBlock(snapshot.context, block))
172
81
  .reduce((targetBlock, incomingBlock) => {
173
82
  return utils.mergeTextBlocks({
174
- context,
83
+ context: snapshot.context,
175
84
  targetBlock,
176
85
  incomingBlock,
177
86
  })
@@ -183,33 +92,6 @@ const oneLineBehaviors = [
183
92
  (_, block) => [raise({type: 'insert.block', block, placement: 'auto'})],
184
93
  ],
185
94
  }),
186
- /**
187
- * Block objects do not fit in a one-line editor
188
- */
189
- defineBehavior({
190
- on: 'insert.block object',
191
- actions: [() => [{type: 'noop'}]],
192
- }),
193
- /**
194
- * `insert.text block` is raised as an `insert.block` so it can be handled
195
- * by the Behaviors above.
196
- */
197
- defineBehavior({
198
- on: 'insert.text block',
199
- actions: [
200
- ({context, event}) => [
201
- raise({
202
- type: 'insert.block',
203
- block: {
204
- _key: context.keyGenerator(),
205
- _type: context.schema.block.name,
206
- children: event.textBlock?.children ?? [],
207
- },
208
- placement: event.placement,
209
- }),
210
- ],
211
- ],
212
- }),
213
95
  ]
214
96
 
215
97
  /**
@@ -0,0 +1,13 @@
1
+ import type {PortableTextObject, PortableTextTextBlock} from '@sanity/types'
2
+
3
+ export type TextBlockWithOptionalKey = Omit<PortableTextTextBlock, '_key'> & {
4
+ _key?: PortableTextTextBlock['_key']
5
+ }
6
+
7
+ export type ObjectBlockWithOptionalKey = Omit<PortableTextObject, '_key'> & {
8
+ _key?: PortableTextObject['_key']
9
+ }
10
+
11
+ export type BlockWithOptionalKey =
12
+ | TextBlockWithOptionalKey
13
+ | ObjectBlockWithOptionalKey
@@ -1,12 +1,13 @@
1
- import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'
1
+ import type {PortableTextTextBlock} from '@sanity/types'
2
2
  import type {EditorContext} from '..'
3
+ import {isTypedObject} from '../internal-utils/asserters'
3
4
 
4
5
  /**
5
6
  * @public
6
7
  */
7
8
  export function isTextBlock(
8
9
  context: Pick<EditorContext, 'schema'>,
9
- block: PortableTextBlock,
10
+ block: unknown,
10
11
  ): block is PortableTextTextBlock {
11
- return block._type === context.schema.block.name
12
+ return isTypedObject(block) && block._type === context.schema.block.name
12
13
  }
@@ -1,68 +0,0 @@
1
- "use strict";
2
- var util_selectionPointToBlockOffset = require("./util.selection-point-to-block-offset.cjs"), util_sliceBlocks = require("./util.slice-blocks.cjs");
3
- function isTextBlock(context, block) {
4
- return block._type === context.schema.block.name;
5
- }
6
- function mergeTextBlocks({
7
- context,
8
- targetBlock,
9
- incomingBlock
10
- }) {
11
- const parsedIncomingBlock = util_selectionPointToBlockOffset.parseBlock({
12
- context,
13
- block: incomingBlock,
14
- options: {
15
- refreshKeys: !0
16
- }
17
- });
18
- return !parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock) ? targetBlock : {
19
- ...targetBlock,
20
- children: [...targetBlock.children, ...parsedIncomingBlock.children],
21
- markDefs: [...targetBlock.markDefs ?? [], ...parsedIncomingBlock.markDefs ?? []]
22
- };
23
- }
24
- function splitTextBlock({
25
- context,
26
- block,
27
- point
28
- }) {
29
- const firstChild = block.children.at(0), lastChild = block.children.at(block.children.length - 1);
30
- if (!firstChild || !lastChild)
31
- return;
32
- const before = util_sliceBlocks.sliceBlocks({
33
- blocks: [block],
34
- selection: {
35
- anchor: {
36
- path: [{
37
- _key: block._key
38
- }, "children", {
39
- _key: firstChild._key
40
- }],
41
- offset: 0
42
- },
43
- focus: point
44
- }
45
- }).at(0), after = util_sliceBlocks.sliceBlocks({
46
- blocks: [block],
47
- selection: {
48
- anchor: point,
49
- focus: {
50
- path: [{
51
- _key: block._key
52
- }, "children", {
53
- _key: lastChild._key
54
- }],
55
- offset: util_sliceBlocks.isSpan(context, lastChild) ? lastChild.text.length : 0
56
- }
57
- }
58
- }).at(0);
59
- if (!(!before || !after) && !(!isTextBlock(context, before) || !isTextBlock(context, after)))
60
- return {
61
- before,
62
- after
63
- };
64
- }
65
- exports.isTextBlock = isTextBlock;
66
- exports.mergeTextBlocks = mergeTextBlocks;
67
- exports.splitTextBlock = splitTextBlock;
68
- //# sourceMappingURL=util.split-text-block.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.split-text-block.cjs","sources":["../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isTextBlock","context","block","_type","schema","name","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","children","markDefs","splitTextBlock","point","firstChild","at","lastChild","length","before","sliceBlocks","blocks","selection","anchor","path","_key","offset","focus","after","isSpan","text"],"mappings":";;AAMgBA,SAAAA,YACdC,SACAC,OACgC;AAChC,SAAOA,MAAMC,UAAUF,QAAQG,OAAOF,MAAMG;AAC9C;ACHO,SAASC,gBAAgB;AAAA,EAC9BL;AAAAA,EACAM;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,iCAAAA,WAAW;AAAA,IACrCT;AAAAA,IACAC,OAAOM;AAAAA,IACPG,SAAS;AAAA,MAACC,aAAa;AAAA,IAAA;AAAA,EAAI,CAC5B;AAED,SAAI,CAACH,uBAAuB,CAACT,YAAYC,SAASQ,mBAAmB,IAC5DF,cAGF;AAAA,IACL,GAAGA;AAAAA,IACHM,UAAU,CAAC,GAAGN,YAAYM,UAAU,GAAGJ,oBAAoBI,QAAQ;AAAA,IACnEC,UAAU,CACR,GAAIP,YAAYO,YAAY,CAAA,GAC5B,GAAIL,oBAAoBK,YAAY,CAAG,CAAA;AAAA,EAE3C;AACF;ACzBO,SAASC,eAAe;AAAA,EAC7Bd;AAAAA,EACAC;AAAAA,EACAc;AAKF,GAA8E;AAC5E,QAAMC,aAAaf,MAAMW,SAASK,GAAG,CAAC,GAChCC,YAAYjB,MAAMW,SAASK,GAAGhB,MAAMW,SAASO,SAAS,CAAC;AAEzD,MAAA,CAACH,cAAc,CAACE;AAClB;AAGF,QAAME,SAASC,iBAAAA,YAAY;AAAA,IACzBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQ;AAAA,QACNC,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAC,OAAOb;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEE,GAAG,CAAC,GACDY,QAAQR,iBAAAA,YAAY;AAAA,IACxBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQT;AAAAA,MACRa,OAAO;AAAA,QACLH,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,UAAUQ;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQG,iBAAO9B,OAAAA,SAASkB,SAAS,IAAIA,UAAUa,KAAKZ,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACS,UAIZ,EAAC9B,CAAAA,YAAYC,SAASoB,MAAM,KAAK,CAACrB,YAAYC,SAAS6B,KAAK;AAIzD,WAAA;AAAA,MAACT;AAAAA,MAAQS;AAAAA,IAAK;AACvB;;;;"}
@@ -1,70 +0,0 @@
1
- import { parseBlock } from "./util.selection-point-to-block-offset.js";
2
- import { sliceBlocks, isSpan } from "./util.slice-blocks.js";
3
- function isTextBlock(context, block) {
4
- return block._type === context.schema.block.name;
5
- }
6
- function mergeTextBlocks({
7
- context,
8
- targetBlock,
9
- incomingBlock
10
- }) {
11
- const parsedIncomingBlock = parseBlock({
12
- context,
13
- block: incomingBlock,
14
- options: {
15
- refreshKeys: !0
16
- }
17
- });
18
- return !parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock) ? targetBlock : {
19
- ...targetBlock,
20
- children: [...targetBlock.children, ...parsedIncomingBlock.children],
21
- markDefs: [...targetBlock.markDefs ?? [], ...parsedIncomingBlock.markDefs ?? []]
22
- };
23
- }
24
- function splitTextBlock({
25
- context,
26
- block,
27
- point
28
- }) {
29
- const firstChild = block.children.at(0), lastChild = block.children.at(block.children.length - 1);
30
- if (!firstChild || !lastChild)
31
- return;
32
- const before = sliceBlocks({
33
- blocks: [block],
34
- selection: {
35
- anchor: {
36
- path: [{
37
- _key: block._key
38
- }, "children", {
39
- _key: firstChild._key
40
- }],
41
- offset: 0
42
- },
43
- focus: point
44
- }
45
- }).at(0), after = sliceBlocks({
46
- blocks: [block],
47
- selection: {
48
- anchor: point,
49
- focus: {
50
- path: [{
51
- _key: block._key
52
- }, "children", {
53
- _key: lastChild._key
54
- }],
55
- offset: isSpan(context, lastChild) ? lastChild.text.length : 0
56
- }
57
- }
58
- }).at(0);
59
- if (!(!before || !after) && !(!isTextBlock(context, before) || !isTextBlock(context, after)))
60
- return {
61
- before,
62
- after
63
- };
64
- }
65
- export {
66
- isTextBlock,
67
- mergeTextBlocks,
68
- splitTextBlock
69
- };
70
- //# sourceMappingURL=util.split-text-block.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.split-text-block.js","sources":["../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isTextBlock","context","block","_type","schema","name","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","children","markDefs","splitTextBlock","point","firstChild","at","lastChild","length","before","sliceBlocks","blocks","selection","anchor","path","_key","offset","focus","after","isSpan","text"],"mappings":";;AAMgBA,SAAAA,YACdC,SACAC,OACgC;AAChC,SAAOA,MAAMC,UAAUF,QAAQG,OAAOF,MAAMG;AAC9C;ACHO,SAASC,gBAAgB;AAAA,EAC9BL;AAAAA,EACAM;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,WAAW;AAAA,IACrCT;AAAAA,IACAC,OAAOM;AAAAA,IACPG,SAAS;AAAA,MAACC,aAAa;AAAA,IAAA;AAAA,EAAI,CAC5B;AAED,SAAI,CAACH,uBAAuB,CAACT,YAAYC,SAASQ,mBAAmB,IAC5DF,cAGF;AAAA,IACL,GAAGA;AAAAA,IACHM,UAAU,CAAC,GAAGN,YAAYM,UAAU,GAAGJ,oBAAoBI,QAAQ;AAAA,IACnEC,UAAU,CACR,GAAIP,YAAYO,YAAY,CAAA,GAC5B,GAAIL,oBAAoBK,YAAY,CAAG,CAAA;AAAA,EAE3C;AACF;ACzBO,SAASC,eAAe;AAAA,EAC7Bd;AAAAA,EACAC;AAAAA,EACAc;AAKF,GAA8E;AAC5E,QAAMC,aAAaf,MAAMW,SAASK,GAAG,CAAC,GAChCC,YAAYjB,MAAMW,SAASK,GAAGhB,MAAMW,SAASO,SAAS,CAAC;AAEzD,MAAA,CAACH,cAAc,CAACE;AAClB;AAGF,QAAME,SAASC,YAAY;AAAA,IACzBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQ;AAAA,QACNC,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAC,OAAOb;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEE,GAAG,CAAC,GACDY,QAAQR,YAAY;AAAA,IACxBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQT;AAAAA,MACRa,OAAO;AAAA,QACLH,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,UAAUQ;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQG,OAAO9B,SAASkB,SAAS,IAAIA,UAAUa,KAAKZ,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACS,UAIZ,EAAC9B,CAAAA,YAAYC,SAASoB,MAAM,KAAK,CAACrB,YAAYC,SAAS6B,KAAK;AAIzD,WAAA;AAAA,MAACT;AAAAA,MAAQS;AAAAA,IAAK;AACvB;"}
@@ -1,20 +0,0 @@
1
- import {insertBlockActionImplementation} from './behavior.action.insert.block'
2
- import type {BehaviorActionImplementation} from './behavior.actions'
3
-
4
- export const insertBlockObjectActionImplementation: BehaviorActionImplementation<
5
- 'insert.block object'
6
- > = ({context, action}) => {
7
- insertBlockActionImplementation({
8
- context,
9
- action: {
10
- type: 'insert.block',
11
- block: {
12
- _key: context.keyGenerator(),
13
- _type: action.blockObject.name,
14
- ...(action.blockObject.value ? action.blockObject.value : {}),
15
- },
16
- editor: action.editor,
17
- placement: action.placement,
18
- },
19
- })
20
- }
@@ -1,33 +0,0 @@
1
- import {insertBlockActionImplementation} from './behavior.action.insert.block'
2
- import type {BehaviorActionImplementation} from './behavior.actions'
3
-
4
- export const insertTextBlockActionImplementation: BehaviorActionImplementation<
5
- 'insert.text block'
6
- > = ({context, action}) => {
7
- insertBlockActionImplementation({
8
- context,
9
- action: {
10
- type: 'insert.block',
11
- block: {
12
- _key: context.keyGenerator(),
13
- _type: context.schema.block.name,
14
- children: action.textBlock?.children?.map((child) => ({
15
- ...child,
16
- _key: context.keyGenerator(),
17
- })) ?? [
18
- {
19
- _type: context.schema.span.name,
20
- _key: context.keyGenerator(),
21
- text: '',
22
- marks: [],
23
- },
24
- ],
25
- markDefs: [],
26
- style: context.schema.styles[0].value ?? 'normal',
27
- },
28
- editor: action.editor,
29
- placement: action.placement,
30
- select: 'start',
31
- },
32
- })
33
- }