@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.
- package/lib/_chunks-cjs/selector.get-text-before.cjs +2 -0
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +93 -104
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +18 -6
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
- package/lib/_chunks-es/selector.get-text-before.js +2 -0
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +93 -104
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
- package/lib/_chunks-es/selector.is-selection-expanded.js +19 -7
- package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
- package/lib/behaviors/index.d.cts +1 -0
- package/lib/behaviors/index.d.ts +1 -0
- package/lib/index.cjs +129 -57
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +3 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +131 -59
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +1 -0
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +1 -0
- package/lib/plugins/index.d.ts +1 -0
- package/lib/plugins/index.js +1 -0
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.cjs +15 -57
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +8 -0
- package/lib/selectors/index.d.ts +8 -0
- package/lib/selectors/index.js +18 -60
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.d.cts +1 -0
- package/lib/utils/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/behaviors/behavior.abstract.delete.ts +2 -8
- package/src/behaviors/behavior.abstract.split.ts +4 -3
- package/src/converters/converter.portable-text.ts +2 -8
- package/src/converters/converter.text-html.ts +2 -8
- package/src/converters/converter.text-plain.ts +2 -8
- package/src/editor/components/render-text-block.tsx +9 -0
- package/src/editor/create-slate-editor.tsx +14 -3
- package/src/editor/editor-selector.ts +1 -0
- package/src/editor/editor-snapshot.ts +2 -0
- package/src/editor/plugins/slate-plugin.update-value.ts +5 -0
- package/src/internal-utils/build-index-maps.test.ts +232 -0
- package/src/internal-utils/build-index-maps.ts +97 -0
- package/src/internal-utils/create-test-snapshot.ts +17 -9
- package/src/internal-utils/mark-state.ts +1 -0
- package/src/operations/behavior.operation.decorator.add.ts +1 -0
- package/src/selectors/index.ts +1 -0
- package/src/selectors/selector.get-anchor-block.ts +3 -4
- package/src/selectors/selector.get-focus-block.ts +3 -3
- package/src/selectors/selector.get-list-state.ts +34 -96
- package/src/selectors/selector.get-next-block.ts +7 -16
- package/src/selectors/selector.get-previous-block.ts +7 -13
- package/src/selectors/selector.get-selected-blocks.ts +13 -1
- package/src/selectors/selector.get-selected-slice.ts +3 -5
- package/src/selectors/selector.get-selected-spans.ts +14 -3
- package/src/selectors/selector.get-selected-text-blocks.ts +13 -1
- package/src/selectors/selector.get-selected-value.ts +47 -0
- package/src/selectors/selector.get-selection-text.ts +3 -3
- package/src/selectors/selector.get-trimmed-selection.ts +13 -1
- package/src/selectors/selector.is-point-after-selection.ts +58 -38
- package/src/selectors/selector.is-point-before-selection.ts +58 -38
- 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
|
-
|
|
11
|
-
|
|
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 ?? [],
|
|
@@ -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: [],
|
package/src/selectors/index.ts
CHANGED
|
@@ -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 =
|
|
19
|
-
? snapshot.context.value.
|
|
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 =
|
|
19
|
-
? snapshot.context.value.
|
|
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
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
66
|
+
if (!isTextBlock(snapshot.context, block)) {
|
|
67
|
+
// Non-text block breaks the sequence
|
|
68
|
+
break
|
|
69
|
+
}
|
|
111
70
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
71
|
+
if (block.listItem === undefined || block.level === undefined) {
|
|
72
|
+
// Non-list item breaks the sequence
|
|
73
|
+
break
|
|
74
|
+
}
|
|
115
75
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return undefined
|
|
121
|
-
}
|
|
76
|
+
if (block.listItem !== targetListItem) {
|
|
77
|
+
// Different list type breaks the sequence
|
|
78
|
+
break
|
|
79
|
+
}
|
|
122
80
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
81
|
+
if (block.level < targetLevel) {
|
|
82
|
+
// Lower level breaks the sequence
|
|
83
|
+
break
|
|
84
|
+
}
|
|
126
85
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
path: previousBlock.path,
|
|
86
|
+
if (block.level === targetLevel) {
|
|
87
|
+
// Same level - continue counting
|
|
88
|
+
listIndex++
|
|
131
89
|
}
|
|
132
|
-
}
|
|
133
90
|
|
|
134
|
-
|
|
135
|
-
return undefined
|
|
91
|
+
// Higher level items don't affect the count for the target level
|
|
136
92
|
}
|
|
137
93
|
|
|
138
|
-
return
|
|
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
|
-
|
|
18
|
+
const index = snapshot.blockIndexMap.get(selectionEndBlock.node._key)
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
34
|
-
return nextBlock
|
|
35
|
-
}
|
|
24
|
+
const nextBlock = snapshot.context.value.at(index + 1)
|
|
36
25
|
|
|
37
|
-
return
|
|
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
|
-
|
|
18
|
+
const index = snapshot.blockIndexMap.get(selectionStartBlock.node._key)
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
31
|
-
return previousBlock
|
|
32
|
-
}
|
|
24
|
+
const previousBlock = snapshot.context.value.at(index - 1)
|
|
33
25
|
|
|
34
|
-
return
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
|
45
|
-
const
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
|
9
|
+
const selectedValue = getSelectedValue(snapshot)
|
|
10
10
|
|
|
11
|
-
return
|
|
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
|
|
60
|
+
for (const block of slicedValue) {
|
|
49
61
|
if (block._key === startBlockKey) {
|
|
50
62
|
startBlockFound = true
|
|
51
63
|
|