@portabletext/editor 1.48.7 → 1.48.8
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/behavior.core.cjs +20 -8
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/behavior.markdown.cjs +5 -5
- package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
- package/lib/_chunks-cjs/editor-provider.cjs +121 -90
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs +2 -2
- package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.get-text-before.cjs +7 -4
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs +63 -47
- package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +29 -23
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs +3 -3
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +15 -15
- package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs +258 -38
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +21 -10
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +5 -6
- package/lib/_chunks-es/behavior.markdown.js.map +1 -1
- package/lib/_chunks-es/editor-provider.js +75 -46
- package/lib/_chunks-es/editor-provider.js.map +1 -1
- package/lib/_chunks-es/selector.get-focus-inline-object.js +1 -2
- package/lib/_chunks-es/selector.get-focus-inline-object.js.map +1 -1
- package/lib/_chunks-es/selector.get-text-before.js +7 -4
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/selector.is-overlapping-selection.js +61 -46
- package/lib/_chunks-es/selector.is-overlapping-selection.js.map +1 -1
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +30 -26
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
- package/lib/_chunks-es/util.merge-text-blocks.js +1 -1
- package/lib/_chunks-es/util.selection-point-to-block-offset.js +15 -16
- package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
- package/lib/_chunks-es/util.slice-blocks.js +258 -38
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/behaviors/index.d.cts +2552 -251
- package/lib/behaviors/index.d.ts +2552 -251
- package/lib/index.cjs +45 -21
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2350 -51
- package/lib/index.d.ts +2350 -51
- package/lib/index.js +44 -21
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +16 -7
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +2324 -24
- package/lib/plugins/index.d.ts +2324 -24
- package/lib/plugins/index.js +16 -7
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.cjs +5 -5
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +2321 -28
- package/lib/selectors/index.d.ts +2321 -28
- package/lib/selectors/index.js +5 -6
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs +30 -24
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +2350 -44
- package/lib/utils/index.d.ts +2350 -44
- package/lib/utils/index.js +30 -24
- package/lib/utils/index.js.map +1 -1
- package/package.json +1 -2
- package/src/behavior-actions/behavior.action.block.unset.ts +1 -1
- package/src/behavior-actions/behavior.action.decorator.add.ts +20 -5
- package/src/behaviors/behavior.abstract.decorator.ts +1 -1
- package/src/behaviors/behavior.abstract.delete.ts +1 -1
- package/src/behaviors/behavior.abstract.insert.ts +2 -2
- package/src/behaviors/behavior.abstract.select.ts +16 -4
- package/src/behaviors/behavior.abstract.split.ts +9 -6
- package/src/behaviors/behavior.core.block-objects.ts +5 -5
- package/src/behaviors/behavior.core.insert-break.ts +16 -4
- package/src/behaviors/behavior.core.lists.ts +4 -6
- package/src/behaviors/behavior.decorator-pair.ts +13 -4
- package/src/behaviors/behavior.default.ts +1 -1
- package/src/behaviors/behavior.markdown.ts +5 -5
- package/src/converters/converter.portable-text.ts +1 -1
- package/src/converters/converter.text-html.ts +1 -1
- package/src/converters/converter.text-plain.ts +4 -4
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +10 -2
- package/src/editor/plugins/createWithSchemaTypes.ts +12 -19
- package/src/internal-utils/__tests__/dmpToOperations.test.ts +13 -12
- package/src/internal-utils/drag-selection.ts +16 -4
- package/src/internal-utils/event-position.ts +20 -8
- package/src/internal-utils/parse-blocks.ts +17 -5
- package/src/internal-utils/validateValue.ts +6 -6
- package/src/plugins/plugin.decorator-shortcut.ts +2 -2
- package/src/selectors/selector.get-active-annotations.ts +5 -2
- package/src/selectors/selector.get-active-list-item.ts +4 -3
- package/src/selectors/selector.get-active-style.ts +4 -3
- package/src/selectors/selector.get-anchor-text-block.ts +3 -6
- package/src/selectors/selector.get-block-offsets.ts +2 -2
- package/src/selectors/selector.get-caret-word-selection.ts +11 -5
- package/src/selectors/selector.get-selected-slice.ts +1 -1
- package/src/selectors/selector.get-selected-spans.ts +11 -15
- package/src/selectors/selector.get-selected-text-blocks.ts +3 -3
- package/src/selectors/selector.get-selection-text.ts +3 -3
- package/src/selectors/selector.get-text-before.ts +5 -2
- package/src/selectors/selector.get-trimmed-selection.ts +20 -14
- package/src/selectors/selector.is-active-annotation.ts +4 -2
- package/src/selectors/selector.is-active-decorator.test.ts +3 -3
- package/src/selectors/selector.is-at-the-end-of-block.ts +4 -1
- package/src/selectors/selector.is-at-the-start-of-block.ts +4 -1
- package/src/selectors/selector.is-point-after-selection.ts +7 -6
- package/src/selectors/selector.is-point-before-selection.ts +7 -6
- package/src/selectors/selector.is-selecting-entire-blocks.ts +8 -2
- package/src/selectors/selectors.ts +25 -28
- package/src/utils/util.block-offset-to-block-selection-point.ts +4 -4
- package/src/utils/util.block-offset-to-selection-point.ts +5 -5
- package/src/utils/util.block-offset.test.ts +219 -156
- package/src/utils/util.block-offset.ts +14 -17
- package/src/utils/util.block-offsets-to-selection.ts +5 -5
- package/src/utils/util.child-selection-point-to-block-offset.ts +7 -10
- package/src/utils/util.get-block-end-point.ts +15 -15
- package/src/utils/util.get-block-start-point.ts +13 -12
- package/src/utils/util.is-empty-text-block.ts +9 -8
- package/src/utils/util.selection-point-to-block-offset.ts +4 -4
- package/src/utils/util.slice-blocks.test.ts +178 -121
- package/src/utils/util.slice-blocks.ts +25 -24
- package/src/utils/util.split-text-block.ts +18 -12
- package/lib/_chunks-cjs/parse-blocks.cjs +0 -205
- package/lib/_chunks-cjs/parse-blocks.cjs.map +0 -1
- package/lib/_chunks-es/parse-blocks.js +0 -206
- package/lib/_chunks-es/parse-blocks.js.map +0 -1
- package/src/behavior-actions/behavior.guards.ts +0 -24
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import type {DiffMatchPatch} from '@portabletext/patches'
|
|
2
2
|
import {makeDiff, makePatches, stringifyPatches} from '@sanity/diff-match-patch'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type PortableTextSpan,
|
|
9
|
-
type PortableTextTextBlock,
|
|
3
|
+
import type {
|
|
4
|
+
Path,
|
|
5
|
+
PortableTextBlock,
|
|
6
|
+
PortableTextSpan,
|
|
7
|
+
PortableTextTextBlock,
|
|
10
8
|
} from '@sanity/types'
|
|
11
9
|
import type {Descendant, Operation} from 'slate'
|
|
12
10
|
import {describe, expect, test} from 'vitest'
|
|
13
11
|
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
14
12
|
import {diffMatchPatch} from '../applyPatch'
|
|
13
|
+
import {isTypedObject} from '../asserters'
|
|
15
14
|
|
|
16
15
|
describe('operationToPatches: diffMatchPatch', () => {
|
|
17
16
|
test.todo('skips patches for blocks that cannot be found locally')
|
|
@@ -152,13 +151,11 @@ function getMockEditor(options: MockEditorOptions): Pick<
|
|
|
152
151
|
|
|
153
152
|
function getText(blockKey?: string) {
|
|
154
153
|
return children
|
|
155
|
-
.filter(
|
|
156
|
-
isPortableTextTextBlock(child),
|
|
157
|
-
)
|
|
154
|
+
.filter(isTextBlock)
|
|
158
155
|
.filter((child) => (blockKey ? child._key === blockKey : true))
|
|
159
156
|
.flatMap((block) =>
|
|
160
157
|
block.children
|
|
161
|
-
.filter((span) =>
|
|
158
|
+
.filter((span) => isSpan(span))
|
|
162
159
|
.map((span) => span.text)
|
|
163
160
|
.join(''),
|
|
164
161
|
)
|
|
@@ -166,7 +163,11 @@ function getMockEditor(options: MockEditorOptions): Pick<
|
|
|
166
163
|
}
|
|
167
164
|
|
|
168
165
|
function isTextBlock(value: unknown): value is PortableTextTextBlock {
|
|
169
|
-
return
|
|
166
|
+
return isTypedObject(value) && value._type === 'block'
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function isSpan(value: unknown): value is PortableTextSpan {
|
|
170
|
+
return isTypedObject(value) && value._type === 'span'
|
|
170
171
|
}
|
|
171
172
|
|
|
172
173
|
function apply(operation: Operation): void {
|
|
@@ -55,8 +55,14 @@ export function getDragSelection({
|
|
|
55
55
|
// Looks like we are dragging an empty span
|
|
56
56
|
// Let's drag the entire block instead
|
|
57
57
|
dragSelection = {
|
|
58
|
-
anchor: utils.getBlockStartPoint(
|
|
59
|
-
|
|
58
|
+
anchor: utils.getBlockStartPoint({
|
|
59
|
+
context: snapshot.context,
|
|
60
|
+
block: draggedTextBlock,
|
|
61
|
+
}),
|
|
62
|
+
focus: utils.getBlockEndPoint({
|
|
63
|
+
context: snapshot.context,
|
|
64
|
+
block: draggedTextBlock,
|
|
65
|
+
}),
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
|
|
@@ -74,8 +80,14 @@ export function getDragSelection({
|
|
|
74
80
|
return dragSelection
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
const selectionStartPoint = utils.getBlockStartPoint(
|
|
78
|
-
|
|
83
|
+
const selectionStartPoint = utils.getBlockStartPoint({
|
|
84
|
+
context: snapshot.context,
|
|
85
|
+
block: selectionStartBlock,
|
|
86
|
+
})
|
|
87
|
+
const selectionEndPoint = utils.getBlockEndPoint({
|
|
88
|
+
context: snapshot.context,
|
|
89
|
+
block: selectionEndBlock,
|
|
90
|
+
})
|
|
79
91
|
|
|
80
92
|
const eventSelectionInsideBlocks = selectors.isOverlappingSelection(
|
|
81
93
|
eventSelection,
|
|
@@ -59,12 +59,18 @@ export function getEventPosition({
|
|
|
59
59
|
isEditor: false,
|
|
60
60
|
selection: {
|
|
61
61
|
anchor: utils.getBlockStartPoint({
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
context: editorActor.getSnapshot().context,
|
|
63
|
+
block: {
|
|
64
|
+
node: block,
|
|
65
|
+
path: [{_key: block._key}],
|
|
66
|
+
},
|
|
64
67
|
}),
|
|
65
68
|
focus: utils.getBlockEndPoint({
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
context: editorActor.getSnapshot().context,
|
|
70
|
+
block: {
|
|
71
|
+
node: block,
|
|
72
|
+
path: [{_key: block._key}],
|
|
73
|
+
},
|
|
68
74
|
}),
|
|
69
75
|
},
|
|
70
76
|
}
|
|
@@ -93,12 +99,18 @@ export function getEventPosition({
|
|
|
93
99
|
isEditor: false,
|
|
94
100
|
selection: {
|
|
95
101
|
anchor: utils.getBlockStartPoint({
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
context: editorActor.getSnapshot().context,
|
|
103
|
+
block: {
|
|
104
|
+
node: block,
|
|
105
|
+
path: [{_key: block._key}],
|
|
106
|
+
},
|
|
98
107
|
}),
|
|
99
108
|
focus: utils.getBlockEndPoint({
|
|
100
|
-
|
|
101
|
-
|
|
109
|
+
context: editorActor.getSnapshot().context,
|
|
110
|
+
block: {
|
|
111
|
+
node: block,
|
|
112
|
+
path: [{_key: block._key}],
|
|
113
|
+
},
|
|
102
114
|
}),
|
|
103
115
|
},
|
|
104
116
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
PortableTextBlock,
|
|
3
|
+
PortableTextListBlock,
|
|
3
4
|
PortableTextObject,
|
|
4
5
|
PortableTextSpan,
|
|
5
6
|
PortableTextTextBlock,
|
|
@@ -79,14 +80,25 @@ function parseBlockObject({
|
|
|
79
80
|
})
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
export function isListBlock(
|
|
84
|
+
context: Pick<EditorContext, 'schema'>,
|
|
85
|
+
block: unknown,
|
|
86
|
+
): block is PortableTextListBlock {
|
|
87
|
+
return (
|
|
88
|
+
isTextBlock(context, block) &&
|
|
89
|
+
block.level !== undefined &&
|
|
90
|
+
block.listItem !== undefined
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
82
94
|
export function isTextBlock(
|
|
83
|
-
|
|
95
|
+
context: Pick<EditorContext, 'schema'>,
|
|
84
96
|
block: unknown,
|
|
85
97
|
): block is PortableTextTextBlock {
|
|
86
98
|
return (
|
|
87
99
|
parseTextBlock({
|
|
88
100
|
block,
|
|
89
|
-
context: {schema, keyGenerator: () => ''},
|
|
101
|
+
context: {schema: context.schema, keyGenerator: () => ''},
|
|
90
102
|
options: {refreshKeys: false},
|
|
91
103
|
}) !== undefined
|
|
92
104
|
)
|
|
@@ -215,14 +227,14 @@ function parseTextBlock({
|
|
|
215
227
|
}
|
|
216
228
|
|
|
217
229
|
export function isSpan(
|
|
218
|
-
|
|
219
|
-
child:
|
|
230
|
+
context: Pick<EditorContext, 'schema'>,
|
|
231
|
+
child: unknown,
|
|
220
232
|
): child is PortableTextSpan {
|
|
221
233
|
return (
|
|
222
234
|
parseSpan({
|
|
223
235
|
span: child,
|
|
224
236
|
markDefKeyMap: new Map(),
|
|
225
|
-
context: {schema, keyGenerator: () => ''},
|
|
237
|
+
context: {schema: context.schema, keyGenerator: () => ''},
|
|
226
238
|
options: {refreshKeys: false},
|
|
227
239
|
}) !== undefined
|
|
228
240
|
)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {insert, set, setIfMissing, unset} from '@portabletext/patches'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type PortableTextTextBlock,
|
|
2
|
+
import type {
|
|
3
|
+
PortableTextBlock,
|
|
4
|
+
PortableTextSpan,
|
|
5
|
+
PortableTextTextBlock,
|
|
7
6
|
} from '@sanity/types'
|
|
8
7
|
import {flatten, isPlainObject, uniq} from 'lodash'
|
|
9
8
|
import type {EditorSchema} from '../editor/editor-schema'
|
|
10
9
|
import type {InvalidValueResolution} from '../types/editor'
|
|
10
|
+
import {isTextBlock} from './parse-blocks'
|
|
11
11
|
|
|
12
12
|
export interface Validation {
|
|
13
13
|
valid: boolean
|
|
@@ -118,7 +118,7 @@ export function validateValue(
|
|
|
118
118
|
// If the block has no `_type`, but aside from that is a valid Portable Text block
|
|
119
119
|
if (
|
|
120
120
|
!blk._type &&
|
|
121
|
-
|
|
121
|
+
isTextBlock({schema: types}, {...blk, _type: types.block.name})
|
|
122
122
|
) {
|
|
123
123
|
resolution = {
|
|
124
124
|
patches: [
|
|
@@ -89,11 +89,11 @@ const selectionListenerCallback: CallbackLogicFunction<
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
const anchor = utils.spanSelectionPointToBlockOffset({
|
|
92
|
-
|
|
92
|
+
context: snapshot.context,
|
|
93
93
|
selectionPoint: event.at.anchor,
|
|
94
94
|
})
|
|
95
95
|
const focus = utils.spanSelectionPointToBlockOffset({
|
|
96
|
-
|
|
96
|
+
context: snapshot.context,
|
|
97
97
|
selectionPoint: event.at.focus,
|
|
98
98
|
})
|
|
99
99
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type {PortableTextObject} from '@sanity/types'
|
|
2
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
3
4
|
import {getSelectedSpans} from './selector.get-selected-spans'
|
|
4
5
|
import {isSelectionCollapsed} from './selector.is-selection-collapsed'
|
|
5
6
|
import {getFocusSpan, getSelectedBlocks} from './selectors'
|
|
@@ -34,7 +35,9 @@ export const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const selectionMarkDefs = selectedBlocks.flatMap((block) =>
|
|
37
|
-
|
|
38
|
+
isTextBlock(snapshot.context, block.node)
|
|
39
|
+
? (block.node.markDefs ?? [])
|
|
40
|
+
: [],
|
|
38
41
|
)
|
|
39
42
|
|
|
40
43
|
return selectionMarkDefs.filter((markDef) =>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {PortableTextListBlock} from '@sanity/types'
|
|
2
|
-
import {createGuards} from '../behavior-actions/behavior.guards'
|
|
3
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
4
4
|
import {getSelectedBlocks} from './selectors'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -13,9 +13,10 @@ export const getActiveListItem: EditorSelector<
|
|
|
13
13
|
return undefined
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const guards = createGuards(snapshot.context)
|
|
17
16
|
const selectedBlocks = getSelectedBlocks(snapshot).map((block) => block.node)
|
|
18
|
-
const selectedTextBlocks = selectedBlocks.filter(
|
|
17
|
+
const selectedTextBlocks = selectedBlocks.filter((block) =>
|
|
18
|
+
isTextBlock(snapshot.context, block),
|
|
19
|
+
)
|
|
19
20
|
|
|
20
21
|
const firstTextBlock = selectedTextBlocks.at(0)
|
|
21
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {PortableTextTextBlock} from '@sanity/types'
|
|
2
|
-
import {createGuards} from '../behavior-actions/behavior.guards'
|
|
3
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
4
4
|
import {getSelectedBlocks} from './selectors'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -13,9 +13,10 @@ export const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = (
|
|
|
13
13
|
return undefined
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const guards = createGuards(snapshot.context)
|
|
17
16
|
const selectedBlocks = getSelectedBlocks(snapshot).map((block) => block.node)
|
|
18
|
-
const selectedTextBlocks = selectedBlocks.filter(
|
|
17
|
+
const selectedTextBlocks = selectedBlocks.filter((block) =>
|
|
18
|
+
isTextBlock(snapshot.context, block),
|
|
19
|
+
)
|
|
19
20
|
|
|
20
21
|
const firstTextBlock = selectedTextBlocks.at(0)
|
|
21
22
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isPortableTextTextBlock,
|
|
3
|
-
type KeyedSegment,
|
|
4
|
-
type PortableTextTextBlock,
|
|
5
|
-
} from '@sanity/types'
|
|
1
|
+
import type {KeyedSegment, PortableTextTextBlock} from '@sanity/types'
|
|
6
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
7
4
|
import {getAnchorBlock} from './selector.get-anchor-block'
|
|
8
5
|
|
|
9
6
|
/**
|
|
@@ -14,7 +11,7 @@ export const getAnchorTextBlock: EditorSelector<
|
|
|
14
11
|
> = (snapshot) => {
|
|
15
12
|
const anchorBlock = getAnchorBlock(snapshot)
|
|
16
13
|
|
|
17
|
-
return anchorBlock &&
|
|
14
|
+
return anchorBlock && isTextBlock(snapshot.context, anchorBlock.node)
|
|
18
15
|
? {node: anchorBlock.node, path: anchorBlock.path}
|
|
19
16
|
: undefined
|
|
20
17
|
}
|
|
@@ -22,11 +22,11 @@ export const getBlockOffsets: EditorSelector<
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const start = utils.spanSelectionPointToBlockOffset({
|
|
25
|
-
|
|
25
|
+
context: snapshot.context,
|
|
26
26
|
selectionPoint: selectionStartPoint,
|
|
27
27
|
})
|
|
28
28
|
const end = utils.spanSelectionPointToBlockOffset({
|
|
29
|
-
|
|
29
|
+
context: snapshot.context,
|
|
30
30
|
selectionPoint: selectionEndPoint,
|
|
31
31
|
})
|
|
32
32
|
|
|
@@ -35,7 +35,7 @@ export const getCaretWordSelection: EditorSelector<EditorSelection> = (
|
|
|
35
35
|
const selectionStartPoint = getSelectionStartPoint(snapshot)
|
|
36
36
|
const selectionStartOffset = selectionStartPoint
|
|
37
37
|
? spanSelectionPointToBlockOffset({
|
|
38
|
-
|
|
38
|
+
context: snapshot.context,
|
|
39
39
|
selectionPoint: selectionStartPoint,
|
|
40
40
|
})
|
|
41
41
|
: undefined
|
|
@@ -45,7 +45,10 @@ export const getCaretWordSelection: EditorSelector<EditorSelection> = (
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const previousInlineObject = getPreviousInlineObject(snapshot)
|
|
48
|
-
const blockStartPoint = getBlockStartPoint(
|
|
48
|
+
const blockStartPoint = getBlockStartPoint({
|
|
49
|
+
context: snapshot.context,
|
|
50
|
+
block: focusTextBlock,
|
|
51
|
+
})
|
|
49
52
|
const textBefore = getSelectionText({
|
|
50
53
|
...snapshot,
|
|
51
54
|
context: {
|
|
@@ -61,7 +64,10 @@ export const getCaretWordSelection: EditorSelector<EditorSelection> = (
|
|
|
61
64
|
const textDirectlyBefore = textBefore.split(/\s+/).at(-1)
|
|
62
65
|
|
|
63
66
|
const nextInlineObject = getNextInlineObject(snapshot)
|
|
64
|
-
const blockEndPoint = getBlockEndPoint(
|
|
67
|
+
const blockEndPoint = getBlockEndPoint({
|
|
68
|
+
context: snapshot.context,
|
|
69
|
+
block: focusTextBlock,
|
|
70
|
+
})
|
|
65
71
|
const textAfter = getSelectionText({
|
|
66
72
|
...snapshot,
|
|
67
73
|
context: {
|
|
@@ -97,12 +103,12 @@ export const getCaretWordSelection: EditorSelector<EditorSelection> = (
|
|
|
97
103
|
: selectionStartOffset
|
|
98
104
|
|
|
99
105
|
const caretWordStartSelectionPoint = blockOffsetToSpanSelectionPoint({
|
|
100
|
-
|
|
106
|
+
context: snapshot.context,
|
|
101
107
|
blockOffset: caretWordStartOffset,
|
|
102
108
|
direction: 'backward',
|
|
103
109
|
})
|
|
104
110
|
const caretWordEndSelectionPoint = blockOffsetToSpanSelectionPoint({
|
|
105
|
-
|
|
111
|
+
context: snapshot.context,
|
|
106
112
|
blockOffset: caretWordEndOffset,
|
|
107
113
|
direction: 'forward',
|
|
108
114
|
})
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isKeySegment,
|
|
3
|
-
isPortableTextSpan,
|
|
4
|
-
isPortableTextTextBlock,
|
|
5
|
-
type KeyedSegment,
|
|
6
|
-
type PortableTextSpan,
|
|
7
|
-
} from '@sanity/types'
|
|
1
|
+
import type {KeyedSegment, PortableTextSpan} from '@sanity/types'
|
|
8
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
|
|
4
|
+
import {isKeyedSegment} from '../utils'
|
|
9
5
|
|
|
10
6
|
/**
|
|
11
7
|
* @public
|
|
@@ -32,10 +28,10 @@ export const getSelectedSpans: EditorSelector<
|
|
|
32
28
|
? snapshot.context.selection.anchor
|
|
33
29
|
: snapshot.context.selection.focus
|
|
34
30
|
|
|
35
|
-
const startBlockKey =
|
|
31
|
+
const startBlockKey = isKeyedSegment(startPoint.path[0])
|
|
36
32
|
? startPoint.path[0]._key
|
|
37
33
|
: undefined
|
|
38
|
-
const endBlockKey =
|
|
34
|
+
const endBlockKey = isKeyedSegment(endPoint.path[0])
|
|
39
35
|
? endPoint.path[0]._key
|
|
40
36
|
: undefined
|
|
41
37
|
|
|
@@ -43,10 +39,10 @@ export const getSelectedSpans: EditorSelector<
|
|
|
43
39
|
return selectedSpans
|
|
44
40
|
}
|
|
45
41
|
|
|
46
|
-
const startSpanKey =
|
|
42
|
+
const startSpanKey = isKeyedSegment(startPoint.path[2])
|
|
47
43
|
? startPoint.path[2]._key
|
|
48
44
|
: undefined
|
|
49
|
-
const endSpanKey =
|
|
45
|
+
const endSpanKey = isKeyedSegment(endPoint.path[2])
|
|
50
46
|
? endPoint.path[2]._key
|
|
51
47
|
: undefined
|
|
52
48
|
|
|
@@ -57,13 +53,13 @@ export const getSelectedSpans: EditorSelector<
|
|
|
57
53
|
startBlockFound = true
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
if (!
|
|
56
|
+
if (!isTextBlock(snapshot.context, block)) {
|
|
61
57
|
continue
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
if (block._key === startBlockKey) {
|
|
65
61
|
for (const child of block.children) {
|
|
66
|
-
if (!
|
|
62
|
+
if (!isSpan(snapshot.context, child)) {
|
|
67
63
|
continue
|
|
68
64
|
}
|
|
69
65
|
|
|
@@ -109,7 +105,7 @@ export const getSelectedSpans: EditorSelector<
|
|
|
109
105
|
|
|
110
106
|
if (block._key === endBlockKey) {
|
|
111
107
|
for (const child of block.children) {
|
|
112
|
-
if (!
|
|
108
|
+
if (!isSpan(snapshot.context, child)) {
|
|
113
109
|
continue
|
|
114
110
|
}
|
|
115
111
|
|
|
@@ -134,7 +130,7 @@ export const getSelectedSpans: EditorSelector<
|
|
|
134
130
|
|
|
135
131
|
if (startBlockFound) {
|
|
136
132
|
for (const child of block.children) {
|
|
137
|
-
if (!
|
|
133
|
+
if (!isSpan(snapshot.context, child)) {
|
|
138
134
|
continue
|
|
139
135
|
}
|
|
140
136
|
|
|
@@ -38,7 +38,7 @@ export const getSelectedTextBlocks: EditorSelector<
|
|
|
38
38
|
|
|
39
39
|
for (const block of snapshot.context.value) {
|
|
40
40
|
if (block._key === startKey) {
|
|
41
|
-
if (isTextBlock(snapshot.context
|
|
41
|
+
if (isTextBlock(snapshot.context, block)) {
|
|
42
42
|
selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -49,7 +49,7 @@ export const getSelectedTextBlocks: EditorSelector<
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (block._key === endKey) {
|
|
52
|
-
if (isTextBlock(snapshot.context
|
|
52
|
+
if (isTextBlock(snapshot.context, block)) {
|
|
53
53
|
selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -57,7 +57,7 @@ export const getSelectedTextBlocks: EditorSelector<
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
if (selectedTextBlocks.length > 0) {
|
|
60
|
-
if (isTextBlock(snapshot.context
|
|
60
|
+
if (isTextBlock(snapshot.context, block)) {
|
|
61
61
|
selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'
|
|
2
1
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
2
|
+
import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
|
|
3
3
|
import {getSelectedSlice} from './selector.get-selected-slice'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -9,14 +9,14 @@ export const getSelectionText: EditorSelector<string> = (snapshot) => {
|
|
|
9
9
|
const selectedSlice = getSelectedSlice(snapshot)
|
|
10
10
|
|
|
11
11
|
return selectedSlice.reduce((text, block) => {
|
|
12
|
-
if (!
|
|
12
|
+
if (!isTextBlock(snapshot.context, block)) {
|
|
13
13
|
return text
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
17
|
text +
|
|
18
18
|
block.children.reduce((text, child) => {
|
|
19
|
-
if (
|
|
19
|
+
if (isSpan(snapshot.context, child)) {
|
|
20
20
|
return text + child.text
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -27,8 +27,11 @@ export const getBlockTextBefore: EditorSelector<string> = (snapshot) => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const startOfBlock = getBlockStartPoint({
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
context: snapshot.context,
|
|
31
|
+
block: {
|
|
32
|
+
node: block,
|
|
33
|
+
path: [{_key: block._key}],
|
|
34
|
+
},
|
|
32
35
|
})
|
|
33
36
|
|
|
34
37
|
return getSelectionText({
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isPortableTextSpan,
|
|
3
|
-
isPortableTextTextBlock,
|
|
4
|
-
type PortableTextSpan,
|
|
5
|
-
} from '@sanity/types'
|
|
1
|
+
import type {PortableTextSpan} from '@sanity/types'
|
|
6
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isSpan, isTextBlock} from '../internal-utils/parse-blocks'
|
|
7
4
|
import type {EditorSelection, EditorSelectionPoint} from '../types/editor'
|
|
8
5
|
import {isEmptyTextBlock, isKeyedSegment} from '../utils'
|
|
9
6
|
import {getSelectionEndPoint} from './selector.get-selection-end-point'
|
|
@@ -58,7 +55,10 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
|
|
|
58
55
|
if (block._key === startBlockKey) {
|
|
59
56
|
startBlockFound = true
|
|
60
57
|
|
|
61
|
-
if (
|
|
58
|
+
if (
|
|
59
|
+
isTextBlock(snapshot.context, block) &&
|
|
60
|
+
isEmptyTextBlock(snapshot.context, block)
|
|
61
|
+
) {
|
|
62
62
|
continue
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -67,17 +67,20 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
|
|
|
67
67
|
continue
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if (!
|
|
70
|
+
if (!isTextBlock(snapshot.context, block)) {
|
|
71
71
|
continue
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
if (
|
|
74
|
+
if (
|
|
75
|
+
block._key === endBlockKey &&
|
|
76
|
+
isEmptyTextBlock(snapshot.context, block)
|
|
77
|
+
) {
|
|
75
78
|
break
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
for (const child of block.children) {
|
|
79
82
|
if (child._key === endChildKey) {
|
|
80
|
-
if (!
|
|
83
|
+
if (!isSpan(snapshot.context, child) || endPoint.offset === 0) {
|
|
81
84
|
adjustedEndPoint = previousPotentialEndpoint
|
|
82
85
|
? {
|
|
83
86
|
path: [
|
|
@@ -96,10 +99,10 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
|
|
|
96
99
|
|
|
97
100
|
if (trimStartPoint) {
|
|
98
101
|
const lonelySpan =
|
|
99
|
-
|
|
102
|
+
isSpan(snapshot.context, child) && block.children.length === 1
|
|
100
103
|
|
|
101
104
|
if (
|
|
102
|
-
(
|
|
105
|
+
(isSpan(snapshot.context, child) && child.text.length > 0) ||
|
|
103
106
|
lonelySpan
|
|
104
107
|
) {
|
|
105
108
|
adjustedStartPoint = {
|
|
@@ -114,7 +117,7 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
|
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
if (child._key === startChildKey) {
|
|
117
|
-
if (!
|
|
120
|
+
if (!isSpan(snapshot.context, child)) {
|
|
118
121
|
trimStartPoint = true
|
|
119
122
|
continue
|
|
120
123
|
}
|
|
@@ -130,7 +133,7 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
|
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
previousPotentialEndpoint =
|
|
133
|
-
|
|
136
|
+
isSpan(snapshot.context, child) && child.text.length > 0
|
|
134
137
|
? {blockKey: block._key, span: child}
|
|
135
138
|
: previousPotentialEndpoint
|
|
136
139
|
}
|
|
@@ -168,7 +171,10 @@ export const getTrimmedSelection: EditorSelector<EditorSelection> = (
|
|
|
168
171
|
},
|
|
169
172
|
})
|
|
170
173
|
|
|
171
|
-
if (
|
|
174
|
+
if (
|
|
175
|
+
focusTextBlock &&
|
|
176
|
+
!isEmptyTextBlock(snapshot.context, focusTextBlock.node)
|
|
177
|
+
) {
|
|
172
178
|
return null
|
|
173
179
|
}
|
|
174
180
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {isPortableTextTextBlock} from '@sanity/types'
|
|
2
1
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
2
|
+
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
3
3
|
import {getSelectedSpans} from './selector.get-selected-spans'
|
|
4
4
|
import {isSelectionExpanded} from './selector.is-selection-expanded'
|
|
5
5
|
import {getFocusSpan, getSelectedBlocks} from './selectors'
|
|
@@ -37,7 +37,9 @@ export function isActiveAnnotation(
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const selectionMarkDefs = selectedBlocks.flatMap((block) =>
|
|
40
|
-
|
|
40
|
+
isTextBlock(snapshot.context, block.node)
|
|
41
|
+
? (block.node.markDefs ?? [])
|
|
42
|
+
: [],
|
|
41
43
|
)
|
|
42
44
|
|
|
43
45
|
return selectedSpans.every((span) => {
|
|
@@ -21,7 +21,7 @@ test(isActiveDecorator.name, () => {
|
|
|
21
21
|
snapshot(
|
|
22
22
|
[
|
|
23
23
|
{
|
|
24
|
-
_type: '
|
|
24
|
+
_type: 'block',
|
|
25
25
|
_key: 'b1',
|
|
26
26
|
children: [
|
|
27
27
|
{
|
|
@@ -57,7 +57,7 @@ test(isActiveDecorator.name, () => {
|
|
|
57
57
|
snapshot(
|
|
58
58
|
[
|
|
59
59
|
{
|
|
60
|
-
_type: '
|
|
60
|
+
_type: 'block',
|
|
61
61
|
_key: 'b1',
|
|
62
62
|
children: [
|
|
63
63
|
{
|
|
@@ -94,7 +94,7 @@ test(isActiveDecorator.name, () => {
|
|
|
94
94
|
[
|
|
95
95
|
{_key: 'b0', _type: 'image'},
|
|
96
96
|
{
|
|
97
|
-
_type: '
|
|
97
|
+
_type: 'block',
|
|
98
98
|
_key: 'b1',
|
|
99
99
|
children: [
|
|
100
100
|
{
|