@portabletext/editor 1.54.5 → 1.55.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 (66) hide show
  1. package/lib/_chunks-cjs/selector.get-text-before.cjs +2 -0
  2. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +93 -104
  4. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  5. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +18 -6
  6. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
  7. package/lib/_chunks-es/selector.get-text-before.js +2 -0
  8. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  9. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +93 -104
  10. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  11. package/lib/_chunks-es/selector.is-selection-expanded.js +19 -7
  12. package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
  13. package/lib/behaviors/index.d.cts +1 -0
  14. package/lib/behaviors/index.d.ts +1 -0
  15. package/lib/index.cjs +129 -57
  16. package/lib/index.cjs.map +1 -1
  17. package/lib/index.d.cts +3 -0
  18. package/lib/index.d.ts +3 -0
  19. package/lib/index.js +131 -59
  20. package/lib/index.js.map +1 -1
  21. package/lib/plugins/index.cjs +1 -0
  22. package/lib/plugins/index.cjs.map +1 -1
  23. package/lib/plugins/index.d.cts +1 -0
  24. package/lib/plugins/index.d.ts +1 -0
  25. package/lib/plugins/index.js +1 -0
  26. package/lib/plugins/index.js.map +1 -1
  27. package/lib/selectors/index.cjs +15 -57
  28. package/lib/selectors/index.cjs.map +1 -1
  29. package/lib/selectors/index.d.cts +8 -0
  30. package/lib/selectors/index.d.ts +8 -0
  31. package/lib/selectors/index.js +18 -60
  32. package/lib/selectors/index.js.map +1 -1
  33. package/lib/utils/index.d.cts +1 -0
  34. package/lib/utils/index.d.ts +1 -0
  35. package/package.json +1 -1
  36. package/src/behaviors/behavior.abstract.delete.ts +2 -8
  37. package/src/behaviors/behavior.abstract.split.ts +4 -3
  38. package/src/converters/converter.portable-text.ts +2 -8
  39. package/src/converters/converter.text-html.ts +2 -8
  40. package/src/converters/converter.text-plain.ts +2 -8
  41. package/src/editor/components/render-text-block.tsx +9 -0
  42. package/src/editor/create-slate-editor.tsx +14 -3
  43. package/src/editor/editor-selector.ts +1 -0
  44. package/src/editor/editor-snapshot.ts +2 -0
  45. package/src/editor/plugins/slate-plugin.update-value.ts +5 -0
  46. package/src/internal-utils/build-index-maps.test.ts +232 -0
  47. package/src/internal-utils/build-index-maps.ts +97 -0
  48. package/src/internal-utils/create-test-snapshot.ts +17 -9
  49. package/src/internal-utils/mark-state.ts +1 -0
  50. package/src/operations/behavior.operation.decorator.add.ts +1 -0
  51. package/src/selectors/index.ts +1 -0
  52. package/src/selectors/selector.get-anchor-block.ts +3 -4
  53. package/src/selectors/selector.get-focus-block.ts +3 -3
  54. package/src/selectors/selector.get-list-state.ts +34 -96
  55. package/src/selectors/selector.get-next-block.ts +7 -16
  56. package/src/selectors/selector.get-previous-block.ts +7 -13
  57. package/src/selectors/selector.get-selected-blocks.ts +13 -1
  58. package/src/selectors/selector.get-selected-slice.ts +3 -5
  59. package/src/selectors/selector.get-selected-spans.ts +14 -3
  60. package/src/selectors/selector.get-selected-text-blocks.ts +13 -1
  61. package/src/selectors/selector.get-selected-value.ts +47 -0
  62. package/src/selectors/selector.get-selection-text.ts +3 -3
  63. package/src/selectors/selector.get-trimmed-selection.ts +13 -1
  64. package/src/selectors/selector.is-point-after-selection.ts +58 -38
  65. package/src/selectors/selector.is-point-before-selection.ts +58 -38
  66. package/src/types/editor.ts +2 -0
@@ -0,0 +1,97 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {EditorContext} from '../editor/editor-snapshot'
3
+ import {isTextBlock} from './parse-blocks'
4
+
5
+ export function buildIndexMaps(
6
+ context: Pick<EditorContext, 'schema'>,
7
+ value: Array<PortableTextBlock>,
8
+ ): {
9
+ blockIndexMap: Map<string, number>
10
+ listIndexMap: Map<string, number>
11
+ } {
12
+ const blockIndexMap = new Map<string, number>()
13
+ const listIndexMap = new Map<string, number>()
14
+ const levelIndexMap = new Map<number, number>()
15
+ let previousListItem:
16
+ | {
17
+ listItem: string
18
+ level: number
19
+ }
20
+ | undefined
21
+
22
+ for (let blockIndex = 0; blockIndex < value.length; blockIndex++) {
23
+ const block = value.at(blockIndex)
24
+
25
+ if (block === undefined) {
26
+ continue
27
+ }
28
+
29
+ blockIndexMap.set(block._key, blockIndex)
30
+
31
+ if (!isTextBlock(context, block)) {
32
+ levelIndexMap.clear()
33
+ previousListItem = undefined
34
+ continue
35
+ }
36
+
37
+ if (block.listItem === undefined || block.level === undefined) {
38
+ levelIndexMap.clear()
39
+ previousListItem = undefined
40
+ continue
41
+ }
42
+
43
+ if (!previousListItem) {
44
+ previousListItem = {
45
+ listItem: block.listItem,
46
+ level: block.level,
47
+ }
48
+ levelIndexMap.set(block.level, 1)
49
+ listIndexMap.set(block._key, 1)
50
+ continue
51
+ }
52
+
53
+ if (previousListItem.listItem !== block.listItem) {
54
+ levelIndexMap.clear()
55
+ previousListItem = {
56
+ listItem: block.listItem,
57
+ level: block.level,
58
+ }
59
+ levelIndexMap.set(block.level, 1)
60
+ listIndexMap.set(block._key, 1)
61
+ continue
62
+ }
63
+
64
+ if (previousListItem.level === block.level) {
65
+ const levelCounter = levelIndexMap.get(block.level) ?? 0
66
+ levelIndexMap.set(block.level, levelCounter + 1)
67
+ previousListItem = {
68
+ listItem: block.listItem,
69
+ level: block.level,
70
+ }
71
+ listIndexMap.set(block._key, levelCounter + 1)
72
+ continue
73
+ }
74
+
75
+ if (previousListItem.level < block.level) {
76
+ levelIndexMap.set(block.level, 1)
77
+ previousListItem = {
78
+ listItem: block.listItem,
79
+ level: block.level,
80
+ }
81
+ listIndexMap.set(block._key, 1)
82
+ continue
83
+ }
84
+
85
+ if (previousListItem.level > block.level) {
86
+ const levelCounter = levelIndexMap.get(block.level) ?? 0
87
+ levelIndexMap.set(block.level, levelCounter + 1)
88
+ previousListItem = {
89
+ listItem: block.listItem,
90
+ level: block.level,
91
+ }
92
+ listIndexMap.set(block._key, levelCounter + 1)
93
+ }
94
+ }
95
+
96
+ return {blockIndexMap, listIndexMap}
97
+ }
@@ -6,16 +6,24 @@ export function createTestSnapshot(snapshot: {
6
6
  context?: Partial<EditorSnapshot['context']>
7
7
  beta?: Partial<EditorSnapshot['beta']>
8
8
  }): EditorSnapshot {
9
+ const context = {
10
+ converters: snapshot.context?.converters ?? [],
11
+ schema:
12
+ snapshot.context?.schema ?? compileSchemaDefinition(defineSchema({})),
13
+ keyGenerator: snapshot.context?.keyGenerator ?? createTestKeyGenerator(),
14
+ readOnly: snapshot.context?.readOnly ?? false,
15
+ value: snapshot.context?.value ?? [],
16
+ selection: snapshot.context?.selection ?? null,
17
+ }
18
+ const blockIndexMap = new Map<string, number>()
19
+
20
+ snapshot.context?.value?.forEach((block, index) => {
21
+ blockIndexMap.set(block._key, index)
22
+ })
23
+
9
24
  return {
10
- context: {
11
- converters: snapshot.context?.converters ?? [],
12
- schema:
13
- snapshot.context?.schema ?? compileSchemaDefinition(defineSchema({})),
14
- keyGenerator: snapshot.context?.keyGenerator ?? createTestKeyGenerator(),
15
- readOnly: snapshot.context?.readOnly ?? false,
16
- value: snapshot.context?.value ?? [],
17
- selection: snapshot.context?.selection ?? null,
18
- },
25
+ blockIndexMap,
26
+ context,
19
27
  beta: {
20
28
  activeAnnotations: snapshot.beta?.activeAnnotations ?? [],
21
29
  activeDecorators: snapshot.beta?.activeDecorators ?? [],
@@ -46,6 +46,7 @@ export function getMarkState({
46
46
  : null
47
47
 
48
48
  const selectedSpans = getSelectedSpans({
49
+ blockIndexMap: editor.blockIndexMap,
49
50
  context: {
50
51
  value: editor.value,
51
52
  selection,
@@ -108,6 +108,7 @@ export const decoratorAddOperationImplementation: BehaviorOperationImplementatio
108
108
  })
109
109
 
110
110
  const trimmedSelection = selectors.getTrimmedSelection({
111
+ blockIndexMap: editor.blockIndexMap,
111
112
  beta: {
112
113
  activeAnnotations: [],
113
114
  activeDecorators: [],
@@ -31,6 +31,7 @@ export {getSelectionEndPoint} from './selector.get-selection-end-point'
31
31
  export {getSelectionStartBlock} from './selector.get-selection-start-block'
32
32
  export {getSelectionStartPoint} from './selector.get-selection-start-point'
33
33
  export {getSelectionText} from './selector.get-selection-text'
34
+ export {getSelectedValue} from './selector.get-selected-value'
34
35
  export {getBlockTextBefore} from './selector.get-text-before'
35
36
  export {getTrimmedSelection} from './selector.get-trimmed-selection'
36
37
  export {getValue} from './selector.get-value'
@@ -14,10 +14,9 @@ export const getAnchorBlock: EditorSelector<
14
14
  }
15
15
 
16
16
  const key = getBlockKeyFromSelectionPoint(snapshot.context.selection.anchor)
17
-
18
- const node = key
19
- ? snapshot.context.value.find((block) => block._key === key)
20
- : undefined
17
+ const index = key ? snapshot.blockIndexMap.get(key) : undefined
18
+ const node =
19
+ index !== undefined ? snapshot.context.value.at(index) : undefined
21
20
 
22
21
  return node && key ? {node, path: [{_key: key}]} : undefined
23
22
  }
@@ -14,10 +14,10 @@ export const getFocusBlock: EditorSelector<
14
14
  }
15
15
 
16
16
  const key = getBlockKeyFromSelectionPoint(snapshot.context.selection.focus)
17
+ const index = key ? snapshot.blockIndexMap.get(key) : undefined
17
18
 
18
- const node = key
19
- ? snapshot.context.value.find((block) => block._key === key)
20
- : undefined
19
+ const node =
20
+ index !== undefined ? snapshot.context.value.at(index) : undefined
21
21
 
22
22
  return node && key ? {node, path: [{_key: key}]} : undefined
23
23
  }
@@ -1,12 +1,11 @@
1
- import type {PortableTextTextBlock} from '@sanity/types'
2
1
  import type {EditorSelector} from '../editor/editor-selector'
3
2
  import {isTextBlock} from '../internal-utils/parse-blocks'
4
3
  import type {BlockPath} from '../types/paths'
5
4
  import {getFocusTextBlock} from './selector.get-focus-text-block'
6
- import {getPreviousBlock} from './selector.get-previous-block'
7
5
 
8
6
  /**
9
7
  * @beta
8
+ * @deprecated Use the precomputed `data-list-index` on text blocks instead.
10
9
  * Given the `path` of a block, this selector will return the "list index" of
11
10
  * the block.
12
11
  */
@@ -46,113 +45,52 @@ export function getListIndex({
46
45
  return undefined
47
46
  }
48
47
 
49
- const previousListItem = getPreviousListItem({
50
- listItem: focusTextBlock.node.listItem,
51
- level: focusTextBlock.node.level,
52
- })({
53
- ...snapshot,
54
- context: {
55
- ...snapshot.context,
56
- selection,
57
- },
58
- })
48
+ const targetListItem = focusTextBlock.node.listItem
49
+ const targetLevel = focusTextBlock.node.level
50
+ const targetKey = focusTextBlock.node._key
59
51
 
60
- if (!previousListItem) {
61
- return 1
62
- }
63
-
64
- if (previousListItem.node.listItem !== focusTextBlock.node.listItem) {
65
- return 1
66
- }
52
+ // Find the target block's index
53
+ const targetIndex = snapshot.blockIndexMap.get(targetKey)
67
54
 
68
- if (
69
- previousListItem.node.level !== undefined &&
70
- previousListItem.node.level < focusTextBlock.node.level
71
- ) {
72
- return 1
73
- }
74
-
75
- const previousListItemListState = getListIndex({
76
- path: previousListItem.path,
77
- })(snapshot)
78
-
79
- if (previousListItemListState === undefined) {
80
- return 1
55
+ if (targetIndex === undefined) {
56
+ return undefined
81
57
  }
82
58
 
83
- return previousListItemListState + 1
84
- }
85
- }
59
+ // Walk backwards from the target block and count consecutive list items
60
+ // of the same type and level
61
+ let listIndex = 1 // Start at 1 for the target block itself
86
62
 
87
- function getPreviousListItem({
88
- listItem,
89
- level,
90
- }: {
91
- listItem: string
92
- level: number
93
- }): EditorSelector<
94
- | {
95
- node: PortableTextTextBlock
96
- path: [{_key: string}]
97
- }
98
- | undefined
99
- > {
100
- return (snapshot) => {
101
- const previousBlock = getPreviousBlock({
102
- ...snapshot,
103
- context: {
104
- ...snapshot.context,
105
- },
106
- })
63
+ for (let i = targetIndex - 1; i >= 0; i--) {
64
+ const block = snapshot.context.value[i]
107
65
 
108
- if (!previousBlock) {
109
- return undefined
110
- }
66
+ if (!isTextBlock(snapshot.context, block)) {
67
+ // Non-text block breaks the sequence
68
+ break
69
+ }
111
70
 
112
- if (!isTextBlock(snapshot.context, previousBlock.node)) {
113
- return undefined
114
- }
71
+ if (block.listItem === undefined || block.level === undefined) {
72
+ // Non-list item breaks the sequence
73
+ break
74
+ }
115
75
 
116
- if (
117
- previousBlock.node.listItem === undefined ||
118
- previousBlock.node.level === undefined
119
- ) {
120
- return undefined
121
- }
76
+ if (block.listItem !== targetListItem) {
77
+ // Different list type breaks the sequence
78
+ break
79
+ }
122
80
 
123
- if (previousBlock.node.listItem !== listItem) {
124
- return undefined
125
- }
81
+ if (block.level < targetLevel) {
82
+ // Lower level breaks the sequence
83
+ break
84
+ }
126
85
 
127
- if (previousBlock.node.level === level) {
128
- return {
129
- node: previousBlock.node,
130
- path: previousBlock.path,
86
+ if (block.level === targetLevel) {
87
+ // Same level - continue counting
88
+ listIndex++
131
89
  }
132
- }
133
90
 
134
- if (previousBlock.node.level < level) {
135
- return undefined
91
+ // Higher level items don't affect the count for the target level
136
92
  }
137
93
 
138
- return getPreviousListItem({
139
- listItem,
140
- level,
141
- })({
142
- ...snapshot,
143
- context: {
144
- ...snapshot.context,
145
- selection: {
146
- anchor: {
147
- path: previousBlock.path,
148
- offset: 0,
149
- },
150
- focus: {
151
- path: previousBlock.path,
152
- offset: 0,
153
- },
154
- },
155
- },
156
- })
94
+ return listIndex
157
95
  }
158
96
  }
@@ -9,30 +9,21 @@ import {getSelectionEndBlock} from './selector.get-selection-end-block'
9
9
  export const getNextBlock: EditorSelector<
10
10
  {node: PortableTextBlock; path: BlockPath} | undefined
11
11
  > = (snapshot) => {
12
- let nextBlock: {node: PortableTextBlock; path: BlockPath} | undefined
13
12
  const selectionEndBlock = getSelectionEndBlock(snapshot)
14
13
 
15
14
  if (!selectionEndBlock) {
16
15
  return undefined
17
16
  }
18
17
 
19
- let foundSelectionEndBlock = false
18
+ const index = snapshot.blockIndexMap.get(selectionEndBlock.node._key)
20
19
 
21
- for (const block of snapshot.context.value) {
22
- if (block._key === selectionEndBlock.node._key) {
23
- foundSelectionEndBlock = true
24
- continue
25
- }
26
-
27
- if (foundSelectionEndBlock) {
28
- nextBlock = {node: block, path: [{_key: block._key}]}
29
- break
30
- }
20
+ if (index === undefined || index === snapshot.context.value.length - 1) {
21
+ return undefined
31
22
  }
32
23
 
33
- if (foundSelectionEndBlock && nextBlock) {
34
- return nextBlock
35
- }
24
+ const nextBlock = snapshot.context.value.at(index + 1)
36
25
 
37
- return undefined
26
+ return nextBlock
27
+ ? {node: nextBlock, path: [{_key: nextBlock._key}]}
28
+ : undefined
38
29
  }
@@ -9,27 +9,21 @@ import {getSelectionStartBlock} from './selector.get-selection-start-block'
9
9
  export const getPreviousBlock: EditorSelector<
10
10
  {node: PortableTextBlock; path: BlockPath} | undefined
11
11
  > = (snapshot) => {
12
- let previousBlock: {node: PortableTextBlock; path: BlockPath} | undefined
13
12
  const selectionStartBlock = getSelectionStartBlock(snapshot)
14
13
 
15
14
  if (!selectionStartBlock) {
16
15
  return undefined
17
16
  }
18
17
 
19
- let foundSelectionStartBlock = false
18
+ const index = snapshot.blockIndexMap.get(selectionStartBlock.node._key)
20
19
 
21
- for (const block of snapshot.context.value) {
22
- if (block._key === selectionStartBlock.node._key) {
23
- foundSelectionStartBlock = true
24
- break
25
- }
26
-
27
- previousBlock = {node: block, path: [{_key: block._key}]}
20
+ if (index === undefined || index === 0) {
21
+ return undefined
28
22
  }
29
23
 
30
- if (foundSelectionStartBlock && previousBlock) {
31
- return previousBlock
32
- }
24
+ const previousBlock = snapshot.context.value.at(index - 1)
33
25
 
34
- return undefined
26
+ return previousBlock
27
+ ? {node: previousBlock, path: [{_key: previousBlock._key}]}
28
+ : undefined
35
29
  }
@@ -25,7 +25,19 @@ export const getSelectedBlocks: EditorSelector<
25
25
  return selectedBlocks
26
26
  }
27
27
 
28
- for (const block of snapshot.context.value) {
28
+ const startBlockIndex = snapshot.blockIndexMap.get(startKey)
29
+ const endBlockIndex = snapshot.blockIndexMap.get(endKey)
30
+
31
+ if (startBlockIndex === undefined || endBlockIndex === undefined) {
32
+ return selectedBlocks
33
+ }
34
+
35
+ const slicedValue = snapshot.context.value.slice(
36
+ startBlockIndex,
37
+ endBlockIndex + 1,
38
+ )
39
+
40
+ for (const block of slicedValue) {
29
41
  if (block._key === startKey) {
30
42
  selectedBlocks.push({node: block, path: [{_key: block._key}]})
31
43
 
@@ -1,15 +1,13 @@
1
1
  import type {PortableTextBlock} from '@sanity/types'
2
2
  import type {EditorSelector} from '../editor/editor-selector'
3
- import {sliceBlocks} from '../utils'
3
+ import {getSelectedValue} from './selector.get-selected-value'
4
4
 
5
5
  /**
6
6
  * @public
7
+ * @deprecated Renamed to `getSelectedValue`.
7
8
  */
8
9
  export const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = (
9
10
  snapshot,
10
11
  ) => {
11
- return sliceBlocks({
12
- context: snapshot.context,
13
- blocks: snapshot.context.value,
14
- })
12
+ return getSelectedValue(snapshot)
15
13
  }
@@ -36,17 +36,28 @@ export const getSelectedSpans: EditorSelector<
36
36
 
37
37
  const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
38
38
  const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
39
+ const startSpanKey = getChildKeyFromSelectionPoint(startPoint)
40
+ const endSpanKey = getChildKeyFromSelectionPoint(endPoint)
39
41
 
40
42
  if (!startBlockKey || !endBlockKey) {
41
43
  return selectedSpans
42
44
  }
43
45
 
44
- const startSpanKey = getChildKeyFromSelectionPoint(startPoint)
45
- const endSpanKey = getChildKeyFromSelectionPoint(endPoint)
46
+ const startBlockIndex = snapshot.blockIndexMap.get(startBlockKey)
47
+ const endBlockIndex = snapshot.blockIndexMap.get(endBlockKey)
48
+
49
+ if (startBlockIndex === undefined || endBlockIndex === undefined) {
50
+ return selectedSpans
51
+ }
52
+
53
+ const slicedValue = snapshot.context.value.slice(
54
+ startBlockIndex,
55
+ endBlockIndex + 1,
56
+ )
46
57
 
47
58
  let startBlockFound = false
48
59
 
49
- for (const block of snapshot.context.value) {
60
+ for (const block of slicedValue) {
50
61
  if (block._key === startBlockKey) {
51
62
  startBlockFound = true
52
63
  }
@@ -29,7 +29,19 @@ export const getSelectedTextBlocks: EditorSelector<
29
29
  return selectedTextBlocks
30
30
  }
31
31
 
32
- for (const block of snapshot.context.value) {
32
+ const startBlockIndex = snapshot.blockIndexMap.get(startBlockKey)
33
+ const endBlockIndex = snapshot.blockIndexMap.get(endBlockKey)
34
+
35
+ if (startBlockIndex === undefined || endBlockIndex === undefined) {
36
+ return selectedTextBlocks
37
+ }
38
+
39
+ const slicedValue = snapshot.context.value.slice(
40
+ startBlockIndex,
41
+ endBlockIndex + 1,
42
+ )
43
+
44
+ for (const block of slicedValue) {
33
45
  if (block._key === startBlockKey) {
34
46
  if (isTextBlock(snapshot.context, block)) {
35
47
  selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
@@ -0,0 +1,47 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import {getBlockKeyFromSelectionPoint} from '../selection/selection-point'
4
+ import {
5
+ getSelectionEndPoint,
6
+ getSelectionStartPoint,
7
+ sliceBlocks,
8
+ } from '../utils'
9
+
10
+ /**
11
+ * @public
12
+ */
13
+ export const getSelectedValue: EditorSelector<Array<PortableTextBlock>> = (
14
+ snapshot,
15
+ ) => {
16
+ const selection = snapshot.context.selection
17
+
18
+ if (!selection) {
19
+ return []
20
+ }
21
+
22
+ const startPoint = getSelectionStartPoint(selection)
23
+ const endPoint = getSelectionEndPoint(selection)
24
+ const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
25
+ const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
26
+
27
+ if (!startBlockKey || !endBlockKey) {
28
+ return []
29
+ }
30
+
31
+ const startBlockIndex = snapshot.blockIndexMap.get(startBlockKey)
32
+ const endBlockIndex = snapshot.blockIndexMap.get(endBlockKey)
33
+
34
+ if (startBlockIndex === undefined || endBlockIndex === undefined) {
35
+ return []
36
+ }
37
+
38
+ const slicedValue = snapshot.context.value.slice(
39
+ startBlockIndex,
40
+ endBlockIndex + 1,
41
+ )
42
+
43
+ return sliceBlocks({
44
+ context: snapshot.context,
45
+ blocks: slicedValue,
46
+ })
47
+ }
@@ -1,14 +1,14 @@
1
1
  import type {EditorSelector} from '../editor/editor-selector'
2
2
  import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
3
- import {getSelectedSlice} from './selector.get-selected-slice'
3
+ import {getSelectedValue} from './selector.get-selected-value'
4
4
 
5
5
  /**
6
6
  * @public
7
7
  */
8
8
  export const getSelectionText: EditorSelector<string> = (snapshot) => {
9
- const selectedSlice = getSelectedSlice(snapshot)
9
+ const selectedValue = getSelectedValue(snapshot)
10
10
 
11
- return selectedSlice.reduce((text, block) => {
11
+ return selectedValue.reduce((text, block) => {
12
12
  if (!isTextBlock(snapshot.context, block)) {
13
13
  return text
14
14
  }
@@ -36,6 +36,18 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
36
36
  return snapshot.context.selection
37
37
  }
38
38
 
39
+ const startBlockIndex = snapshot.blockIndexMap.get(startBlockKey)
40
+ const endBlockIndex = snapshot.blockIndexMap.get(endBlockKey)
41
+
42
+ if (startBlockIndex === undefined || endBlockIndex === undefined) {
43
+ return snapshot.context.selection
44
+ }
45
+
46
+ const slicedValue = snapshot.context.value.slice(
47
+ startBlockIndex,
48
+ endBlockIndex + 1,
49
+ )
50
+
39
51
  let startBlockFound = false
40
52
  let adjustedStartPoint: EditorSelectionPoint | undefined
41
53
  let trimStartPoint = false
@@ -45,7 +57,7 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
45
57
  | {blockKey: string; span: PortableTextSpan}
46
58
  | undefined
47
59
 
48
- for (const block of snapshot.context.value) {
60
+ for (const block of slicedValue) {
49
61
  if (block._key === startBlockKey) {
50
62
  startBlockFound = true
51
63