@portabletext/editor 1.32.0 → 1.33.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/behavior.core.cjs +4 -4
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/behavior.markdown.cjs +19 -11
- package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
- package/lib/_chunks-cjs/plugin.event-listener.cjs +127 -88
- package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.get-trimmed-selection.cjs +97 -0
- package/lib/_chunks-cjs/selector.get-trimmed-selection.cjs.map +1 -0
- package/lib/_chunks-cjs/{parse-blocks.cjs → util.block-offsets-to-selection.cjs} +21 -2
- package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +1 -0
- package/lib/_chunks-cjs/util.reverse-selection.cjs +11 -0
- package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +1 -1
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +18 -11
- package/lib/_chunks-es/behavior.markdown.js.map +1 -1
- package/lib/_chunks-es/plugin.event-listener.js +127 -87
- package/lib/_chunks-es/plugin.event-listener.js.map +1 -1
- package/lib/_chunks-es/selector.get-trimmed-selection.js +100 -0
- package/lib/_chunks-es/selector.get-trimmed-selection.js.map +1 -0
- package/lib/_chunks-es/{parse-blocks.js → util.block-offsets-to-selection.js} +21 -1
- package/lib/_chunks-es/util.block-offsets-to-selection.js.map +1 -0
- package/lib/_chunks-es/util.reverse-selection.js +11 -0
- package/lib/_chunks-es/util.reverse-selection.js.map +1 -1
- package/lib/behaviors/index.d.cts +1 -0
- package/lib/behaviors/index.d.ts +1 -0
- package/lib/index.d.cts +60 -0
- package/lib/index.d.ts +60 -0
- package/lib/plugins/index.cjs +295 -3
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +74 -1
- package/lib/plugins/index.d.ts +74 -1
- package/lib/plugins/index.js +300 -4
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.cjs +51 -1
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +67 -0
- package/lib/selectors/index.d.ts +67 -0
- package/lib/selectors/index.js +53 -2
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs +5 -4
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +16 -0
- package/lib/utils/index.d.ts +16 -0
- package/lib/utils/index.js +4 -3
- package/package.json +2 -2
- package/src/behavior-actions/behavior.action.decorator.add.ts +161 -0
- package/src/behavior-actions/behavior.action.delete.text.ts +54 -0
- package/src/behavior-actions/behavior.actions.ts +5 -43
- package/src/behaviors/behavior.markdown-emphasis.ts +395 -0
- package/src/behaviors/behavior.markdown.ts +11 -4
- package/src/behaviors/behavior.types.ts +1 -0
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +2 -97
- package/src/plugins/plugin.markdown.tsx +11 -1
- package/src/selectors/index.ts +5 -0
- package/src/selectors/selector.get-anchor-block.ts +22 -0
- package/src/selectors/selector.get-anchor-child.ts +36 -0
- package/src/selectors/selector.get-anchor-span.ts +18 -0
- package/src/selectors/selector.get-anchor-text-block.ts +20 -0
- package/src/selectors/selector.get-trimmed-selection.test.ts +658 -0
- package/src/selectors/selector.get-trimmed-selection.ts +175 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/util.block-offsets-to-selection.ts +36 -0
- package/lib/_chunks-cjs/parse-blocks.cjs.map +0 -1
- package/lib/_chunks-cjs/util.is-empty-text-block.cjs +0 -14
- package/lib/_chunks-cjs/util.is-empty-text-block.cjs.map +0 -1
- package/lib/_chunks-es/parse-blocks.js.map +0 -1
- package/lib/_chunks-es/util.is-empty-text-block.js +0 -15
- package/lib/_chunks-es/util.is-empty-text-block.js.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {KeyedSegment as KeyedSegment_2} from '@portabletext/patches'
|
|
1
2
|
import type {
|
|
2
3
|
ArraySchemaType,
|
|
3
4
|
BlockDecoratorDefinition,
|
|
@@ -25,6 +26,22 @@ declare type BlockOffset = {
|
|
|
25
26
|
offset: number
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
declare function blockOffsetsToSelection({
|
|
33
|
+
value,
|
|
34
|
+
offsets,
|
|
35
|
+
backward,
|
|
36
|
+
}: {
|
|
37
|
+
value: Array<PortableTextBlock>
|
|
38
|
+
offsets: {
|
|
39
|
+
anchor: BlockOffset
|
|
40
|
+
focus: BlockOffset
|
|
41
|
+
}
|
|
42
|
+
backward?: boolean
|
|
43
|
+
}): EditorSelection
|
|
44
|
+
|
|
28
45
|
/**
|
|
29
46
|
* @public
|
|
30
47
|
*/
|
|
@@ -155,6 +172,50 @@ export declare const getActiveStyle: EditorSelector<
|
|
|
155
172
|
PortableTextTextBlock['style']
|
|
156
173
|
>
|
|
157
174
|
|
|
175
|
+
/**
|
|
176
|
+
* @public
|
|
177
|
+
*/
|
|
178
|
+
export declare const getAnchorBlock: EditorSelector<
|
|
179
|
+
| {
|
|
180
|
+
node: PortableTextBlock
|
|
181
|
+
path: [KeyedSegment]
|
|
182
|
+
}
|
|
183
|
+
| undefined
|
|
184
|
+
>
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @public
|
|
188
|
+
*/
|
|
189
|
+
export declare const getAnchorChild: EditorSelector<
|
|
190
|
+
| {
|
|
191
|
+
node: PortableTextObject | PortableTextSpan
|
|
192
|
+
path: [KeyedSegment_2, 'children', KeyedSegment_2]
|
|
193
|
+
}
|
|
194
|
+
| undefined
|
|
195
|
+
>
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @public
|
|
199
|
+
*/
|
|
200
|
+
export declare const getAnchorSpan: EditorSelector<
|
|
201
|
+
| {
|
|
202
|
+
node: PortableTextSpan
|
|
203
|
+
path: [KeyedSegment_2, 'children', KeyedSegment_2]
|
|
204
|
+
}
|
|
205
|
+
| undefined
|
|
206
|
+
>
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @public
|
|
210
|
+
*/
|
|
211
|
+
export declare const getAnchorTextBlock: EditorSelector<
|
|
212
|
+
| {
|
|
213
|
+
node: PortableTextTextBlock
|
|
214
|
+
path: [KeyedSegment]
|
|
215
|
+
}
|
|
216
|
+
| undefined
|
|
217
|
+
>
|
|
218
|
+
|
|
158
219
|
/**
|
|
159
220
|
* @public
|
|
160
221
|
*/
|
|
@@ -409,6 +470,11 @@ export declare const getSelectionText: EditorSelector<string>
|
|
|
409
470
|
*/
|
|
410
471
|
declare function getTextBlockText(block: PortableTextTextBlock): string
|
|
411
472
|
|
|
473
|
+
/**
|
|
474
|
+
* @public
|
|
475
|
+
*/
|
|
476
|
+
export declare const getTrimmedSelection: EditorSelector<EditorSelection>
|
|
477
|
+
|
|
412
478
|
/**
|
|
413
479
|
* @public
|
|
414
480
|
*/
|
|
@@ -626,6 +692,7 @@ declare namespace utils {
|
|
|
626
692
|
EditorSelectionPoint,
|
|
627
693
|
blockOffsetToSpanSelectionPoint,
|
|
628
694
|
spanSelectionPointToBlockOffset,
|
|
695
|
+
blockOffsetsToSelection,
|
|
629
696
|
getBlockEndPoint,
|
|
630
697
|
getBlockStartPoint,
|
|
631
698
|
getTextBlockText,
|
package/lib/selectors/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {KeyedSegment as KeyedSegment_2} from '@portabletext/patches'
|
|
1
2
|
import type {
|
|
2
3
|
ArraySchemaType,
|
|
3
4
|
BlockDecoratorDefinition,
|
|
@@ -25,6 +26,22 @@ declare type BlockOffset = {
|
|
|
25
26
|
offset: number
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
declare function blockOffsetsToSelection({
|
|
33
|
+
value,
|
|
34
|
+
offsets,
|
|
35
|
+
backward,
|
|
36
|
+
}: {
|
|
37
|
+
value: Array<PortableTextBlock>
|
|
38
|
+
offsets: {
|
|
39
|
+
anchor: BlockOffset
|
|
40
|
+
focus: BlockOffset
|
|
41
|
+
}
|
|
42
|
+
backward?: boolean
|
|
43
|
+
}): EditorSelection
|
|
44
|
+
|
|
28
45
|
/**
|
|
29
46
|
* @public
|
|
30
47
|
*/
|
|
@@ -155,6 +172,50 @@ export declare const getActiveStyle: EditorSelector<
|
|
|
155
172
|
PortableTextTextBlock['style']
|
|
156
173
|
>
|
|
157
174
|
|
|
175
|
+
/**
|
|
176
|
+
* @public
|
|
177
|
+
*/
|
|
178
|
+
export declare const getAnchorBlock: EditorSelector<
|
|
179
|
+
| {
|
|
180
|
+
node: PortableTextBlock
|
|
181
|
+
path: [KeyedSegment]
|
|
182
|
+
}
|
|
183
|
+
| undefined
|
|
184
|
+
>
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @public
|
|
188
|
+
*/
|
|
189
|
+
export declare const getAnchorChild: EditorSelector<
|
|
190
|
+
| {
|
|
191
|
+
node: PortableTextObject | PortableTextSpan
|
|
192
|
+
path: [KeyedSegment_2, 'children', KeyedSegment_2]
|
|
193
|
+
}
|
|
194
|
+
| undefined
|
|
195
|
+
>
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @public
|
|
199
|
+
*/
|
|
200
|
+
export declare const getAnchorSpan: EditorSelector<
|
|
201
|
+
| {
|
|
202
|
+
node: PortableTextSpan
|
|
203
|
+
path: [KeyedSegment_2, 'children', KeyedSegment_2]
|
|
204
|
+
}
|
|
205
|
+
| undefined
|
|
206
|
+
>
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @public
|
|
210
|
+
*/
|
|
211
|
+
export declare const getAnchorTextBlock: EditorSelector<
|
|
212
|
+
| {
|
|
213
|
+
node: PortableTextTextBlock
|
|
214
|
+
path: [KeyedSegment]
|
|
215
|
+
}
|
|
216
|
+
| undefined
|
|
217
|
+
>
|
|
218
|
+
|
|
158
219
|
/**
|
|
159
220
|
* @public
|
|
160
221
|
*/
|
|
@@ -409,6 +470,11 @@ export declare const getSelectionText: EditorSelector<string>
|
|
|
409
470
|
*/
|
|
410
471
|
declare function getTextBlockText(block: PortableTextTextBlock): string
|
|
411
472
|
|
|
473
|
+
/**
|
|
474
|
+
* @public
|
|
475
|
+
*/
|
|
476
|
+
export declare const getTrimmedSelection: EditorSelector<EditorSelection>
|
|
477
|
+
|
|
412
478
|
/**
|
|
413
479
|
* @public
|
|
414
480
|
*/
|
|
@@ -626,6 +692,7 @@ declare namespace utils {
|
|
|
626
692
|
EditorSelectionPoint,
|
|
627
693
|
blockOffsetToSpanSelectionPoint,
|
|
628
694
|
spanSelectionPointToBlockOffset,
|
|
695
|
+
blockOffsetsToSelection,
|
|
629
696
|
getBlockEndPoint,
|
|
630
697
|
getBlockStartPoint,
|
|
631
698
|
getTextBlockText,
|
package/lib/selectors/index.js
CHANGED
|
@@ -1,14 +1,60 @@
|
|
|
1
|
-
import { isPortableTextTextBlock, isKeySegment } from "@sanity/types";
|
|
1
|
+
import { isPortableTextTextBlock, isPortableTextSpan, isKeySegment } from "@sanity/types";
|
|
2
2
|
import { getSelectedBlocks, getSelectedSpans, getSelectionStartPoint, getSelectionEndPoint } from "../_chunks-es/selector.is-at-the-start-of-block.js";
|
|
3
3
|
import { getActiveListItem, getActiveStyle, getCaretWordSelection, getFirstBlock, getFocusBlock, getFocusBlockObject, getFocusChild, getFocusListBlock, getFocusSpan, getFocusTextBlock, getLastBlock, getNextBlock, getNextInlineObject, getPreviousBlock, getPreviousInlineObject, getSelectionEndBlock, getSelectionStartBlock, getSelectionText, isActiveAnnotation, isActiveDecorator, isActiveListItem, isActiveStyle, isAtTheEndOfBlock, isAtTheStartOfBlock, isSelectionCollapsed, isSelectionExpanded } from "../_chunks-es/selector.is-at-the-start-of-block.js";
|
|
4
|
-
import { spanSelectionPointToBlockOffset, reverseSelection } from "../_chunks-es/util.reverse-selection.js";
|
|
4
|
+
import { isKeyedSegment, spanSelectionPointToBlockOffset, reverseSelection } from "../_chunks-es/util.reverse-selection.js";
|
|
5
5
|
import { sliceBlocks } from "../_chunks-es/util.slice-blocks.js";
|
|
6
6
|
import { getBlockTextBefore } from "../_chunks-es/selector.get-text-before.js";
|
|
7
|
+
import { getTrimmedSelection } from "../_chunks-es/selector.get-trimmed-selection.js";
|
|
7
8
|
const getActiveAnnotations = (snapshot) => {
|
|
8
9
|
if (!snapshot.context.selection)
|
|
9
10
|
return [];
|
|
10
11
|
const selectedBlocks = getSelectedBlocks(snapshot), selectedSpans = getSelectedSpans(snapshot);
|
|
11
12
|
return selectedSpans.length === 0 ? [] : selectedBlocks.flatMap((block) => isPortableTextTextBlock(block.node) ? block.node.markDefs ?? [] : []).filter((markDef) => selectedSpans.some((span) => span.node.marks?.includes(markDef._key)));
|
|
13
|
+
}, getAnchorBlock = ({
|
|
14
|
+
context
|
|
15
|
+
}) => {
|
|
16
|
+
const key = context.selection && isKeyedSegment(context.selection.anchor.path[0]) ? context.selection.anchor.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
17
|
+
return node && key ? {
|
|
18
|
+
node,
|
|
19
|
+
path: [{
|
|
20
|
+
_key: key
|
|
21
|
+
}]
|
|
22
|
+
} : void 0;
|
|
23
|
+
}, getAnchorTextBlock = ({
|
|
24
|
+
context
|
|
25
|
+
}) => {
|
|
26
|
+
const anchorBlock = getAnchorBlock({
|
|
27
|
+
context
|
|
28
|
+
});
|
|
29
|
+
return anchorBlock && isPortableTextTextBlock(anchorBlock.node) ? {
|
|
30
|
+
node: anchorBlock.node,
|
|
31
|
+
path: anchorBlock.path
|
|
32
|
+
} : void 0;
|
|
33
|
+
}, getAnchorChild = ({
|
|
34
|
+
context
|
|
35
|
+
}) => {
|
|
36
|
+
const anchorBlock = getAnchorTextBlock({
|
|
37
|
+
context
|
|
38
|
+
});
|
|
39
|
+
if (!anchorBlock)
|
|
40
|
+
return;
|
|
41
|
+
const key = context.selection && isKeyedSegment(context.selection.anchor.path[2]) ? context.selection.anchor.path[2]._key : void 0, node = key ? anchorBlock.node.children.find((span) => span._key === key) : void 0;
|
|
42
|
+
return node && key ? {
|
|
43
|
+
node,
|
|
44
|
+
path: [...anchorBlock.path, "children", {
|
|
45
|
+
_key: key
|
|
46
|
+
}]
|
|
47
|
+
} : void 0;
|
|
48
|
+
}, getAnchorSpan = ({
|
|
49
|
+
context
|
|
50
|
+
}) => {
|
|
51
|
+
const anchorChild = getAnchorChild({
|
|
52
|
+
context
|
|
53
|
+
});
|
|
54
|
+
return anchorChild && isPortableTextSpan(anchorChild.node) ? {
|
|
55
|
+
node: anchorChild.node,
|
|
56
|
+
path: anchorChild.path
|
|
57
|
+
} : void 0;
|
|
12
58
|
}, getBlockOffsets = ({
|
|
13
59
|
context
|
|
14
60
|
}) => {
|
|
@@ -140,6 +186,10 @@ export {
|
|
|
140
186
|
getActiveAnnotations,
|
|
141
187
|
getActiveListItem,
|
|
142
188
|
getActiveStyle,
|
|
189
|
+
getAnchorBlock,
|
|
190
|
+
getAnchorChild,
|
|
191
|
+
getAnchorSpan,
|
|
192
|
+
getAnchorTextBlock,
|
|
143
193
|
getBlockOffsets,
|
|
144
194
|
getBlockTextBefore,
|
|
145
195
|
getCaretWordSelection,
|
|
@@ -164,6 +214,7 @@ export {
|
|
|
164
214
|
getSelectionStartBlock,
|
|
165
215
|
getSelectionStartPoint,
|
|
166
216
|
getSelectionText,
|
|
217
|
+
getTrimmedSelection,
|
|
167
218
|
getValue,
|
|
168
219
|
isActiveAnnotation,
|
|
169
220
|
isActiveDecorator,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-active-annotations.ts","../../src/selectors/selector.get-block-offsets.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selection.ts","../../src/selectors/selector.get-value.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts","../../src/selectors/selector.is-overlapping-selection.ts"],"sourcesContent":["import {isPortableTextTextBlock, type PortableTextObject} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return []\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectionMarkDefs.filter((markDef) =>\n selectedSpans.some((span) => span.node.marks?.includes(markDef._key)),\n )\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport * as utils from '../utils'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\n\n/**\n * @public\n */\nexport const getBlockOffsets: EditorSelector<\n {start: utils.BlockOffset; end: utils.BlockOffset} | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const selectionStartPoint = getSelectionStartPoint({context})\n const selectionEndPoint = getSelectionEndPoint({context})\n\n if (!selectionStartPoint || !selectionEndPoint) {\n return undefined\n }\n\n const start = utils.spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: selectionStartPoint,\n })\n const end = utils.spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: selectionEndPoint,\n })\n\n return start && end ? {start, end} : undefined\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import type {EditorSelection, EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getSelection: EditorSelector<EditorSelection> = ({context}) => {\n return context.selection\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getValue: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return context.value\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n","import type {EditorSelection} from '../types/editor'\nimport type {EditorSelector} from './../editor/editor-selector'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\nimport {isPointAfterSelection} from './selector.is-point-after-selection'\nimport {isPointBeforeSelection} from './selector.is-point-before-selection'\n\n/**\n * @public\n */\nexport function isOverlappingSelection(\n selection: EditorSelection,\n): EditorSelector<boolean> {\n return ({context}) => {\n if (!selection || !context.selection) {\n return false\n }\n\n const selectionStartPoint = getSelectionStartPoint({\n context: {\n ...context,\n selection,\n },\n })\n const selectionEndPoint = getSelectionEndPoint({\n context: {\n ...context,\n selection,\n },\n })\n\n if (!selectionStartPoint || !selectionEndPoint) {\n return false\n }\n\n if (!isPointAfterSelection(selectionStartPoint)({context})) {\n return false\n }\n\n if (!isPointBeforeSelection(selectionEndPoint)({context})) {\n return false\n }\n\n return true\n }\n}\n"],"names":["getActiveAnnotations","snapshot","context","selection","selectedBlocks","getSelectedBlocks","selectedSpans","getSelectedSpans","length","flatMap","block","isPortableTextTextBlock","node","markDefs","filter","markDef","some","span","marks","includes","_key","getBlockOffsets","selectionStartPoint","getSelectionStartPoint","selectionEndPoint","getSelectionEndPoint","start","utils","value","selectionPoint","end","undefined","getSelectedSlice","sliceBlocks","blocks","getSelection","getValue","isPointAfterSelection","point","reverseSelection","pointBlockKey","isKeySegment","path","pointChildKey","endBlockKey","focus","endChildKey","after","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before","isOverlappingSelection"],"mappings":";;;;;;AAQO,MAAMA,uBACXC,CACG,aAAA;AACC,MAAA,CAACA,SAASC,QAAQC;AACpB,WAAO,CAAE;AAGX,QAAMC,iBAAiBC,kBAAkBJ,QAAQ,GAC3CK,gBAAgBC,iBAAiBN,QAAQ;AAE/C,SAAIK,cAAcE,WAAW,IACpB,KAGiBJ,eAAeK,QAASC,CAChDC,UAAAA,wBAAwBD,MAAME,IAAI,IAAKF,MAAME,KAAKC,YAAY,CAAM,IAAA,CACtE,CAAA,EAEyBC,OAAQC,CAAAA,YAC/BT,cAAcU,KAAMC,CAAAA,SAASA,KAAKL,KAAKM,OAAOC,SAASJ,QAAQK,IAAI,CAAC,CACtE;AACF,GCrBaC,kBAETA,CAAC;AAAA,EAACnB;AAAO,MAAM;AACjB,MAAI,CAACA,QAAQC;AACX;AAGF,QAAMmB,sBAAsBC,uBAAuB;AAAA,IAACrB;AAAAA,EAAAA,CAAQ,GACtDsB,oBAAoBC,qBAAqB;AAAA,IAACvB;AAAAA,EAAAA,CAAQ;AAEpD,MAAA,CAACoB,uBAAuB,CAACE;AAC3B;AAGIE,QAAAA,QAAQC,gCAAsC;AAAA,IAClDC,OAAO1B,QAAQ0B;AAAAA,IACfC,gBAAgBP;AAAAA,EAAAA,CACjB,GACKQ,MAAMH,gCAAsC;AAAA,IAChDC,OAAO1B,QAAQ0B;AAAAA,IACfC,gBAAgBL;AAAAA,EAAAA,CACjB;AAED,SAAOE,SAASI,MAAM;AAAA,IAACJ;AAAAA,IAAOI;AAAAA,EAAAA,IAAOC;AACvC,GCzBaC,mBAA6DA,CAAC;AAAA,EACzE9B;AACF,MACS+B,YAAY;AAAA,EAACC,QAAQhC,QAAQ0B;AAAAA,EAAOzB,WAAWD,QAAQC;AAAS,CAAC,GCL7DgC,eAAgDA,CAAC;AAAA,EAACjC;AAAO,MAC7DA,QAAQC,WCAJiC,WAAqDA,CAAC;AAAA,EACjElC;AACF,MACSA,QAAQ0B;ACDV,SAASS,sBACdC,OACyB;AACzB,SAAQrC,CAAa,aAAA;AACf,QAAA,CAACA,SAASC,QAAQC;AACb,aAAA;AAGT,UAAMA,YAAYoC,iBAAiBtC,SAASC,QAAQC,SAAS,GAEvDqC,gBAAgBC,aAAaH,MAAMI,KAAK,CAAC,CAAC,IAC5CJ,MAAMI,KAAK,CAAC,EAAEtB,OACdW,QACEY,gBAAgBF,aAAaH,MAAMI,KAAK,CAAC,CAAC,IAC5CJ,MAAMI,KAAK,CAAC,EAAEtB,OACdW,QAEEa,cAAcH,aAAatC,UAAU0C,MAAMH,KAAK,CAAC,CAAC,IACpDvC,UAAU0C,MAAMH,KAAK,CAAC,EAAEtB,OACxBW,QACEe,cAAcL,aAAatC,UAAU0C,MAAMH,KAAK,CAAC,CAAC,IACpDvC,UAAU0C,MAAMH,KAAK,CAAC,EAAEtB,OACxBW;AAEA,QAAA,CAACS,iBAAiB,CAACI;AACd,aAAA;AAGT,QAAIG,QAAQ;AAEDrC,eAAAA,SAAST,SAASC,QAAQ0B,OAAO;AACtClB,UAAAA,MAAMU,SAASwB,aAAa;AAC1BlC,YAAAA,MAAMU,SAASoB,eAAe;AACxB,kBAAA;AACR;AAAA,QAAA;AASF,YAJI,CAAC7B,wBAAwBD,KAAK,KAI9B,CAACiC,iBAAiB,CAACG;AACrB;AAGSE,mBAAAA,SAAStC,MAAMuC,UAAU;AAC9BD,cAAAA,MAAM5B,SAAS0B,aAAa;AAC1BE,gBAAAA,MAAM5B,SAASuB,eAAe;AACxB,sBAAA;AACR;AAAA,YAAA;AAKML,oBAAAA,MAAMY,SAAS/C,UAAU0C,MAAMK;AACvC;AAAA,UAAA;AAGF,cAAIF,MAAM5B,SAASuB;AACjB;AAAA,QAAA;AAAA,MAEJ;AAGF,UAAIjC,MAAMU,SAASoB;AACjB;AAAA,IAAA;AAIGO,WAAAA;AAAAA,EACT;AACF;ACzEO,SAASI,uBACdb,OACyB;AACzB,SAAQrC,CAAa,aAAA;AACf,QAAA,CAACA,SAASC,QAAQC;AACb,aAAA;AAGT,UAAMA,YAAYoC,iBAAiBtC,SAASC,QAAQC,SAAS,GAEvDqC,gBAAgBC,aAAaH,MAAMI,KAAK,CAAC,CAAC,IAC5CJ,MAAMI,KAAK,CAAC,EAAEtB,OACdW,QACEY,gBAAgBF,aAAaH,MAAMI,KAAK,CAAC,CAAC,IAC5CJ,MAAMI,KAAK,CAAC,EAAEtB,OACdW,QAEEqB,gBAAgBX,aAAatC,UAAUkD,OAAOX,KAAK,CAAC,CAAC,IACvDvC,UAAUkD,OAAOX,KAAK,CAAC,EAAEtB,OACzBW,QACEuB,gBAAgBb,aAAatC,UAAUkD,OAAOX,KAAK,CAAC,CAAC,IACvDvC,UAAUkD,OAAOX,KAAK,CAAC,EAAEtB,OACzBW;AAEA,QAAA,CAACS,iBAAiB,CAACY;AACd,aAAA;AAGT,QAAIG,SAAS;AAEF7C,eAAAA,SAAST,SAASC,QAAQ0B,OAAO;AACtClB,UAAAA,MAAMU,SAASoB,eAAe;AAC5B9B,YAAAA,MAAMU,SAASgC,eAAe;AACvB,mBAAA;AACT;AAAA,QAAA;AASF,YAJI,CAACzC,wBAAwBD,KAAK,KAI9B,CAACiC,iBAAiB,CAACW;AACrB;AAGSN,mBAAAA,SAAStC,MAAMuC,UAAU;AAC9BD,cAAAA,MAAM5B,SAASuB,eAAe;AAC5BK,gBAAAA,MAAM5B,SAASkC,eAAe;AACvB,uBAAA;AACT;AAAA,YAAA;AAKOhB,qBAAAA,MAAMY,SAAS/C,UAAUkD,OAAOH;AACzC;AAAA,UAAA;AAGF,cAAIF,MAAM5B,SAASkC;AACjB;AAAA,QAAA;AAAA,MAEJ;AAGF,UAAI5C,MAAMU,SAASgC;AACjB;AAAA,IAAA;AAIGG,WAAAA;AAAAA,EACT;AACF;ACvEO,SAASC,uBACdrD,WACyB;AACzB,SAAO,CAAC;AAAA,IAACD;AAAAA,EAAAA,MAAa;AAChB,QAAA,CAACC,aAAa,CAACD,QAAQC;AAClB,aAAA;AAGT,UAAMmB,sBAAsBC,uBAAuB;AAAA,MACjDrB,SAAS;AAAA,QACP,GAAGA;AAAAA,QACHC;AAAAA,MAAAA;AAAAA,IACF,CACD,GACKqB,oBAAoBC,qBAAqB;AAAA,MAC7CvB,SAAS;AAAA,QACP,GAAGA;AAAAA,QACHC;AAAAA,MAAAA;AAAAA,IACF,CACD;AAUD,WARI,GAACmB,uBAAuB,CAACE,qBAIzB,CAACa,sBAAsBf,mBAAmB,EAAE;AAAA,MAACpB;AAAAA,IAAAA,CAAQ,KAIrD,CAACiD,uBAAuB3B,iBAAiB,EAAE;AAAA,MAACtB;AAAAA,IAAAA,CAAQ;AAAA,EAK1D;AACF;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-active-annotations.ts","../../src/selectors/selector.get-anchor-block.ts","../../src/selectors/selector.get-anchor-text-block.ts","../../src/selectors/selector.get-anchor-child.ts","../../src/selectors/selector.get-anchor-span.ts","../../src/selectors/selector.get-block-offsets.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selection.ts","../../src/selectors/selector.get-value.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts","../../src/selectors/selector.is-overlapping-selection.ts"],"sourcesContent":["import {isPortableTextTextBlock, type PortableTextObject} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return []\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectionMarkDefs.filter((markDef) =>\n selectedSpans.some((span) => span.node.marks?.includes(markDef._key)),\n )\n}\n","import type {KeyedSegment, PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {isKeyedSegment} from '../utils'\n\n/**\n * @public\n */\nexport const getAnchorBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const key = context.selection\n ? isKeyedSegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n","import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextTextBlock,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getAnchorBlock} from './selector.get-anchor-block'\n\n/**\n * @public\n */\nexport const getAnchorTextBlock: EditorSelector<\n {node: PortableTextTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const anchorBlock = getAnchorBlock({context})\n\n return anchorBlock && isPortableTextTextBlock(anchorBlock.node)\n ? {node: anchorBlock.node, path: anchorBlock.path}\n : undefined\n}\n","import type {KeyedSegment} from '@portabletext/patches'\nimport type {PortableTextObject, PortableTextSpan} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {isKeyedSegment} from '../utils'\nimport {getAnchorTextBlock} from './selector.get-anchor-text-block'\n\n/**\n * @public\n */\nexport const getAnchorChild: EditorSelector<\n | {\n node: PortableTextObject | PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n const anchorBlock = getAnchorTextBlock({context})\n\n if (!anchorBlock) {\n return undefined\n }\n\n const key = context.selection\n ? isKeyedSegment(context.selection.anchor.path[2])\n ? context.selection.anchor.path[2]._key\n : undefined\n : undefined\n\n const node = key\n ? anchorBlock.node.children.find((span) => span._key === key)\n : undefined\n\n return node && key\n ? {node, path: [...anchorBlock.path, 'children', {_key: key}]}\n : undefined\n}\n","import type {KeyedSegment} from '@portabletext/patches'\nimport {isPortableTextSpan, type PortableTextSpan} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getAnchorChild} from './selector.get-anchor-child'\n\n/**\n * @public\n */\nexport const getAnchorSpan: EditorSelector<\n | {node: PortableTextSpan; path: [KeyedSegment, 'children', KeyedSegment]}\n | undefined\n> = ({context}) => {\n const anchorChild = getAnchorChild({context})\n\n return anchorChild && isPortableTextSpan(anchorChild.node)\n ? {node: anchorChild.node, path: anchorChild.path}\n : undefined\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport * as utils from '../utils'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\n\n/**\n * @public\n */\nexport const getBlockOffsets: EditorSelector<\n {start: utils.BlockOffset; end: utils.BlockOffset} | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const selectionStartPoint = getSelectionStartPoint({context})\n const selectionEndPoint = getSelectionEndPoint({context})\n\n if (!selectionStartPoint || !selectionEndPoint) {\n return undefined\n }\n\n const start = utils.spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: selectionStartPoint,\n })\n const end = utils.spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: selectionEndPoint,\n })\n\n return start && end ? {start, end} : undefined\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import type {EditorSelection, EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getSelection: EditorSelector<EditorSelection> = ({context}) => {\n return context.selection\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getValue: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return context.value\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n","import type {EditorSelection} from '../types/editor'\nimport type {EditorSelector} from './../editor/editor-selector'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\nimport {isPointAfterSelection} from './selector.is-point-after-selection'\nimport {isPointBeforeSelection} from './selector.is-point-before-selection'\n\n/**\n * @public\n */\nexport function isOverlappingSelection(\n selection: EditorSelection,\n): EditorSelector<boolean> {\n return ({context}) => {\n if (!selection || !context.selection) {\n return false\n }\n\n const selectionStartPoint = getSelectionStartPoint({\n context: {\n ...context,\n selection,\n },\n })\n const selectionEndPoint = getSelectionEndPoint({\n context: {\n ...context,\n selection,\n },\n })\n\n if (!selectionStartPoint || !selectionEndPoint) {\n return false\n }\n\n if (!isPointAfterSelection(selectionStartPoint)({context})) {\n return false\n }\n\n if (!isPointBeforeSelection(selectionEndPoint)({context})) {\n return false\n }\n\n return true\n }\n}\n"],"names":["getActiveAnnotations","snapshot","context","selection","selectedBlocks","getSelectedBlocks","selectedSpans","getSelectedSpans","length","flatMap","block","isPortableTextTextBlock","node","markDefs","filter","markDef","some","span","marks","includes","_key","getAnchorBlock","key","isKeyedSegment","anchor","path","undefined","value","find","getAnchorTextBlock","anchorBlock","getAnchorChild","children","getAnchorSpan","anchorChild","isPortableTextSpan","getBlockOffsets","selectionStartPoint","getSelectionStartPoint","selectionEndPoint","getSelectionEndPoint","start","utils","selectionPoint","end","getSelectedSlice","sliceBlocks","blocks","getSelection","getValue","isPointAfterSelection","point","reverseSelection","pointBlockKey","isKeySegment","pointChildKey","endBlockKey","focus","endChildKey","after","child","offset","isPointBeforeSelection","startBlockKey","startChildKey","before","isOverlappingSelection"],"mappings":"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"}
|
package/lib/utils/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
-
var util_reverseSelection = require("../_chunks-cjs/util.reverse-selection.cjs"),
|
|
3
|
+
var util_reverseSelection = require("../_chunks-cjs/util.reverse-selection.cjs"), util_blockOffsetsToSelection = require("../_chunks-cjs/util.block-offsets-to-selection.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs");
|
|
4
4
|
function isTextBlock(context, block) {
|
|
5
5
|
return block._type === context.schema.block.name;
|
|
6
6
|
}
|
|
@@ -9,7 +9,7 @@ function mergeTextBlocks({
|
|
|
9
9
|
targetBlock,
|
|
10
10
|
incomingBlock
|
|
11
11
|
}) {
|
|
12
|
-
const parsedIncomingBlock =
|
|
12
|
+
const parsedIncomingBlock = util_blockOffsetsToSelection.parseBlock({
|
|
13
13
|
context,
|
|
14
14
|
block: incomingBlock,
|
|
15
15
|
options: {
|
|
@@ -66,13 +66,14 @@ function splitTextBlock({
|
|
|
66
66
|
exports.blockOffsetToSpanSelectionPoint = util_reverseSelection.blockOffsetToSpanSelectionPoint;
|
|
67
67
|
exports.getBlockEndPoint = util_reverseSelection.getBlockEndPoint;
|
|
68
68
|
exports.getBlockStartPoint = util_reverseSelection.getBlockStartPoint;
|
|
69
|
+
exports.getTextBlockText = util_reverseSelection.getTextBlockText;
|
|
70
|
+
exports.isEmptyTextBlock = util_reverseSelection.isEmptyTextBlock;
|
|
69
71
|
exports.isEqualSelectionPoints = util_reverseSelection.isEqualSelectionPoints;
|
|
70
72
|
exports.isKeyedSegment = util_reverseSelection.isKeyedSegment;
|
|
71
73
|
exports.isSpan = util_reverseSelection.isSpan;
|
|
72
74
|
exports.reverseSelection = util_reverseSelection.reverseSelection;
|
|
73
75
|
exports.spanSelectionPointToBlockOffset = util_reverseSelection.spanSelectionPointToBlockOffset;
|
|
74
|
-
exports.
|
|
75
|
-
exports.isEmptyTextBlock = util_isEmptyTextBlock.isEmptyTextBlock;
|
|
76
|
+
exports.blockOffsetsToSelection = util_blockOffsetsToSelection.blockOffsetsToSelection;
|
|
76
77
|
exports.sliceBlocks = util_sliceBlocks.sliceBlocks;
|
|
77
78
|
exports.isTextBlock = isTextBlock;
|
|
78
79
|
exports.mergeTextBlocks = mergeTextBlocks;
|
package/lib/utils/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../selectors'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport type {EditorContext} from '../selectors'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {isTextBlock, sliceBlocks, type EditorSelectionPoint} from '.'\nimport type {EditorContext} from '../selectors'\nimport {isSpan} from './util.is-span'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isTextBlock","context","block","_type","schema","name","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","children","markDefs","splitTextBlock","point","firstChild","at","lastChild","length","before","sliceBlocks","blocks","selection","anchor","path","_key","offset","focus","after","isSpan","text"],"mappings":";;;AAMgBA,SAAAA,YACdC,SACAC,OACgC;AAChC,SAAOA,MAAMC,UAAUF,QAAQG,OAAOF,MAAMG;AAC9C;ACHO,SAASC,gBAAgB;AAAA,EAC9BL;AAAAA,EACAM;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../selectors'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport type {EditorContext} from '../selectors'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {isTextBlock, sliceBlocks, type EditorSelectionPoint} from '.'\nimport type {EditorContext} from '../selectors'\nimport {isSpan} from './util.is-span'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isTextBlock","context","block","_type","schema","name","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","children","markDefs","splitTextBlock","point","firstChild","at","lastChild","length","before","sliceBlocks","blocks","selection","anchor","path","_key","offset","focus","after","isSpan","text"],"mappings":";;;AAMgBA,SAAAA,YACdC,SACAC,OACgC;AAChC,SAAOA,MAAMC,UAAUF,QAAQG,OAAOF,MAAMG;AAC9C;ACHO,SAASC,gBAAgB;AAAA,EAC9BL;AAAAA,EACAM;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,6BAAAA,WAAW;AAAA,IACrCT;AAAAA,IACAC,OAAOM;AAAAA,IACPG,SAAS;AAAA,MAACC,aAAa;AAAA,IAAA;AAAA,EAAI,CAC5B;AAED,SAAI,CAACH,uBAAuB,CAACT,YAAYC,SAASQ,mBAAmB,IAC5DF,cAGF;AAAA,IACL,GAAGA;AAAAA,IACHM,UAAU,CAAC,GAAGN,YAAYM,UAAU,GAAGJ,oBAAoBI,QAAQ;AAAA,IACnEC,UAAU,CACR,GAAIP,YAAYO,YAAY,CAAA,GAC5B,GAAIL,oBAAoBK,YAAY,CAAG,CAAA;AAAA,EAE3C;AACF;AC3BO,SAASC,eAAe;AAAA,EAC7Bd;AAAAA,EACAC;AAAAA,EACAc;AAKF,GAA8E;AAC5E,QAAMC,aAAaf,MAAMW,SAASK,GAAG,CAAC,GAChCC,YAAYjB,MAAMW,SAASK,GAAGhB,MAAMW,SAASO,SAAS,CAAC;AAEzD,MAAA,CAACH,cAAc,CAACE;AAClB;AAGF,QAAME,SAASC,iBAAAA,YAAY;AAAA,IACzBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQ;AAAA,QACNC,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAC,OAAOb;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEE,GAAG,CAAC,GACDY,QAAQR,iBAAAA,YAAY;AAAA,IACxBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQT;AAAAA,MACRa,OAAO;AAAA,QACLH,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,UAAUQ;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQG,sBAAO9B,OAAAA,SAASkB,SAAS,IAAIA,UAAUa,KAAKZ,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACS,UAIZ,EAAC9B,CAAAA,YAAYC,SAASoB,MAAM,KAAK,CAACrB,YAAYC,SAAS6B,KAAK;AAIzD,WAAA;AAAA,MAACT;AAAAA,MAAQS;AAAAA,IAAK;AACvB;;;;;;;;;;;;;;;;"}
|
package/lib/utils/index.d.cts
CHANGED
|
@@ -24,6 +24,22 @@ export declare type BlockOffset = {
|
|
|
24
24
|
offset: number
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare function blockOffsetsToSelection({
|
|
31
|
+
value,
|
|
32
|
+
offsets,
|
|
33
|
+
backward,
|
|
34
|
+
}: {
|
|
35
|
+
value: Array<PortableTextBlock>
|
|
36
|
+
offsets: {
|
|
37
|
+
anchor: BlockOffset
|
|
38
|
+
focus: BlockOffset
|
|
39
|
+
}
|
|
40
|
+
backward?: boolean
|
|
41
|
+
}): EditorSelection
|
|
42
|
+
|
|
27
43
|
/**
|
|
28
44
|
* @public
|
|
29
45
|
*/
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -24,6 +24,22 @@ export declare type BlockOffset = {
|
|
|
24
24
|
offset: number
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare function blockOffsetsToSelection({
|
|
31
|
+
value,
|
|
32
|
+
offsets,
|
|
33
|
+
backward,
|
|
34
|
+
}: {
|
|
35
|
+
value: Array<PortableTextBlock>
|
|
36
|
+
offsets: {
|
|
37
|
+
anchor: BlockOffset
|
|
38
|
+
focus: BlockOffset
|
|
39
|
+
}
|
|
40
|
+
backward?: boolean
|
|
41
|
+
}): EditorSelection
|
|
42
|
+
|
|
27
43
|
/**
|
|
28
44
|
* @public
|
|
29
45
|
*/
|
package/lib/utils/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isSpan } from "../_chunks-es/util.reverse-selection.js";
|
|
2
|
-
import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, isEqualSelectionPoints, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset } from "../_chunks-es/util.reverse-selection.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isEqualSelectionPoints, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset } from "../_chunks-es/util.reverse-selection.js";
|
|
3
|
+
import { parseBlock } from "../_chunks-es/util.block-offsets-to-selection.js";
|
|
4
|
+
import { blockOffsetsToSelection } from "../_chunks-es/util.block-offsets-to-selection.js";
|
|
5
5
|
import { sliceBlocks } from "../_chunks-es/util.slice-blocks.js";
|
|
6
6
|
function isTextBlock(context, block) {
|
|
7
7
|
return block._type === context.schema.block.name;
|
|
@@ -67,6 +67,7 @@ function splitTextBlock({
|
|
|
67
67
|
}
|
|
68
68
|
export {
|
|
69
69
|
blockOffsetToSpanSelectionPoint,
|
|
70
|
+
blockOffsetsToSelection,
|
|
70
71
|
getBlockEndPoint,
|
|
71
72
|
getBlockStartPoint,
|
|
72
73
|
getTextBlockText,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.0",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"use-effect-event": "^1.0.2",
|
|
81
81
|
"xstate": "^5.19.2",
|
|
82
82
|
"@portabletext/block-tools": "1.1.6",
|
|
83
|
-
"@portabletext/patches": "1.1.
|
|
83
|
+
"@portabletext/patches": "1.1.3"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@portabletext/toolkit": "^2.0.17",
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {Editor, Range, Text, Transforms} from 'slate'
|
|
2
|
+
import {toPortableTextRange, toSlateRange} from '../internal-utils/ranges'
|
|
3
|
+
import {fromSlateValue} from '../internal-utils/values'
|
|
4
|
+
import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
|
|
5
|
+
import * as selectors from '../selectors'
|
|
6
|
+
import * as utils from '../utils'
|
|
7
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
8
|
+
|
|
9
|
+
export const decoratorAddActionImplementation: BehaviorActionImplementation<
|
|
10
|
+
'decorator.add'
|
|
11
|
+
> = ({context, action}) => {
|
|
12
|
+
const editor = action.editor
|
|
13
|
+
const mark = action.decorator
|
|
14
|
+
const selection = action.selection
|
|
15
|
+
? (toSlateRange(action.selection, action.editor) ?? editor.selection)
|
|
16
|
+
: editor.selection
|
|
17
|
+
|
|
18
|
+
if (!selection) {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const value = fromSlateValue(
|
|
23
|
+
editor.children,
|
|
24
|
+
context.schema.block.name,
|
|
25
|
+
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
const editorSelection = toPortableTextRange(value, selection, context.schema)
|
|
29
|
+
const anchorOffset = editorSelection
|
|
30
|
+
? utils.spanSelectionPointToBlockOffset({
|
|
31
|
+
value,
|
|
32
|
+
selectionPoint: editorSelection.anchor,
|
|
33
|
+
})
|
|
34
|
+
: undefined
|
|
35
|
+
const focusOffset = editorSelection
|
|
36
|
+
? utils.spanSelectionPointToBlockOffset({
|
|
37
|
+
value,
|
|
38
|
+
selectionPoint: editorSelection.focus,
|
|
39
|
+
})
|
|
40
|
+
: undefined
|
|
41
|
+
|
|
42
|
+
if (!anchorOffset || !focusOffset) {
|
|
43
|
+
throw new Error('Unable to find anchor or focus offset')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (Range.isExpanded(selection)) {
|
|
47
|
+
// Split if needed
|
|
48
|
+
Transforms.setNodes(
|
|
49
|
+
editor,
|
|
50
|
+
{},
|
|
51
|
+
{at: selection, match: Text.isText, split: true, hanging: true},
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// The value might have changed after splitting
|
|
55
|
+
const newValue = fromSlateValue(
|
|
56
|
+
editor.children,
|
|
57
|
+
context.schema.block.name,
|
|
58
|
+
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
59
|
+
)
|
|
60
|
+
// We need to find the new selection from the original offsets because the
|
|
61
|
+
// split operation might have changed the value.
|
|
62
|
+
const newSelection = utils.blockOffsetsToSelection({
|
|
63
|
+
value: newValue,
|
|
64
|
+
offsets: {anchor: anchorOffset, focus: focusOffset},
|
|
65
|
+
backward: editorSelection?.backward,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const trimmedSelection = selectors.getTrimmedSelection({
|
|
69
|
+
context: {
|
|
70
|
+
activeDecorators: [],
|
|
71
|
+
converters: [],
|
|
72
|
+
keyGenerator: context.keyGenerator,
|
|
73
|
+
schema: context.schema,
|
|
74
|
+
selection: newSelection,
|
|
75
|
+
value: newValue,
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
if (!trimmedSelection) {
|
|
80
|
+
throw new Error('Unable to find trimmed selection')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const newRange = toSlateRange(trimmedSelection, editor)
|
|
84
|
+
|
|
85
|
+
if (!newRange) {
|
|
86
|
+
throw new Error('Unable to find new selection')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Use new selection to find nodes to decorate
|
|
90
|
+
const splitTextNodes = Range.isRange(newRange)
|
|
91
|
+
? [
|
|
92
|
+
...Editor.nodes(editor, {
|
|
93
|
+
at: newRange,
|
|
94
|
+
match: (node) => Text.isText(node),
|
|
95
|
+
}),
|
|
96
|
+
]
|
|
97
|
+
: []
|
|
98
|
+
|
|
99
|
+
for (const [node, path] of splitTextNodes) {
|
|
100
|
+
const marks = [
|
|
101
|
+
...(Array.isArray(node.marks) ? node.marks : []).filter(
|
|
102
|
+
(eMark: string) => eMark !== mark,
|
|
103
|
+
),
|
|
104
|
+
mark,
|
|
105
|
+
]
|
|
106
|
+
Transforms.setNodes(
|
|
107
|
+
editor,
|
|
108
|
+
{marks},
|
|
109
|
+
{at: path, match: Text.isText, split: true, hanging: true},
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
const [block, blockPath] = Editor.node(editor, selection, {
|
|
114
|
+
depth: 1,
|
|
115
|
+
})
|
|
116
|
+
const lonelyEmptySpan =
|
|
117
|
+
editor.isTextBlock(block) &&
|
|
118
|
+
block.children.length === 1 &&
|
|
119
|
+
editor.isTextSpan(block.children[0]) &&
|
|
120
|
+
block.children[0].text === ''
|
|
121
|
+
? block.children[0]
|
|
122
|
+
: undefined
|
|
123
|
+
|
|
124
|
+
if (lonelyEmptySpan) {
|
|
125
|
+
const existingMarks = lonelyEmptySpan.marks ?? []
|
|
126
|
+
const existingMarksWithoutDecorator = existingMarks.filter(
|
|
127
|
+
(existingMark) => existingMark !== mark,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
Transforms.setNodes(
|
|
131
|
+
editor,
|
|
132
|
+
{
|
|
133
|
+
marks:
|
|
134
|
+
existingMarks.length === existingMarksWithoutDecorator.length
|
|
135
|
+
? [...existingMarks, mark]
|
|
136
|
+
: existingMarksWithoutDecorator,
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
at: blockPath,
|
|
140
|
+
match: (node) => editor.isTextSpan(node),
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
} else {
|
|
144
|
+
const existingMarks: string[] =
|
|
145
|
+
{
|
|
146
|
+
...(Editor.marks(editor) || {}),
|
|
147
|
+
}.marks || []
|
|
148
|
+
const marks = {
|
|
149
|
+
...(Editor.marks(editor) || {}),
|
|
150
|
+
marks: [...existingMarks, mark],
|
|
151
|
+
}
|
|
152
|
+
editor.marks = marks as Text
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (editor.selection) {
|
|
157
|
+
// Reselect
|
|
158
|
+
const selection = editor.selection
|
|
159
|
+
editor.selection = {...selection}
|
|
160
|
+
}
|
|
161
|
+
}
|