@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.
- package/lib/_chunks-cjs/{util.slice-blocks.cjs → selection-point.cjs} +26 -18
- package/lib/_chunks-cjs/selection-point.cjs.map +1 -0
- package/lib/_chunks-cjs/selector.get-text-before.cjs +13 -10
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +46 -46
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +21 -17
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
- package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs +10 -10
- package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs.map +1 -1
- package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +5 -5
- package/lib/_chunks-cjs/util.is-equal-selection-points.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 +7 -14
- package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
- package/lib/_chunks-es/{util.slice-blocks.js → selection-point.js} +26 -18
- package/lib/_chunks-es/selection-point.js.map +1 -0
- package/lib/_chunks-es/selector.get-text-before.js +13 -10
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +21 -21
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
- package/lib/_chunks-es/selector.is-selection-expanded.js +14 -10
- package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
- package/lib/_chunks-es/util.child-selection-point-to-block-offset.js +2 -2
- package/lib/_chunks-es/util.child-selection-point-to-block-offset.js.map +1 -1
- package/lib/_chunks-es/util.is-equal-selection-points.js +1 -1
- package/lib/_chunks-es/util.merge-text-blocks.js +1 -1
- package/lib/_chunks-es/util.selection-point-to-block-offset.js +4 -11
- package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +25 -2010
- package/lib/behaviors/index.d.ts +25 -2010
- package/lib/behaviors/index.js.map +1 -1
- package/lib/index.cjs +515 -393
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +361 -34
- package/lib/index.d.ts +361 -34
- package/lib/index.js +471 -349
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +11 -11
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +32 -1986
- package/lib/plugins/index.d.ts +32 -1986
- package/lib/plugins/index.js +1 -1
- package/lib/selectors/index.cjs +11 -7
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +2 -2648
- package/lib/selectors/index.d.ts +2 -2648
- package/lib/selectors/index.js +7 -3
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs +25 -14
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +0 -2647
- package/lib/utils/index.d.ts +0 -2647
- package/lib/utils/index.js +14 -3
- package/lib/utils/index.js.map +1 -1
- package/package.json +14 -14
- package/src/behaviors/behavior.abstract.delete.ts +0 -2
- package/src/behaviors/behavior.abstract.insert.ts +8 -8
- package/src/behaviors/behavior.abstract.ts +0 -113
- package/src/behaviors/behavior.core.block-element.ts +9 -3
- package/src/behaviors/behavior.core.dnd.ts +328 -1
- package/src/behaviors/behavior.perform-event.ts +10 -0
- package/src/behaviors/behavior.types.action.ts +2 -0
- package/src/behaviors/behavior.types.event.ts +5 -0
- package/src/behaviors/behavior.types.guard.ts +2 -0
- package/src/converters/converter.portable-text.ts +2 -7
- package/src/converters/converter.text-html.ts +1 -3
- package/src/converters/converter.text-plain.ts +3 -5
- package/src/editor/Editable.tsx +6 -133
- package/src/editor/editor-machine.ts +15 -10
- package/src/editor/editor-selector.ts +0 -2
- package/src/editor/editor-snapshot.ts +0 -18
- package/src/internal-utils/create-test-snapshot.ts +0 -2
- package/src/internal-utils/event-position.ts +42 -30
- package/src/internal-utils/selection-block-keys.ts +7 -7
- package/src/internal-utils/selection-elements.ts +108 -0
- package/src/internal-utils/selection-focus-text.ts +13 -9
- package/src/internal-utils/selection-text.ts +9 -78
- package/src/internal-utils/terse-pt.test.ts +108 -26
- package/src/internal-utils/terse-pt.ts +132 -14
- package/src/operations/behavior.operation.decorator.add.ts +0 -2
- package/src/operations/behavior.operation.delete.ts +18 -13
- package/src/operations/behavior.operation.insert.block.ts +5 -1
- package/src/selection/selection-point.ts +22 -0
- package/src/selectors/selector.get-anchor-block.ts +6 -6
- package/src/selectors/selector.get-anchor-child.ts +6 -6
- package/src/selectors/selector.get-selected-spans.ts +16 -19
- package/src/selectors/selector.get-selected-text-blocks.ts +11 -19
- package/src/selectors/selector.get-selection-end-block.ts +30 -0
- package/src/selectors/selector.get-selection-start-block.ts +30 -0
- package/src/selectors/selector.get-text-before.ts +15 -16
- package/src/selectors/selector.get-trimmed-selection.ts +15 -21
- package/src/selectors/selector.is-point-after-selection.ts +11 -19
- package/src/selectors/selector.is-point-before-selection.ts +11 -19
- package/src/selectors/selectors.ts +23 -39
- package/src/utils/util.block-offset.ts +6 -7
- package/src/utils/util.child-selection-point-to-block-offset.ts +6 -7
- package/src/utils/util.selection-point-to-block-offset.ts +5 -6
- package/src/utils/util.slice-blocks.ts +11 -20
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +0 -1
- package/lib/_chunks-es/util.slice-blocks.js.map +0 -1
- 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 {
|
|
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
|
-
|
|
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 ===
|
|
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 (
|
|
37
|
+
if (startBlockKey === endBlockKey) {
|
|
46
38
|
break
|
|
47
39
|
}
|
|
48
40
|
continue
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
if (block._key ===
|
|
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
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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:
|
|
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 {
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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 {
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
const endPoint = getSelectionEndPoint(snapshot.context.selection)
|
|
22
|
+
const endBlockKey = getBlockKeyFromSelectionPoint(endPoint)
|
|
23
|
+
const endChildKey = getChildKeyFromSelectionPoint(endPoint)
|
|
21
24
|
|
|
22
|
-
const pointBlockKey =
|
|
23
|
-
|
|
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 >
|
|
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 {
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
const startPoint = getSelectionStartPoint(snapshot.context.selection)
|
|
22
|
+
const startBlockKey = getBlockKeyFromSelectionPoint(startPoint)
|
|
23
|
+
const startChildKey = getChildKeyFromSelectionPoint(startPoint)
|
|
21
24
|
|
|
22
|
-
const pointBlockKey =
|
|
23
|
-
|
|
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 <
|
|
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 {
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
209
|
-
|
|
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
|
|
238
|
-
|
|
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 =
|
|
105
|
-
|
|
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 =
|
|
20
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
) {
|
|
17
|
+
const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)
|
|
18
|
+
|
|
19
|
+
if (selectionPoint.path.length === 1 && blockKey !== undefined) {
|
|
21
20
|
return {
|
|
22
|
-
path: [{_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 {
|
|
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
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
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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"}
|