@portabletext/editor 1.50.8 → 1.52.0

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 (104) hide show
  1. package/lib/_chunks-cjs/{util.slice-blocks.cjs → selection-point.cjs} +26 -18
  2. package/lib/_chunks-cjs/selection-point.cjs.map +1 -0
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs +13 -10
  4. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  5. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +46 -46
  6. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  7. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +21 -17
  8. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
  9. package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs +10 -10
  10. package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs.map +1 -1
  11. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +5 -5
  12. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs.map +1 -1
  13. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +3 -3
  14. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  15. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +7 -14
  16. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
  17. package/lib/_chunks-es/{util.slice-blocks.js → selection-point.js} +26 -18
  18. package/lib/_chunks-es/selection-point.js.map +1 -0
  19. package/lib/_chunks-es/selector.get-text-before.js +13 -10
  20. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  21. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +21 -21
  22. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  23. package/lib/_chunks-es/selector.is-selection-expanded.js +14 -10
  24. package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
  25. package/lib/_chunks-es/util.child-selection-point-to-block-offset.js +2 -2
  26. package/lib/_chunks-es/util.child-selection-point-to-block-offset.js.map +1 -1
  27. package/lib/_chunks-es/util.is-equal-selection-points.js +1 -1
  28. package/lib/_chunks-es/util.merge-text-blocks.js +1 -1
  29. package/lib/_chunks-es/util.selection-point-to-block-offset.js +4 -11
  30. package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
  31. package/lib/behaviors/index.cjs.map +1 -1
  32. package/lib/behaviors/index.d.cts +25 -2010
  33. package/lib/behaviors/index.d.ts +25 -2010
  34. package/lib/behaviors/index.js.map +1 -1
  35. package/lib/index.cjs +515 -393
  36. package/lib/index.cjs.map +1 -1
  37. package/lib/index.d.cts +361 -34
  38. package/lib/index.d.ts +361 -34
  39. package/lib/index.js +471 -349
  40. package/lib/index.js.map +1 -1
  41. package/lib/plugins/index.cjs +11 -11
  42. package/lib/plugins/index.cjs.map +1 -1
  43. package/lib/plugins/index.d.cts +32 -1986
  44. package/lib/plugins/index.d.ts +32 -1986
  45. package/lib/plugins/index.js +1 -1
  46. package/lib/selectors/index.cjs +11 -7
  47. package/lib/selectors/index.cjs.map +1 -1
  48. package/lib/selectors/index.d.cts +2 -2648
  49. package/lib/selectors/index.d.ts +2 -2648
  50. package/lib/selectors/index.js +7 -3
  51. package/lib/selectors/index.js.map +1 -1
  52. package/lib/utils/index.cjs +25 -14
  53. package/lib/utils/index.cjs.map +1 -1
  54. package/lib/utils/index.d.cts +0 -2647
  55. package/lib/utils/index.d.ts +0 -2647
  56. package/lib/utils/index.js +14 -3
  57. package/lib/utils/index.js.map +1 -1
  58. package/package.json +14 -14
  59. package/src/behaviors/behavior.abstract.delete.ts +0 -2
  60. package/src/behaviors/behavior.abstract.insert.ts +8 -8
  61. package/src/behaviors/behavior.abstract.ts +0 -113
  62. package/src/behaviors/behavior.core.block-element.ts +9 -3
  63. package/src/behaviors/behavior.core.dnd.ts +328 -1
  64. package/src/behaviors/behavior.perform-event.ts +10 -0
  65. package/src/behaviors/behavior.types.action.ts +2 -0
  66. package/src/behaviors/behavior.types.event.ts +5 -0
  67. package/src/behaviors/behavior.types.guard.ts +2 -0
  68. package/src/converters/converter.portable-text.ts +2 -7
  69. package/src/converters/converter.text-html.ts +1 -3
  70. package/src/converters/converter.text-plain.ts +3 -5
  71. package/src/editor/Editable.tsx +6 -133
  72. package/src/editor/editor-machine.ts +15 -10
  73. package/src/editor/editor-selector.ts +0 -2
  74. package/src/editor/editor-snapshot.ts +0 -18
  75. package/src/internal-utils/create-test-snapshot.ts +0 -2
  76. package/src/internal-utils/event-position.ts +42 -30
  77. package/src/internal-utils/selection-block-keys.ts +7 -7
  78. package/src/internal-utils/selection-elements.ts +108 -0
  79. package/src/internal-utils/selection-focus-text.ts +13 -9
  80. package/src/internal-utils/selection-text.ts +9 -78
  81. package/src/internal-utils/terse-pt.test.ts +108 -26
  82. package/src/internal-utils/terse-pt.ts +132 -14
  83. package/src/operations/behavior.operation.decorator.add.ts +0 -2
  84. package/src/operations/behavior.operation.delete.ts +18 -13
  85. package/src/operations/behavior.operation.insert.block.ts +5 -1
  86. package/src/selection/selection-point.ts +22 -0
  87. package/src/selectors/selector.get-anchor-block.ts +6 -6
  88. package/src/selectors/selector.get-anchor-child.ts +6 -6
  89. package/src/selectors/selector.get-selected-spans.ts +16 -19
  90. package/src/selectors/selector.get-selected-text-blocks.ts +11 -19
  91. package/src/selectors/selector.get-selection-end-block.ts +30 -0
  92. package/src/selectors/selector.get-selection-start-block.ts +30 -0
  93. package/src/selectors/selector.get-text-before.ts +15 -16
  94. package/src/selectors/selector.get-trimmed-selection.ts +15 -21
  95. package/src/selectors/selector.is-point-after-selection.ts +11 -19
  96. package/src/selectors/selector.is-point-before-selection.ts +11 -19
  97. package/src/selectors/selectors.ts +23 -39
  98. package/src/utils/util.block-offset.ts +6 -7
  99. package/src/utils/util.child-selection-point-to-block-offset.ts +6 -7
  100. package/src/utils/util.selection-point-to-block-offset.ts +5 -6
  101. package/src/utils/util.slice-blocks.ts +11 -20
  102. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +0 -1
  103. package/lib/_chunks-es/util.slice-blocks.js.map +0 -1
  104. package/src/internal-utils/inline-object-selection.ts +0 -115
@@ -1,7 +1,8 @@
1
1
  import type {KeyedSegment, PortableTextTextBlock} from '@sanity/types'
2
2
  import type {EditorSelector} from '../editor/editor-selector'
3
3
  import {isTextBlock} from '../internal-utils/parse-blocks'
4
- import {isKeyedSegment} from '../utils'
4
+ import {getBlockKeyFromSelectionPoint} from '../selection/selection-point'
5
+ import {getSelectionEndPoint, getSelectionStartPoint} from '../utils'
5
6
 
6
7
  /**
7
8
  * @public
@@ -17,38 +18,29 @@ export const getSelectedTextBlocks: EditorSelector<
17
18
  node: PortableTextTextBlock
18
19
  path: [KeyedSegment]
19
20
  }> = []
20
- const startKey = snapshot.context.selection.backward
21
- ? isKeyedSegment(snapshot.context.selection.focus.path[0])
22
- ? snapshot.context.selection.focus.path[0]._key
23
- : undefined
24
- : isKeyedSegment(snapshot.context.selection.anchor.path[0])
25
- ? snapshot.context.selection.anchor.path[0]._key
26
- : undefined
27
- const endKey = snapshot.context.selection.backward
28
- ? isKeyedSegment(snapshot.context.selection.anchor.path[0])
29
- ? snapshot.context.selection.anchor.path[0]._key
30
- : undefined
31
- : isKeyedSegment(snapshot.context.selection.focus.path[0])
32
- ? snapshot.context.selection.focus.path[0]._key
33
- : undefined
34
21
 
35
- if (!startKey || !endKey) {
22
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
23
+ const endPoint = getSelectionEndPoint(snapshot.context.selection)
24
+ const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
25
+ const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
26
+
27
+ if (!startBlockKey || !endBlockKey) {
36
28
  return selectedTextBlocks
37
29
  }
38
30
 
39
31
  for (const block of snapshot.context.value) {
40
- if (block._key === startKey) {
32
+ if (block._key === startBlockKey) {
41
33
  if (isTextBlock(snapshot.context, block)) {
42
34
  selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
43
35
  }
44
36
 
45
- if (startKey === endKey) {
37
+ if (startBlockKey === endBlockKey) {
46
38
  break
47
39
  }
48
40
  continue
49
41
  }
50
42
 
51
- if (block._key === endKey) {
43
+ if (block._key === endBlockKey) {
52
44
  if (isTextBlock(snapshot.context, block)) {
53
45
  selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
54
46
  }
@@ -0,0 +1,30 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import type {BlockPath} from '../types/paths'
4
+ import {getSelectionEndPoint} from '../utils/util.get-selection-end-point'
5
+ import {getFocusBlock} from './selectors'
6
+
7
+ export const getSelectionEndBlock: EditorSelector<
8
+ | {
9
+ node: PortableTextBlock
10
+ path: BlockPath
11
+ }
12
+ | undefined
13
+ > = (snapshot) => {
14
+ const endPoint = getSelectionEndPoint(snapshot.context.selection)
15
+
16
+ if (!endPoint) {
17
+ return undefined
18
+ }
19
+
20
+ return getFocusBlock({
21
+ ...snapshot,
22
+ context: {
23
+ ...snapshot.context,
24
+ selection: {
25
+ anchor: endPoint,
26
+ focus: endPoint,
27
+ },
28
+ },
29
+ })
30
+ }
@@ -0,0 +1,30 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import type {BlockPath} from '../types/paths'
4
+ import {getSelectionStartPoint} from '../utils/util.get-selection-start-point'
5
+ import {getFocusBlock} from './selectors'
6
+
7
+ export const getSelectionStartBlock: EditorSelector<
8
+ | {
9
+ node: PortableTextBlock
10
+ path: BlockPath
11
+ }
12
+ | undefined
13
+ > = (snapshot) => {
14
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
15
+
16
+ if (!startPoint) {
17
+ return undefined
18
+ }
19
+
20
+ return getFocusBlock({
21
+ ...snapshot,
22
+ context: {
23
+ ...snapshot.context,
24
+ selection: {
25
+ anchor: startPoint,
26
+ focus: startPoint,
27
+ },
28
+ },
29
+ })
30
+ }
@@ -1,8 +1,8 @@
1
1
  import type {EditorSelector} from '../editor/editor-selector'
2
+ import {getSelectionStartPoint} from '../utils'
2
3
  import {getBlockStartPoint} from '../utils/util.get-block-start-point'
3
- import {isKeyedSegment} from '../utils/util.is-keyed-segment'
4
- import {reverseSelection} from '../utils/util.reverse-selection'
5
4
  import {getSelectionText} from './selector.get-selection-text'
5
+ import {getFocusBlock} from './selectors'
6
6
 
7
7
  /**
8
8
  * @public
@@ -12,15 +12,17 @@ export const getBlockTextBefore: EditorSelector<string> = (snapshot) => {
12
12
  return ''
13
13
  }
14
14
 
15
- const selection = snapshot.context.selection.backward
16
- ? reverseSelection(snapshot.context.selection)
17
- : snapshot.context.selection
18
- const point = selection.anchor
19
- const key = isKeyedSegment(point.path[0]) ? point.path[0]._key : undefined
20
-
21
- const block = key
22
- ? snapshot.context.value.find((block) => block._key === key)
23
- : undefined
15
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
16
+ const block = getFocusBlock({
17
+ ...snapshot,
18
+ context: {
19
+ ...snapshot.context,
20
+ selection: {
21
+ anchor: startPoint,
22
+ focus: startPoint,
23
+ },
24
+ },
25
+ })
24
26
 
25
27
  if (!block) {
26
28
  return ''
@@ -28,10 +30,7 @@ export const getBlockTextBefore: EditorSelector<string> = (snapshot) => {
28
30
 
29
31
  const startOfBlock = getBlockStartPoint({
30
32
  context: snapshot.context,
31
- block: {
32
- node: block,
33
- path: [{_key: block._key}],
34
- },
33
+ block,
35
34
  })
36
35
 
37
36
  return getSelectionText({
@@ -40,7 +39,7 @@ export const getBlockTextBefore: EditorSelector<string> = (snapshot) => {
40
39
  ...snapshot.context,
41
40
  selection: {
42
41
  anchor: startOfBlock,
43
- focus: point,
42
+ focus: startPoint,
44
43
  },
45
44
  },
46
45
  })
@@ -1,10 +1,16 @@
1
1
  import type {PortableTextSpan} from '@sanity/types'
2
2
  import type {EditorSelector} from '../editor/editor-selector'
3
3
  import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
4
+ import {
5
+ getBlockKeyFromSelectionPoint,
6
+ getChildKeyFromSelectionPoint,
7
+ } from '../selection/selection-point'
4
8
  import type {EditorSelection, EditorSelectionPoint} from '../types/editor'
5
- import {isEmptyTextBlock, isKeyedSegment} from '../utils'
6
- import {getSelectionEndPoint} from './selector.get-selection-end-point'
7
- import {getSelectionStartPoint} from './selector.get-selection-start-point'
9
+ import {
10
+ getSelectionEndPoint,
11
+ getSelectionStartPoint,
12
+ isEmptyTextBlock,
13
+ } from '../utils'
8
14
  import {isSelectionCollapsed} from './selector.is-selection-collapsed'
9
15
  import {getFocusTextBlock} from './selectors'
10
16
 
@@ -18,25 +24,13 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
18
24
  return snapshot.context.selection
19
25
  }
20
26
 
21
- const startPoint = getSelectionStartPoint(snapshot)
22
- const endPoint = getSelectionEndPoint(snapshot)
27
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
28
+ const endPoint = getSelectionEndPoint(snapshot.context.selection)
23
29
 
24
- if (!startPoint || !endPoint) {
25
- return snapshot.context.selection
26
- }
27
-
28
- const startBlockKey = isKeyedSegment(startPoint.path[0])
29
- ? startPoint.path[0]._key
30
- : null
31
- const startChildKey = isKeyedSegment(startPoint.path[2])
32
- ? startPoint.path[2]._key
33
- : null
34
- const endBlockKey = isKeyedSegment(endPoint.path[0])
35
- ? endPoint.path[0]._key
36
- : null
37
- const endChildKey = isKeyedSegment(endPoint.path[2])
38
- ? endPoint.path[2]._key
39
- : null
30
+ const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
31
+ const startChildKey = getChildKeyFromSelectionPoint(startPoint)
32
+ const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
33
+ const endChildKey = getChildKeyFromSelectionPoint(endPoint)
40
34
 
41
35
  if (!startBlockKey || !endBlockKey) {
42
36
  return snapshot.context.selection
@@ -1,8 +1,11 @@
1
1
  import type {EditorSelector} from '../editor/editor-selector'
2
2
  import {isTextBlock} from '../internal-utils/parse-blocks'
3
+ import {
4
+ getBlockKeyFromSelectionPoint,
5
+ getChildKeyFromSelectionPoint,
6
+ } from '../selection/selection-point'
3
7
  import type {EditorSelectionPoint} from '../types/editor'
4
- import {isKeyedSegment} from '../utils/util.is-keyed-segment'
5
- import {reverseSelection} from '../utils/util.reverse-selection'
8
+ import {getSelectionEndPoint} from '../utils'
6
9
 
7
10
  /**
8
11
  * @public
@@ -15,23 +18,12 @@ export function isPointAfterSelection(
15
18
  return false
16
19
  }
17
20
 
18
- const selection = snapshot.context.selection.backward
19
- ? reverseSelection(snapshot.context.selection)
20
- : snapshot.context.selection
21
+ const endPoint = getSelectionEndPoint(snapshot.context.selection)
22
+ const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
23
+ const endChildKey = getChildKeyFromSelectionPoint(endPoint)
21
24
 
22
- const pointBlockKey = isKeyedSegment(point.path[0])
23
- ? point.path[0]._key
24
- : undefined
25
- const pointChildKey = isKeyedSegment(point.path[2])
26
- ? point.path[2]._key
27
- : undefined
28
-
29
- const endBlockKey = isKeyedSegment(selection.focus.path[0])
30
- ? selection.focus.path[0]._key
31
- : undefined
32
- const endChildKey = isKeyedSegment(selection.focus.path[2])
33
- ? selection.focus.path[2]._key
34
- : undefined
25
+ const pointBlockKey = getBlockKeyFromSelectionPoint(point)
26
+ const pointChildKey = getChildKeyFromSelectionPoint(point)
35
27
 
36
28
  if (!pointBlockKey || !endBlockKey) {
37
29
  return false
@@ -65,7 +57,7 @@ export function isPointAfterSelection(
65
57
 
66
58
  // Both the point and the selection end in this child
67
59
 
68
- after = point.offset > selection.focus.offset
60
+ after = point.offset > endPoint.offset
69
61
  break
70
62
  }
71
63
 
@@ -1,8 +1,11 @@
1
1
  import type {EditorSelector} from '../editor/editor-selector'
2
2
  import {isTextBlock} from '../internal-utils/parse-blocks'
3
+ import {
4
+ getBlockKeyFromSelectionPoint,
5
+ getChildKeyFromSelectionPoint,
6
+ } from '../selection/selection-point'
3
7
  import type {EditorSelectionPoint} from '../types/editor'
4
- import {isKeyedSegment} from '../utils/util.is-keyed-segment'
5
- import {reverseSelection} from '../utils/util.reverse-selection'
8
+ import {getSelectionStartPoint} from '../utils'
6
9
 
7
10
  /**
8
11
  * @public
@@ -15,23 +18,12 @@ export function isPointBeforeSelection(
15
18
  return false
16
19
  }
17
20
 
18
- const selection = snapshot.context.selection.backward
19
- ? reverseSelection(snapshot.context.selection)
20
- : snapshot.context.selection
21
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
22
+ const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
23
+ const startChildKey = getChildKeyFromSelectionPoint(startPoint)
21
24
 
22
- const pointBlockKey = isKeyedSegment(point.path[0])
23
- ? point.path[0]._key
24
- : undefined
25
- const pointChildKey = isKeyedSegment(point.path[2])
26
- ? point.path[2]._key
27
- : undefined
28
-
29
- const startBlockKey = isKeyedSegment(selection.anchor.path[0])
30
- ? selection.anchor.path[0]._key
31
- : undefined
32
- const startChildKey = isKeyedSegment(selection.anchor.path[2])
33
- ? selection.anchor.path[2]._key
34
- : undefined
25
+ const pointBlockKey = getBlockKeyFromSelectionPoint(point)
26
+ const pointChildKey = getChildKeyFromSelectionPoint(point)
35
27
 
36
28
  if (!pointBlockKey || !startBlockKey) {
37
29
  return false
@@ -65,7 +57,7 @@ export function isPointBeforeSelection(
65
57
 
66
58
  // Both the point and the selection start in this child
67
59
 
68
- before = point.offset < selection.anchor.offset
60
+ before = point.offset < startPoint.offset
69
61
  break
70
62
  }
71
63
 
@@ -8,7 +8,11 @@ import type {
8
8
  } from '@sanity/types'
9
9
  import type {EditorSelector} from '../editor/editor-selector'
10
10
  import {isListBlock, isSpan, isTextBlock} from '../internal-utils/parse-blocks'
11
- import {isKeyedSegment} from '../utils/util.is-keyed-segment'
11
+ import {
12
+ getBlockKeyFromSelectionPoint,
13
+ getChildKeyFromSelectionPoint,
14
+ } from '../selection/selection-point'
15
+ import {getSelectionEndPoint, getSelectionStartPoint} from '../utils'
12
16
 
13
17
  /**
14
18
  * @public
@@ -16,11 +20,11 @@ import {isKeyedSegment} from '../utils/util.is-keyed-segment'
16
20
  export const getFocusBlock: EditorSelector<
17
21
  {node: PortableTextBlock; path: [KeyedSegment]} | undefined
18
22
  > = (snapshot) => {
19
- const key = snapshot.context.selection
20
- ? isKeyedSegment(snapshot.context.selection.focus.path[0])
21
- ? snapshot.context.selection.focus.path[0]._key
22
- : undefined
23
- : undefined
23
+ if (!snapshot.context.selection) {
24
+ return undefined
25
+ }
26
+
27
+ const key = getBlockKeyFromSelectionPoint(snapshot.context.selection.focus)
24
28
 
25
29
  const node = key
26
30
  ? snapshot.context.value.find((block) => block._key === key)
@@ -78,17 +82,17 @@ export const getFocusChild: EditorSelector<
78
82
  }
79
83
  | undefined
80
84
  > = (snapshot) => {
85
+ if (!snapshot.context.selection) {
86
+ return undefined
87
+ }
88
+
81
89
  const focusBlock = getFocusTextBlock(snapshot)
82
90
 
83
91
  if (!focusBlock) {
84
92
  return undefined
85
93
  }
86
94
 
87
- const key = snapshot.context.selection
88
- ? isKeyedSegment(snapshot.context.selection.focus.path[2])
89
- ? snapshot.context.selection.focus.path[2]._key
90
- : undefined
91
- : undefined
95
+ const key = getChildKeyFromSelectionPoint(snapshot.context.selection.focus)
92
96
 
93
97
  const node = key
94
98
  ? focusBlock.node.children.find((span) => span._key === key)
@@ -149,20 +153,10 @@ export const getSelectedBlocks: EditorSelector<
149
153
 
150
154
  const selectedBlocks: Array<{node: PortableTextBlock; path: [KeyedSegment]}> =
151
155
  []
152
- const startKey = snapshot.context.selection.backward
153
- ? isKeyedSegment(snapshot.context.selection.focus.path[0])
154
- ? snapshot.context.selection.focus.path[0]._key
155
- : undefined
156
- : isKeyedSegment(snapshot.context.selection.anchor.path[0])
157
- ? snapshot.context.selection.anchor.path[0]._key
158
- : undefined
159
- const endKey = snapshot.context.selection.backward
160
- ? isKeyedSegment(snapshot.context.selection.anchor.path[0])
161
- ? snapshot.context.selection.anchor.path[0]._key
162
- : undefined
163
- : isKeyedSegment(snapshot.context.selection.focus.path[0])
164
- ? snapshot.context.selection.focus.path[0]._key
165
- : undefined
156
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
157
+ const endPoint = getSelectionEndPoint(snapshot.context.selection)
158
+ const startKey = getBlockKeyFromSelectionPoint(startPoint)
159
+ const endKey = getBlockKeyFromSelectionPoint(endPoint)
166
160
 
167
161
  if (!startKey || !endKey) {
168
162
  return selectedBlocks
@@ -205,13 +199,8 @@ export const getSelectionStartBlock: EditorSelector<
205
199
  return undefined
206
200
  }
207
201
 
208
- const key = snapshot.context.selection.backward
209
- ? isKeyedSegment(snapshot.context.selection.focus.path[0])
210
- ? snapshot.context.selection.focus.path[0]._key
211
- : undefined
212
- : isKeyedSegment(snapshot.context.selection.anchor.path[0])
213
- ? snapshot.context.selection.anchor.path[0]._key
214
- : undefined
202
+ const startPoint = getSelectionStartPoint(snapshot.context.selection)
203
+ const key = getBlockKeyFromSelectionPoint(startPoint)
215
204
 
216
205
  const node = key
217
206
  ? snapshot.context.value.find((block) => block._key === key)
@@ -234,13 +223,8 @@ export const getSelectionEndBlock: EditorSelector<
234
223
  return undefined
235
224
  }
236
225
 
237
- const key = snapshot.context.selection.backward
238
- ? isKeyedSegment(snapshot.context.selection.anchor.path[0])
239
- ? snapshot.context.selection.anchor.path[0]._key
240
- : undefined
241
- : isKeyedSegment(snapshot.context.selection.focus.path[0])
242
- ? snapshot.context.selection.focus.path[0]._key
243
- : undefined
226
+ const endPoint = getSelectionEndPoint(snapshot.context.selection)
227
+ const key = getBlockKeyFromSelectionPoint(endPoint)
244
228
 
245
229
  const node = key
246
230
  ? snapshot.context.value.find((block) => block._key === key)
@@ -1,9 +1,12 @@
1
1
  import type {KeyedSegment} from '@sanity/types'
2
2
  import type {EditorContext} from '../editor/editor-snapshot'
3
3
  import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
4
+ import {
5
+ getBlockKeyFromSelectionPoint,
6
+ getChildKeyFromSelectionPoint,
7
+ } from '../selection/selection-point'
4
8
  import type {BlockOffset} from '../types/block-offset'
5
9
  import type {EditorSelectionPoint} from '../types/editor'
6
- import {isKeyedSegment} from './util.is-keyed-segment'
7
10
 
8
11
  /**
9
12
  * @public
@@ -101,12 +104,8 @@ export function spanSelectionPointToBlockOffset({
101
104
  }): BlockOffset | undefined {
102
105
  let offset = 0
103
106
 
104
- const blockKey = isKeyedSegment(selectionPoint.path[0])
105
- ? selectionPoint.path[0]._key
106
- : undefined
107
- const spanKey = isKeyedSegment(selectionPoint.path[2])
108
- ? selectionPoint.path[2]._key
109
- : undefined
107
+ const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)
108
+ const spanKey = getChildKeyFromSelectionPoint(selectionPoint)
110
109
 
111
110
  if (!blockKey || !spanKey) {
112
111
  return undefined
@@ -1,8 +1,11 @@
1
1
  import type {EditorContext} from '../editor/editor-snapshot'
2
2
  import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
3
+ import {
4
+ getBlockKeyFromSelectionPoint,
5
+ getChildKeyFromSelectionPoint,
6
+ } from '../selection/selection-point'
3
7
  import type {BlockOffset} from '../types/block-offset'
4
8
  import type {EditorSelectionPoint} from '../types/editor'
5
- import {isKeyedSegment} from './util.is-keyed-segment'
6
9
 
7
10
  /**
8
11
  * @public
@@ -16,12 +19,8 @@ export function childSelectionPointToBlockOffset({
16
19
  }): BlockOffset | undefined {
17
20
  let offset = 0
18
21
 
19
- const blockKey = isKeyedSegment(selectionPoint.path[0])
20
- ? selectionPoint.path[0]._key
21
- : undefined
22
- const childKey = isKeyedSegment(selectionPoint.path[2])
23
- ? selectionPoint.path[2]._key
24
- : undefined
22
+ const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)
23
+ const childKey = getChildKeyFromSelectionPoint(selectionPoint)
25
24
 
26
25
  if (!blockKey || !childKey) {
27
26
  return undefined
@@ -1,8 +1,8 @@
1
1
  import type {EditorContext} from '../editor/editor-snapshot'
2
+ import {getBlockKeyFromSelectionPoint} from '../selection/selection-point'
2
3
  import type {BlockOffset} from '../types/block-offset'
3
4
  import type {EditorSelectionPoint} from '../types/editor'
4
5
  import {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'
5
- import {isKeyedSegment} from './util.is-keyed-segment'
6
6
 
7
7
  /**
8
8
  * @public
@@ -14,12 +14,11 @@ export function selectionPointToBlockOffset({
14
14
  context: Pick<EditorContext, 'schema' | 'value'>
15
15
  selectionPoint: EditorSelectionPoint
16
16
  }): BlockOffset | undefined {
17
- if (
18
- selectionPoint.path.length === 1 &&
19
- isKeyedSegment(selectionPoint.path[0])
20
- ) {
17
+ const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)
18
+
19
+ if (selectionPoint.path.length === 1 && blockKey !== undefined) {
21
20
  return {
22
- path: [{_key: selectionPoint.path[0]._key}],
21
+ path: [{_key: blockKey}],
23
22
  offset: selectionPoint.offset,
24
23
  }
25
24
  }
@@ -1,7 +1,11 @@
1
1
  import type {PortableTextBlock} from '@sanity/types'
2
2
  import type {EditorContext} from '..'
3
3
  import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
4
- import {isKeyedSegment} from './util.is-keyed-segment'
4
+ import {
5
+ getBlockKeyFromSelectionPoint,
6
+ getChildKeyFromSelectionPoint,
7
+ } from '../selection/selection-point'
8
+ import {getSelectionEndPoint, getSelectionStartPoint} from '../utils'
5
9
 
6
10
  /**
7
11
  * @public
@@ -23,25 +27,12 @@ export function sliceBlocks({
23
27
  const middleBlocks: PortableTextBlock[] = []
24
28
  let endBlock: PortableTextBlock | undefined
25
29
 
26
- const startPoint = context.selection.backward
27
- ? context.selection.focus
28
- : context.selection.anchor
29
- const endPoint = context.selection.backward
30
- ? context.selection.anchor
31
- : context.selection.focus
32
-
33
- const startBlockKey = isKeyedSegment(startPoint.path[0])
34
- ? startPoint.path[0]._key
35
- : undefined
36
- const endBlockKey = isKeyedSegment(endPoint.path[0])
37
- ? endPoint.path[0]._key
38
- : undefined
39
- const startChildKey = isKeyedSegment(startPoint.path[2])
40
- ? startPoint.path[2]._key
41
- : undefined
42
- const endChildKey = isKeyedSegment(endPoint.path[2])
43
- ? endPoint.path[2]._key
44
- : undefined
30
+ const startPoint = getSelectionStartPoint(context.selection)
31
+ const endPoint = getSelectionEndPoint(context.selection)
32
+ const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
33
+ const startChildKey = getChildKeyFromSelectionPoint(startPoint)
34
+ const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
35
+ const endChildKey = getChildKeyFromSelectionPoint(endPoint)
45
36
 
46
37
  if (!startBlockKey || !endBlockKey) {
47
38
  return slice
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.slice-blocks.cjs","sources":["../../src/internal-utils/asserters.ts","../../src/internal-utils/parse-blocks.ts","../../src/utils/util.is-keyed-segment.ts","../../src/utils/util.block-offset.ts","../../src/utils/util.get-block-start-point.ts","../../src/utils/util.get-text-block-text.ts","../../src/utils/util.is-span.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.slice-blocks.ts"],"sourcesContent":["import type {TypedObject} from '@sanity/types'\n\nexport function isTypedObject(object: unknown): object is TypedObject {\n return isRecord(object) && typeof object._type === 'string'\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && (typeof value === 'object' || typeof value === 'function')\n}\n","import type {\n PortableTextBlock,\n PortableTextListBlock,\n PortableTextObject,\n PortableTextSpan,\n PortableTextTextBlock,\n TypedObject,\n} from '@sanity/types'\nimport type {EditorSchema} from '../editor/editor-schema'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isTypedObject} from './asserters'\n\nexport function parseBlocks({\n context,\n blocks,\n options,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n blocks: unknown\n options: {\n refreshKeys: boolean\n validateFields: boolean\n }\n}): Array<PortableTextBlock> {\n if (!Array.isArray(blocks)) {\n return []\n }\n\n return blocks.flatMap((block) => {\n const parsedBlock = parseBlock({context, block, options})\n\n return parsedBlock ? [parsedBlock] : []\n })\n}\n\nexport function parseBlock({\n context,\n block,\n options,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n block: unknown\n options: {\n refreshKeys: boolean\n validateFields: boolean\n }\n}): PortableTextBlock | undefined {\n return (\n parseTextBlock({block, context, options}) ??\n parseBlockObject({blockObject: block, context, options})\n )\n}\n\nexport function parseBlockObject({\n blockObject,\n context,\n options,\n}: {\n blockObject: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean; validateFields: boolean}\n}): PortableTextObject | undefined {\n if (!isTypedObject(blockObject)) {\n return undefined\n }\n\n const schemaType = context.schema.blockObjects.find(\n ({name}) => name === blockObject._type,\n )\n\n if (!schemaType) {\n return undefined\n }\n\n return parseObject({\n object: blockObject,\n context: {\n keyGenerator: context.keyGenerator,\n schemaType,\n },\n options,\n })\n}\n\nexport function isListBlock(\n context: Pick<EditorContext, 'schema'>,\n block: unknown,\n): block is PortableTextListBlock {\n return (\n isTextBlock(context, block) &&\n block.level !== undefined &&\n block.listItem !== undefined\n )\n}\n\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: unknown,\n): block is PortableTextTextBlock {\n return (\n parseTextBlock({\n block,\n context: {schema: context.schema, keyGenerator: () => ''},\n options: {refreshKeys: false, validateFields: false},\n }) !== undefined\n )\n}\n\nexport function parseTextBlock({\n block,\n context,\n options,\n}: {\n block: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean; validateFields: boolean}\n}): PortableTextTextBlock | undefined {\n if (!isTypedObject(block)) {\n return undefined\n }\n\n const customFields: Record<string, unknown> = {}\n\n for (const key of Object.keys(block)) {\n if (\n key !== '_type' &&\n key !== '_key' &&\n key !== 'children' &&\n key !== 'markDefs' &&\n key !== 'style' &&\n key !== 'listItem' &&\n key !== 'level'\n ) {\n customFields[key] = block[key]\n }\n }\n\n if (block._type !== context.schema.block.name) {\n return undefined\n }\n\n const _key = options.refreshKeys\n ? context.keyGenerator()\n : typeof block._key === 'string'\n ? block._key\n : context.keyGenerator()\n\n const unparsedMarkDefs: Array<unknown> = Array.isArray(block.markDefs)\n ? block.markDefs\n : []\n const markDefKeyMap = new Map<string, string>()\n const markDefs = unparsedMarkDefs.flatMap((markDef) => {\n if (!isTypedObject(markDef)) {\n return []\n }\n\n const schemaType = context.schema.annotations.find(\n ({name}) => name === markDef._type,\n )\n\n if (!schemaType) {\n return []\n }\n\n if (typeof markDef._key !== 'string') {\n // If the `markDef` doesn't have a `_key` then we don't know what spans\n // it belongs to and therefore we have to discard it.\n return []\n }\n\n const parsedAnnotation = parseObject({\n object: markDef,\n context: {\n schemaType,\n keyGenerator: context.keyGenerator,\n },\n options,\n })\n\n if (!parsedAnnotation) {\n return []\n }\n\n markDefKeyMap.set(markDef._key, parsedAnnotation._key)\n\n return [parsedAnnotation]\n })\n\n const unparsedChildren: Array<unknown> = Array.isArray(block.children)\n ? block.children\n : []\n\n const children = unparsedChildren\n .map(\n (child) =>\n parseSpan({span: child, context, markDefKeyMap, options}) ??\n parseInlineObject({inlineObject: child, context, options}),\n )\n .filter((child) => child !== undefined)\n\n const parsedBlock: PortableTextTextBlock = {\n _type: context.schema.block.name,\n _key,\n children:\n children.length > 0\n ? children\n : [\n {\n _key: context.keyGenerator(),\n _type: context.schema.span.name,\n text: '',\n marks: [],\n },\n ],\n markDefs,\n ...(options.validateFields ? {} : customFields),\n }\n\n if (\n typeof block.style === 'string' &&\n context.schema.styles.find((style) => style.name === block.style)\n ) {\n parsedBlock.style = block.style\n } else {\n const defaultStyle = context.schema.styles.at(0)?.name\n\n if (defaultStyle !== undefined) {\n parsedBlock.style = defaultStyle\n } else {\n console.error('Expected default style')\n }\n }\n\n if (\n typeof block.listItem === 'string' &&\n context.schema.lists.find((list) => list.name === block.listItem)\n ) {\n parsedBlock.listItem = block.listItem\n }\n\n if (typeof block.level === 'number') {\n parsedBlock.level = block.level\n }\n\n return parsedBlock\n}\n\nexport function isSpan(\n context: Pick<EditorContext, 'schema'>,\n child: unknown,\n): child is PortableTextSpan {\n return (\n parseSpan({\n span: child,\n markDefKeyMap: new Map(),\n context: {schema: context.schema, keyGenerator: () => ''},\n options: {refreshKeys: false, validateFields: false},\n }) !== undefined\n )\n}\n\nexport function parseSpan({\n span,\n context,\n markDefKeyMap,\n options,\n}: {\n span: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n markDefKeyMap: Map<string, string>\n options: {refreshKeys: boolean; validateFields: boolean}\n}): PortableTextSpan | undefined {\n if (!isTypedObject(span)) {\n return undefined\n }\n\n const customFields: Record<string, unknown> = {}\n\n for (const key of Object.keys(span)) {\n if (\n key !== '_type' &&\n key !== '_key' &&\n key !== 'text' &&\n key !== 'marks'\n ) {\n customFields[key] = span[key]\n }\n }\n\n // In reality, the span schema name is always 'span', but we only the check here anyway\n if (span._type !== context.schema.span.name || span._type !== 'span') {\n return undefined\n }\n\n const unparsedMarks: Array<unknown> = Array.isArray(span.marks)\n ? span.marks\n : []\n const marks = unparsedMarks.flatMap((mark) => {\n if (typeof mark !== 'string') {\n return []\n }\n\n const markDefKey = markDefKeyMap.get(mark)\n\n if (markDefKey !== undefined) {\n return [markDefKey]\n }\n\n if (\n context.schema.decorators.some((decorator) => decorator.name === mark)\n ) {\n return [mark]\n }\n\n return []\n })\n\n return {\n _type: 'span',\n _key: options.refreshKeys\n ? context.keyGenerator()\n : typeof span._key === 'string'\n ? span._key\n : context.keyGenerator(),\n text: typeof span.text === 'string' ? span.text : '',\n marks,\n ...(options.validateFields ? {} : customFields),\n }\n}\n\nexport function parseInlineObject({\n inlineObject,\n context,\n options,\n}: {\n inlineObject: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean; validateFields: boolean}\n}): PortableTextObject | undefined {\n if (!isTypedObject(inlineObject)) {\n return undefined\n }\n\n const schemaType = context.schema.inlineObjects.find(\n ({name}) => name === inlineObject._type,\n )\n\n if (!schemaType) {\n return undefined\n }\n\n return parseObject({\n object: inlineObject,\n context: {\n keyGenerator: context.keyGenerator,\n schemaType,\n },\n options,\n })\n}\n\nexport function parseAnnotation({\n annotation,\n context,\n options,\n}: {\n annotation: TypedObject\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean; validateFields: boolean}\n}): PortableTextObject | undefined {\n if (!isTypedObject(annotation)) {\n return undefined\n }\n\n const schemaType = context.schema.annotations.find(\n ({name}) => name === annotation._type,\n )\n\n if (!schemaType) {\n return undefined\n }\n\n return parseObject({\n object: annotation,\n context: {\n keyGenerator: context.keyGenerator,\n schemaType,\n },\n options,\n })\n}\n\nfunction parseObject({\n object,\n context,\n options,\n}: {\n object: TypedObject\n context: Pick<EditorContext, 'keyGenerator'> & {\n schemaType: EditorSchema['blockObjects'][0]\n }\n options: {refreshKeys: boolean; validateFields: boolean}\n}): PortableTextObject {\n const {_type, _key, ...customFields} = object\n\n // Validates all props on the object and only takes those that match\n // the name of a field\n const values = options.validateFields\n ? context.schemaType.fields.reduce<Record<string, unknown>>(\n (fieldValues, field) => {\n const fieldValue = object[field.name]\n\n if (fieldValue !== undefined) {\n fieldValues[field.name] = fieldValue\n }\n\n return fieldValues\n },\n {},\n )\n : customFields\n\n return {\n _type: context.schemaType.name,\n _key: options.refreshKeys\n ? context.keyGenerator()\n : typeof object._key === 'string'\n ? object._key\n : context.keyGenerator(),\n ...values,\n }\n}\n","import type {KeyedSegment} from '@sanity/types'\n\n/**\n * @public\n */\nexport function isKeyedSegment(segment: unknown): segment is KeyedSegment {\n return typeof segment === 'object' && segment !== null && '_key' in segment\n}\n","import type {KeyedSegment} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan, isTextBlock} from '../internal-utils/parse-blocks'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function blockOffsetToSpanSelectionPoint({\n context,\n blockOffset,\n direction,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}) {\n let offsetLeft = blockOffset.offset\n let selectionPoint:\n | {path: [KeyedSegment, 'children', KeyedSegment]; offset: number}\n | undefined\n let skippedInlineObject = false\n\n for (const block of context.value) {\n if (block._key !== blockOffset.path[0]._key) {\n continue\n }\n\n if (!isTextBlock(context, block)) {\n continue\n }\n\n for (const child of block.children) {\n if (direction === 'forward') {\n if (!isSpan(context, child)) {\n continue\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n break\n }\n\n offsetLeft -= child.text.length\n\n continue\n }\n\n if (!isSpan(context, child)) {\n skippedInlineObject = true\n continue\n }\n\n if (offsetLeft === 0 && selectionPoint && !skippedInlineObject) {\n if (skippedInlineObject) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: 0,\n }\n }\n break\n }\n\n if (offsetLeft > child.text.length) {\n offsetLeft -= child.text.length\n continue\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n\n offsetLeft -= child.text.length\n\n if (offsetLeft !== 0) {\n break\n }\n }\n }\n }\n\n return selectionPoint\n}\n\n/**\n * @public\n */\nexport function spanSelectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = isKeyedSegment(selectionPoint.path[0])\n ? selectionPoint.path[0]._key\n : undefined\n const spanKey = isKeyedSegment(selectionPoint.path[2])\n ? selectionPoint.path[2]._key\n : undefined\n\n if (!blockKey || !spanKey) {\n return undefined\n }\n\n for (const block of context.value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isTextBlock(context, block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isSpan(context, child)) {\n continue\n }\n\n if (child._key === spanKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n offset += child.text.length\n }\n }\n}\n","import type {KeyedSegment, PortableTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isTextBlock} from '../internal-utils/parse-blocks'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockStartPoint({\n context,\n block,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: {\n node: PortableTextBlock\n path: [KeyedSegment]\n }\n}): EditorSelectionPoint {\n if (isTextBlock(context, block.node)) {\n return {\n path: [...block.path, 'children', {_key: block.node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path: block.path,\n offset: 0,\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\n\n/**\n * @public\n */\nexport function getTextBlockText(block: PortableTextTextBlock) {\n return block.children.map((child) => child.text ?? '').join('')\n}\n","import type {PortableTextChild, PortableTextSpan} from '@sanity/types'\nimport type {EditorContext} from '..'\n\n/**\n * @public\n */\nexport function isSpan(\n context: Pick<EditorContext, 'schema'>,\n child: PortableTextChild,\n): child is PortableTextSpan {\n return child._type === context.schema.span.name\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n>(selection: TEditorSelection): TEditorSelection {\n if (!selection) {\n return selection\n }\n\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n } as TEditorSelection\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n } as TEditorSelection\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\nimport {isSpan, isTextBlock} from '../internal-utils/parse-blocks'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function sliceBlocks({\n context,\n blocks,\n}: {\n context: Pick<EditorContext, 'schema' | 'selection'>\n blocks: Array<PortableTextBlock>\n}): Array<PortableTextBlock> {\n const slice: Array<PortableTextBlock> = []\n\n if (!context.selection) {\n return slice\n }\n\n let startBlock: PortableTextBlock | undefined\n const middleBlocks: PortableTextBlock[] = []\n let endBlock: PortableTextBlock | undefined\n\n const startPoint = context.selection.backward\n ? context.selection.focus\n : context.selection.anchor\n const endPoint = context.selection.backward\n ? context.selection.anchor\n : context.selection.focus\n\n const startBlockKey = isKeyedSegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeyedSegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n const startChildKey = isKeyedSegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endChildKey = isKeyedSegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return slice\n }\n\n for (const block of blocks) {\n if (!isTextBlock(context, block)) {\n if (block._key === startBlockKey && block._key === endBlockKey) {\n startBlock = block\n break\n }\n }\n\n if (block._key === startBlockKey) {\n if (!isTextBlock(context, block)) {\n startBlock = block\n continue\n }\n\n if (startChildKey) {\n for (const child of block.children) {\n if (child._key === startChildKey) {\n if (isSpan(context, child)) {\n const text =\n child._key === endChildKey\n ? child.text.slice(startPoint.offset, endPoint.offset)\n : child.text.slice(startPoint.offset)\n\n startBlock = {\n ...block,\n children: [\n {\n ...child,\n text,\n },\n ],\n }\n } else {\n startBlock = {\n ...block,\n children: [child],\n }\n }\n\n if (startChildKey === endChildKey) {\n break\n }\n continue\n }\n\n if (startBlock && isTextBlock(context, startBlock)) {\n if (\n endChildKey &&\n child._key === endChildKey &&\n isSpan(context, child)\n ) {\n startBlock.children.push({\n ...child,\n text: child.text.slice(0, endPoint.offset),\n })\n } else {\n startBlock.children.push(child)\n }\n\n if (\n block._key === endBlockKey &&\n endChildKey &&\n child._key === endChildKey\n ) {\n break\n }\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n startBlock = block\n\n if (startBlockKey === endBlockKey) {\n break\n }\n }\n\n if (block._key === endBlockKey) {\n if (!isTextBlock(context, block)) {\n endBlock = block\n break\n }\n\n if (endChildKey) {\n endBlock = {\n ...block,\n children: [],\n }\n\n for (const child of block.children) {\n if (endBlock && isTextBlock(context, endBlock)) {\n if (child._key === endChildKey && isSpan(context, child)) {\n endBlock.children.push({\n ...child,\n text: child.text.slice(0, endPoint.offset),\n })\n\n break\n }\n\n endBlock.children.push(child)\n\n if (endChildKey && child._key === endChildKey) {\n break\n }\n }\n }\n\n break\n }\n\n endBlock = block\n\n break\n }\n\n if (startBlock) {\n middleBlocks.push(block)\n }\n }\n\n return [\n ...(startBlock ? [startBlock] : []),\n ...middleBlocks,\n ...(endBlock ? [endBlock] : []),\n ]\n}\n"],"names":["isTypedObject","object","isRecord","_type","value","parseBlocks","context","blocks","options","Array","isArray","flatMap","block","parsedBlock","parseBlock","parseTextBlock","parseBlockObject","blockObject","schemaType","schema","blockObjects","find","name","parseObject","keyGenerator","isListBlock","isTextBlock","level","undefined","listItem","refreshKeys","validateFields","customFields","key","Object","keys","_key","unparsedMarkDefs","markDefs","markDefKeyMap","Map","markDef","annotations","parsedAnnotation","set","children","map","child","parseSpan","span","parseInlineObject","inlineObject","filter","length","text","marks","style","styles","defaultStyle","at","console","error","lists","list","isSpan","mark","markDefKey","get","decorators","some","decorator","inlineObjects","parseAnnotation","annotation","values","fields","reduce","fieldValues","field","fieldValue","isKeyedSegment","segment","blockOffsetToSpanSelectionPoint","blockOffset","direction","offsetLeft","offset","selectionPoint","skippedInlineObject","path","spanSelectionPointToBlockOffset","blockKey","spanKey","getBlockStartPoint","node","getTextBlockText","join","reverseSelection","selection","backward","anchor","focus","sliceBlocks","slice","startBlock","middleBlocks","endBlock","startPoint","endPoint","startBlockKey","endBlockKey","startChildKey","endChildKey","push"],"mappings":"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"}