@portabletext/editor 1.53.0 → 1.53.1
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.map +1 -1
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +144 -6
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +6 -140
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +148 -10
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
- package/lib/_chunks-es/selector.is-selection-expanded.js +6 -140
- package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
- package/lib/index.cjs +24 -24
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +2 -2
- package/lib/selectors/index.cjs +10 -10
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +11 -11
- package/lib/selectors/index.d.ts +11 -11
- package/lib/selectors/index.js +4 -4
- package/lib/selectors/index.js.map +1 -1
- package/package.json +13 -13
- package/src/selectors/index.ts +13 -1
- package/src/selectors/selector.get-active-annotations.ts +2 -1
- package/src/selectors/selector.get-active-list-item.ts +1 -1
- package/src/selectors/selector.get-active-style.ts +1 -1
- package/src/selectors/selector.get-caret-word-selection.ts +1 -1
- package/src/selectors/selector.get-first-block.ts +14 -0
- package/src/selectors/selector.get-focus-block-object.ts +18 -0
- package/src/selectors/selector.get-focus-block.ts +23 -0
- package/src/selectors/selector.get-focus-child.ts +39 -0
- package/src/selectors/selector.get-focus-inline-object.ts +1 -1
- package/src/selectors/selector.get-focus-list-block.ts +18 -0
- package/src/selectors/selector.get-focus-span.ts +18 -0
- package/src/selectors/selector.get-focus-text-block.ts +18 -0
- package/src/selectors/selector.get-last-block.ts +16 -0
- package/src/selectors/selector.get-list-state.ts +2 -1
- package/src/selectors/selector.get-next-block.ts +38 -0
- package/src/selectors/selector.get-next-inline-object.ts +1 -1
- package/src/selectors/selector.get-previous-block.ts +35 -0
- package/src/selectors/selector.get-previous-inline-object.ts +1 -1
- package/src/selectors/selector.get-selected-blocks.ts +50 -0
- package/src/selectors/selector.get-selection-end-block.ts +4 -1
- package/src/selectors/selector.get-selection-start-block.ts +4 -1
- package/src/selectors/selector.get-text-before.ts +1 -1
- package/src/selectors/selector.get-trimmed-selection.ts +1 -1
- package/src/selectors/selector.is-active-annotation.ts +1 -1
- package/src/selectors/selector.is-selecting-entire-blocks.ts +2 -1
- package/src/selectors/selectors.ts +0 -299
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
KeyedSegment,
|
|
3
|
+
PortableTextObject,
|
|
4
|
+
PortableTextSpan,
|
|
5
|
+
} from '@sanity/types'
|
|
6
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
7
|
+
import {getChildKeyFromSelectionPoint} from '../selection/selection-point'
|
|
8
|
+
import {getFocusTextBlock} from './selector.get-focus-text-block'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export const getFocusChild: EditorSelector<
|
|
14
|
+
| {
|
|
15
|
+
node: PortableTextObject | PortableTextSpan
|
|
16
|
+
path: [KeyedSegment, 'children', KeyedSegment]
|
|
17
|
+
}
|
|
18
|
+
| undefined
|
|
19
|
+
> = (snapshot) => {
|
|
20
|
+
if (!snapshot.context.selection) {
|
|
21
|
+
return undefined
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const focusBlock = getFocusTextBlock(snapshot)
|
|
25
|
+
|
|
26
|
+
if (!focusBlock) {
|
|
27
|
+
return undefined
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const key = getChildKeyFromSelectionPoint(snapshot.context.selection.focus)
|
|
31
|
+
|
|
32
|
+
const node = key
|
|
33
|
+
? focusBlock.node.children.find((span) => span._key === key)
|
|
34
|
+
: undefined
|
|
35
|
+
|
|
36
|
+
return node && key
|
|
37
|
+
? {node, path: [...focusBlock.path, 'children', {_key: key}]}
|
|
38
|
+
: undefined
|
|
39
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type {PortableTextListBlock} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isListBlock} from '../internal-utils/parse-blocks'
|
|
4
|
+
import type {BlockPath} from '../types/paths'
|
|
5
|
+
import {getFocusTextBlock} from './selector.get-focus-text-block'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export const getFocusListBlock: EditorSelector<
|
|
11
|
+
{node: PortableTextListBlock; path: BlockPath} | undefined
|
|
12
|
+
> = (snapshot) => {
|
|
13
|
+
const focusTextBlock = getFocusTextBlock(snapshot)
|
|
14
|
+
|
|
15
|
+
return focusTextBlock && isListBlock(snapshot.context, focusTextBlock.node)
|
|
16
|
+
? {node: focusTextBlock.node, path: focusTextBlock.path}
|
|
17
|
+
: undefined
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type {KeyedSegment, PortableTextSpan} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isSpan} from '../internal-utils/parse-blocks'
|
|
4
|
+
import {getFocusChild} from './selector.get-focus-child'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export const getFocusSpan: EditorSelector<
|
|
10
|
+
| {node: PortableTextSpan; path: [KeyedSegment, 'children', KeyedSegment]}
|
|
11
|
+
| undefined
|
|
12
|
+
> = (snapshot) => {
|
|
13
|
+
const focusChild = getFocusChild(snapshot)
|
|
14
|
+
|
|
15
|
+
return focusChild && isSpan(snapshot.context, focusChild.node)
|
|
16
|
+
? {node: focusChild.node, path: focusChild.path}
|
|
17
|
+
: undefined
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type {PortableTextTextBlock} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
4
|
+
import type {BlockPath} from '../types/paths'
|
|
5
|
+
import {getFocusBlock} from './selector.get-focus-block'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export const getFocusTextBlock: EditorSelector<
|
|
11
|
+
{node: PortableTextTextBlock; path: BlockPath} | undefined
|
|
12
|
+
> = (snapshot) => {
|
|
13
|
+
const focusBlock = getFocusBlock(snapshot)
|
|
14
|
+
|
|
15
|
+
return focusBlock && isTextBlock(snapshot.context, focusBlock.node)
|
|
16
|
+
? {node: focusBlock.node, path: focusBlock.path}
|
|
17
|
+
: undefined
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type {PortableTextBlock} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import type {BlockPath} from '../types/paths'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export const getLastBlock: EditorSelector<
|
|
9
|
+
{node: PortableTextBlock; path: BlockPath} | undefined
|
|
10
|
+
> = (snapshot) => {
|
|
11
|
+
const node = snapshot.context.value[snapshot.context.value.length - 1]
|
|
12
|
+
? snapshot.context.value[snapshot.context.value.length - 1]
|
|
13
|
+
: undefined
|
|
14
|
+
|
|
15
|
+
return node ? {node, path: [{_key: node._key}]} : undefined
|
|
16
|
+
}
|
|
@@ -2,7 +2,8 @@ import type {PortableTextTextBlock} from '@sanity/types'
|
|
|
2
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
3
|
import {isTextBlock} from '../internal-utils/parse-blocks'
|
|
4
4
|
import type {BlockPath} from '../types/paths'
|
|
5
|
-
import {getFocusTextBlock
|
|
5
|
+
import {getFocusTextBlock} from './selector.get-focus-text-block'
|
|
6
|
+
import {getPreviousBlock} from './selector.get-previous-block'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @beta
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {PortableTextBlock} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import type {BlockPath} from '../types/paths'
|
|
4
|
+
import {getSelectionEndBlock} from './selector.get-selection-end-block'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export const getNextBlock: EditorSelector<
|
|
10
|
+
{node: PortableTextBlock; path: BlockPath} | undefined
|
|
11
|
+
> = (snapshot) => {
|
|
12
|
+
let nextBlock: {node: PortableTextBlock; path: BlockPath} | undefined
|
|
13
|
+
const selectionEndBlock = getSelectionEndBlock(snapshot)
|
|
14
|
+
|
|
15
|
+
if (!selectionEndBlock) {
|
|
16
|
+
return undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let foundSelectionEndBlock = false
|
|
20
|
+
|
|
21
|
+
for (const block of snapshot.context.value) {
|
|
22
|
+
if (block._key === selectionEndBlock.node._key) {
|
|
23
|
+
foundSelectionEndBlock = true
|
|
24
|
+
continue
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (foundSelectionEndBlock) {
|
|
28
|
+
nextBlock = {node: block, path: [{_key: block._key}]}
|
|
29
|
+
break
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (foundSelectionEndBlock && nextBlock) {
|
|
34
|
+
return nextBlock
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return undefined
|
|
38
|
+
}
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
} from '@sanity/types'
|
|
6
6
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
7
7
|
import {isSpan} from '../utils'
|
|
8
|
+
import {getFocusTextBlock} from './selector.get-focus-text-block'
|
|
8
9
|
import {getSelectionEndPoint} from './selector.get-selection-end-point'
|
|
9
|
-
import {getFocusTextBlock} from './selectors'
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @public
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type {KeyedSegment, PortableTextBlock} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import type {BlockPath} from '../types/paths'
|
|
4
|
+
import {getSelectionStartBlock} from './selector.get-selection-start-block'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export const getPreviousBlock: EditorSelector<
|
|
10
|
+
{node: PortableTextBlock; path: BlockPath} | undefined
|
|
11
|
+
> = (snapshot) => {
|
|
12
|
+
let previousBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
13
|
+
const selectionStartBlock = getSelectionStartBlock(snapshot)
|
|
14
|
+
|
|
15
|
+
if (!selectionStartBlock) {
|
|
16
|
+
return undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let foundSelectionStartBlock = false
|
|
20
|
+
|
|
21
|
+
for (const block of snapshot.context.value) {
|
|
22
|
+
if (block._key === selectionStartBlock.node._key) {
|
|
23
|
+
foundSelectionStartBlock = true
|
|
24
|
+
break
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
previousBlock = {node: block, path: [{_key: block._key}]}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (foundSelectionStartBlock && previousBlock) {
|
|
31
|
+
return previousBlock
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return undefined
|
|
35
|
+
}
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
} from '@sanity/types'
|
|
6
6
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
7
7
|
import {isSpan} from '../utils'
|
|
8
|
+
import {getFocusTextBlock} from './selector.get-focus-text-block'
|
|
8
9
|
import {getSelectionStartPoint} from './selector.get-selection-start-point'
|
|
9
|
-
import {getFocusTextBlock} from './selectors'
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @public
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type {KeyedSegment, PortableTextBlock} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {getBlockKeyFromSelectionPoint} from '../selection/selection-point'
|
|
4
|
+
import type {BlockPath} from '../types/paths'
|
|
5
|
+
import {getSelectionEndPoint} from '../utils/util.get-selection-end-point'
|
|
6
|
+
import {getSelectionStartPoint} from '../utils/util.get-selection-start-point'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export const getSelectedBlocks: EditorSelector<
|
|
12
|
+
Array<{node: PortableTextBlock; path: BlockPath}>
|
|
13
|
+
> = (snapshot) => {
|
|
14
|
+
if (!snapshot.context.selection) {
|
|
15
|
+
return []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const selectedBlocks: Array<{node: PortableTextBlock; path: [KeyedSegment]}> =
|
|
19
|
+
[]
|
|
20
|
+
const startPoint = getSelectionStartPoint(snapshot.context.selection)
|
|
21
|
+
const endPoint = getSelectionEndPoint(snapshot.context.selection)
|
|
22
|
+
const startKey = getBlockKeyFromSelectionPoint(startPoint)
|
|
23
|
+
const endKey = getBlockKeyFromSelectionPoint(endPoint)
|
|
24
|
+
|
|
25
|
+
if (!startKey || !endKey) {
|
|
26
|
+
return selectedBlocks
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (const block of snapshot.context.value) {
|
|
30
|
+
if (block._key === startKey) {
|
|
31
|
+
selectedBlocks.push({node: block, path: [{_key: block._key}]})
|
|
32
|
+
|
|
33
|
+
if (startKey === endKey) {
|
|
34
|
+
break
|
|
35
|
+
}
|
|
36
|
+
continue
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (block._key === endKey) {
|
|
40
|
+
selectedBlocks.push({node: block, path: [{_key: block._key}]})
|
|
41
|
+
break
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (selectedBlocks.length > 0) {
|
|
45
|
+
selectedBlocks.push({node: block, path: [{_key: block._key}]})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return selectedBlocks
|
|
50
|
+
}
|
|
@@ -2,8 +2,11 @@ import type {PortableTextBlock} from '@sanity/types'
|
|
|
2
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
3
|
import type {BlockPath} from '../types/paths'
|
|
4
4
|
import {getSelectionEndPoint} from '../utils/util.get-selection-end-point'
|
|
5
|
-
import {getFocusBlock} from './
|
|
5
|
+
import {getFocusBlock} from './selector.get-focus-block'
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
7
10
|
export const getSelectionEndBlock: EditorSelector<
|
|
8
11
|
| {
|
|
9
12
|
node: PortableTextBlock
|
|
@@ -2,8 +2,11 @@ import type {PortableTextBlock} from '@sanity/types'
|
|
|
2
2
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
3
|
import type {BlockPath} from '../types/paths'
|
|
4
4
|
import {getSelectionStartPoint} from '../utils/util.get-selection-start-point'
|
|
5
|
-
import {getFocusBlock} from './
|
|
5
|
+
import {getFocusBlock} from './selector.get-focus-block'
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
7
10
|
export const getSelectionStartBlock: EditorSelector<
|
|
8
11
|
| {
|
|
9
12
|
node: PortableTextBlock
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
2
2
|
import {getSelectionStartPoint} from '../utils'
|
|
3
3
|
import {getBlockStartPoint} from '../utils/util.get-block-start-point'
|
|
4
|
+
import {getFocusBlock} from './selector.get-focus-block'
|
|
4
5
|
import {getSelectionText} from './selector.get-selection-text'
|
|
5
|
-
import {getFocusBlock} from './selectors'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @public
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
getSelectionStartPoint,
|
|
12
12
|
isEmptyTextBlock,
|
|
13
13
|
} from '../utils'
|
|
14
|
+
import {getFocusTextBlock} from './selector.get-focus-text-block'
|
|
14
15
|
import {isSelectionCollapsed} from './selector.is-selection-collapsed'
|
|
15
|
-
import {getFocusTextBlock} from './selectors'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @public
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {EditorSelector} from '../editor/editor-selector'
|
|
2
2
|
import * as utils from '../utils'
|
|
3
|
-
import {getSelectionEndBlock
|
|
3
|
+
import {getSelectionEndBlock} from './selector.get-selection-end-block'
|
|
4
|
+
import {getSelectionStartBlock} from './selector.get-selection-start-block'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @public
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
KeyedSegment,
|
|
3
|
-
PortableTextBlock,
|
|
4
|
-
PortableTextListBlock,
|
|
5
|
-
PortableTextObject,
|
|
6
|
-
PortableTextSpan,
|
|
7
|
-
PortableTextTextBlock,
|
|
8
|
-
} from '@sanity/types'
|
|
9
|
-
import type {EditorSelector} from '../editor/editor-selector'
|
|
10
|
-
import {isListBlock, isSpan, isTextBlock} from '../internal-utils/parse-blocks'
|
|
11
|
-
import {
|
|
12
|
-
getBlockKeyFromSelectionPoint,
|
|
13
|
-
getChildKeyFromSelectionPoint,
|
|
14
|
-
} from '../selection/selection-point'
|
|
15
|
-
import {getSelectionEndPoint, getSelectionStartPoint} from '../utils'
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
export const getFocusBlock: EditorSelector<
|
|
21
|
-
{node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
22
|
-
> = (snapshot) => {
|
|
23
|
-
if (!snapshot.context.selection) {
|
|
24
|
-
return undefined
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const key = getBlockKeyFromSelectionPoint(snapshot.context.selection.focus)
|
|
28
|
-
|
|
29
|
-
const node = key
|
|
30
|
-
? snapshot.context.value.find((block) => block._key === key)
|
|
31
|
-
: undefined
|
|
32
|
-
|
|
33
|
-
return node && key ? {node, path: [{_key: key}]} : undefined
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
export const getFocusListBlock: EditorSelector<
|
|
40
|
-
{node: PortableTextListBlock; path: [KeyedSegment]} | undefined
|
|
41
|
-
> = (snapshot) => {
|
|
42
|
-
const focusTextBlock = getFocusTextBlock(snapshot)
|
|
43
|
-
|
|
44
|
-
return focusTextBlock && isListBlock(snapshot.context, focusTextBlock.node)
|
|
45
|
-
? {node: focusTextBlock.node, path: focusTextBlock.path}
|
|
46
|
-
: undefined
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @public
|
|
51
|
-
*/
|
|
52
|
-
export const getFocusTextBlock: EditorSelector<
|
|
53
|
-
{node: PortableTextTextBlock; path: [KeyedSegment]} | undefined
|
|
54
|
-
> = (snapshot) => {
|
|
55
|
-
const focusBlock = getFocusBlock(snapshot)
|
|
56
|
-
|
|
57
|
-
return focusBlock && isTextBlock(snapshot.context, focusBlock.node)
|
|
58
|
-
? {node: focusBlock.node, path: focusBlock.path}
|
|
59
|
-
: undefined
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @public
|
|
64
|
-
*/
|
|
65
|
-
export const getFocusBlockObject: EditorSelector<
|
|
66
|
-
{node: PortableTextObject; path: [KeyedSegment]} | undefined
|
|
67
|
-
> = (snapshot) => {
|
|
68
|
-
const focusBlock = getFocusBlock(snapshot)
|
|
69
|
-
|
|
70
|
-
return focusBlock && !isTextBlock(snapshot.context, focusBlock.node)
|
|
71
|
-
? {node: focusBlock.node, path: focusBlock.path}
|
|
72
|
-
: undefined
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @public
|
|
77
|
-
*/
|
|
78
|
-
export const getFocusChild: EditorSelector<
|
|
79
|
-
| {
|
|
80
|
-
node: PortableTextObject | PortableTextSpan
|
|
81
|
-
path: [KeyedSegment, 'children', KeyedSegment]
|
|
82
|
-
}
|
|
83
|
-
| undefined
|
|
84
|
-
> = (snapshot) => {
|
|
85
|
-
if (!snapshot.context.selection) {
|
|
86
|
-
return undefined
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const focusBlock = getFocusTextBlock(snapshot)
|
|
90
|
-
|
|
91
|
-
if (!focusBlock) {
|
|
92
|
-
return undefined
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const key = getChildKeyFromSelectionPoint(snapshot.context.selection.focus)
|
|
96
|
-
|
|
97
|
-
const node = key
|
|
98
|
-
? focusBlock.node.children.find((span) => span._key === key)
|
|
99
|
-
: undefined
|
|
100
|
-
|
|
101
|
-
return node && key
|
|
102
|
-
? {node, path: [...focusBlock.path, 'children', {_key: key}]}
|
|
103
|
-
: undefined
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* @public
|
|
108
|
-
*/
|
|
109
|
-
export const getFocusSpan: EditorSelector<
|
|
110
|
-
| {node: PortableTextSpan; path: [KeyedSegment, 'children', KeyedSegment]}
|
|
111
|
-
| undefined
|
|
112
|
-
> = (snapshot) => {
|
|
113
|
-
const focusChild = getFocusChild(snapshot)
|
|
114
|
-
|
|
115
|
-
return focusChild && isSpan(snapshot.context, focusChild.node)
|
|
116
|
-
? {node: focusChild.node, path: focusChild.path}
|
|
117
|
-
: undefined
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @public
|
|
122
|
-
*/
|
|
123
|
-
export const getFirstBlock: EditorSelector<
|
|
124
|
-
{node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
125
|
-
> = (snapshot) => {
|
|
126
|
-
const node = snapshot.context.value[0]
|
|
127
|
-
|
|
128
|
-
return node ? {node, path: [{_key: node._key}]} : undefined
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* @public
|
|
133
|
-
*/
|
|
134
|
-
export const getLastBlock: EditorSelector<
|
|
135
|
-
{node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
136
|
-
> = (snapshot) => {
|
|
137
|
-
const node = snapshot.context.value[snapshot.context.value.length - 1]
|
|
138
|
-
? snapshot.context.value[snapshot.context.value.length - 1]
|
|
139
|
-
: undefined
|
|
140
|
-
|
|
141
|
-
return node ? {node, path: [{_key: node._key}]} : undefined
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* @public
|
|
146
|
-
*/
|
|
147
|
-
export const getSelectedBlocks: EditorSelector<
|
|
148
|
-
Array<{node: PortableTextBlock; path: [KeyedSegment]}>
|
|
149
|
-
> = (snapshot) => {
|
|
150
|
-
if (!snapshot.context.selection) {
|
|
151
|
-
return []
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const selectedBlocks: Array<{node: PortableTextBlock; path: [KeyedSegment]}> =
|
|
155
|
-
[]
|
|
156
|
-
const startPoint = getSelectionStartPoint(snapshot.context.selection)
|
|
157
|
-
const endPoint = getSelectionEndPoint(snapshot.context.selection)
|
|
158
|
-
const startKey = getBlockKeyFromSelectionPoint(startPoint)
|
|
159
|
-
const endKey = getBlockKeyFromSelectionPoint(endPoint)
|
|
160
|
-
|
|
161
|
-
if (!startKey || !endKey) {
|
|
162
|
-
return selectedBlocks
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
for (const block of snapshot.context.value) {
|
|
166
|
-
if (block._key === startKey) {
|
|
167
|
-
selectedBlocks.push({node: block, path: [{_key: block._key}]})
|
|
168
|
-
|
|
169
|
-
if (startKey === endKey) {
|
|
170
|
-
break
|
|
171
|
-
}
|
|
172
|
-
continue
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (block._key === endKey) {
|
|
176
|
-
selectedBlocks.push({node: block, path: [{_key: block._key}]})
|
|
177
|
-
break
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (selectedBlocks.length > 0) {
|
|
181
|
-
selectedBlocks.push({node: block, path: [{_key: block._key}]})
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return selectedBlocks
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* @public
|
|
190
|
-
*/
|
|
191
|
-
export const getSelectionStartBlock: EditorSelector<
|
|
192
|
-
| {
|
|
193
|
-
node: PortableTextBlock
|
|
194
|
-
path: [KeyedSegment]
|
|
195
|
-
}
|
|
196
|
-
| undefined
|
|
197
|
-
> = (snapshot) => {
|
|
198
|
-
if (!snapshot.context.selection) {
|
|
199
|
-
return undefined
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const startPoint = getSelectionStartPoint(snapshot.context.selection)
|
|
203
|
-
const key = getBlockKeyFromSelectionPoint(startPoint)
|
|
204
|
-
|
|
205
|
-
const node = key
|
|
206
|
-
? snapshot.context.value.find((block) => block._key === key)
|
|
207
|
-
: undefined
|
|
208
|
-
|
|
209
|
-
return node && key ? {node, path: [{_key: key}]} : undefined
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* @public
|
|
214
|
-
*/
|
|
215
|
-
export const getSelectionEndBlock: EditorSelector<
|
|
216
|
-
| {
|
|
217
|
-
node: PortableTextBlock
|
|
218
|
-
path: [KeyedSegment]
|
|
219
|
-
}
|
|
220
|
-
| undefined
|
|
221
|
-
> = (snapshot) => {
|
|
222
|
-
if (!snapshot.context.selection) {
|
|
223
|
-
return undefined
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const endPoint = getSelectionEndPoint(snapshot.context.selection)
|
|
227
|
-
const key = getBlockKeyFromSelectionPoint(endPoint)
|
|
228
|
-
|
|
229
|
-
const node = key
|
|
230
|
-
? snapshot.context.value.find((block) => block._key === key)
|
|
231
|
-
: undefined
|
|
232
|
-
|
|
233
|
-
return node && key ? {node, path: [{_key: key}]} : undefined
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* @public
|
|
238
|
-
*/
|
|
239
|
-
export const getPreviousBlock: EditorSelector<
|
|
240
|
-
{node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
241
|
-
> = (snapshot) => {
|
|
242
|
-
let previousBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
243
|
-
const selectionStartBlock = getSelectionStartBlock(snapshot)
|
|
244
|
-
|
|
245
|
-
if (!selectionStartBlock) {
|
|
246
|
-
return undefined
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
let foundSelectionStartBlock = false
|
|
250
|
-
|
|
251
|
-
for (const block of snapshot.context.value) {
|
|
252
|
-
if (block._key === selectionStartBlock.node._key) {
|
|
253
|
-
foundSelectionStartBlock = true
|
|
254
|
-
break
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
previousBlock = {node: block, path: [{_key: block._key}]}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (foundSelectionStartBlock && previousBlock) {
|
|
261
|
-
return previousBlock
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return undefined
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* @public
|
|
269
|
-
*/
|
|
270
|
-
export const getNextBlock: EditorSelector<
|
|
271
|
-
{node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
272
|
-
> = (snapshot) => {
|
|
273
|
-
let nextBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined
|
|
274
|
-
const selectionEndBlock = getSelectionEndBlock(snapshot)
|
|
275
|
-
|
|
276
|
-
if (!selectionEndBlock) {
|
|
277
|
-
return undefined
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
let foundSelectionEndBlock = false
|
|
281
|
-
|
|
282
|
-
for (const block of snapshot.context.value) {
|
|
283
|
-
if (block._key === selectionEndBlock.node._key) {
|
|
284
|
-
foundSelectionEndBlock = true
|
|
285
|
-
continue
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (foundSelectionEndBlock) {
|
|
289
|
-
nextBlock = {node: block, path: [{_key: block._key}]}
|
|
290
|
-
break
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (foundSelectionEndBlock && nextBlock) {
|
|
295
|
-
return nextBlock
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
return undefined
|
|
299
|
-
}
|