@portabletext/editor 2.7.2 → 2.8.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.is-selecting-entire-blocks.cjs +3 -1
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +10 -4
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs +0 -1
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs +60 -9
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-dts/behavior.types.action.d.cts +149 -149
- package/lib/_chunks-dts/behavior.types.action.d.ts +86 -86
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +4 -2
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
- package/lib/_chunks-es/selector.is-selection-expanded.js +10 -4
- package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
- package/lib/_chunks-es/util.merge-text-blocks.js +0 -1
- package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
- package/lib/_chunks-es/util.slice-blocks.js +56 -8
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/index.cjs +94 -131
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +90 -128
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.cts +3 -3
- package/lib/selectors/index.d.cts +13 -3
- package/lib/selectors/index.d.ts +13 -3
- package/package.json +13 -14
- package/src/behaviors/behavior.abstract.insert.ts +58 -1
- package/src/behaviors/behavior.abstract.split.ts +0 -1
- package/src/behaviors/behavior.core.annotations.ts +24 -2
- package/src/behaviors/behavior.core.ts +1 -1
- package/src/behaviors/behavior.types.event.ts +18 -18
- package/src/converters/converter.portable-text.ts +0 -1
- package/src/converters/converter.text-html.serialize.test.ts +27 -17
- package/src/converters/converter.text-html.ts +0 -1
- package/src/converters/converter.text-plain.test.ts +1 -1
- package/src/converters/converter.text-plain.ts +0 -1
- package/src/editor/Editable.tsx +0 -1
- package/src/editor/plugins/createWithEditableAPI.ts +16 -0
- package/src/internal-utils/parse-blocks.test.ts +23 -23
- package/src/internal-utils/parse-blocks.ts +13 -24
- package/src/internal-utils/test-editor.tsx +15 -21
- package/src/operations/behavior.operation.annotation.add.ts +2 -13
- package/src/operations/behavior.operation.block.set.ts +1 -1
- package/src/operations/behavior.operation.block.unset.ts +2 -2
- package/src/operations/behavior.operation.insert.block.ts +1 -1
- package/src/operations/behavior.operations.ts +0 -18
- package/src/plugins/plugin.internal.auto-close-brackets.test.tsx +25 -71
- package/src/plugins/plugin.markdown.test.tsx +12 -30
- package/src/selectors/selector.get-selected-value.test.ts +748 -0
- package/src/selectors/selector.get-selected-value.ts +28 -7
- package/src/selectors/selector.get-trimmed-selection.test.ts +0 -1
- package/src/selectors/selector.is-active-annotation.test.ts +320 -0
- package/src/selectors/selector.is-active-annotation.ts +24 -0
- package/src/utils/util.merge-text-blocks.ts +1 -1
- package/src/utils/util.slice-blocks.ts +36 -3
- package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -430
- package/src/editor/__tests__/PortableTextEditorTester.tsx +0 -58
- package/src/editor/__tests__/RangeDecorations.test.tsx +0 -213
- package/src/editor/__tests__/insert-block.test.tsx +0 -224
- package/src/editor/__tests__/self-solving.test.tsx +0 -183
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +0 -298
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +0 -177
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +0 -538
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +0 -162
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +0 -65
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +0 -612
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +0 -103
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +0 -147
- package/src/internal-utils/__tests__/valueNormalization.test.tsx +0 -79
- package/src/operations/behavior.operation.insert-inline-object.ts +0 -59
- package/src/operations/behavior.operation.insert-span.ts +0 -48
- package/src/utils/util.slice-blocks.test.ts +0 -465
package/lib/plugins/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react11 from "react";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* @beta
|
|
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
|
|
|
181
181
|
*/
|
|
182
182
|
declare function MarkdownPlugin(props: {
|
|
183
183
|
config: MarkdownPluginConfig;
|
|
184
|
-
}):
|
|
184
|
+
}): react11.JSX.Element;
|
|
185
185
|
/**
|
|
186
186
|
* @beta
|
|
187
187
|
* Restrict the editor to one line. The plugin takes care of blocking
|
|
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
|
|
|
192
192
|
*
|
|
193
193
|
* @deprecated Install the plugin from `@portabletext/plugin-one-line`
|
|
194
194
|
*/
|
|
195
|
-
declare function OneLinePlugin():
|
|
195
|
+
declare function OneLinePlugin(): react11.JSX.Element;
|
|
196
196
|
export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
|
|
@@ -242,9 +242,19 @@ declare const getTrimmedSelection: EditorSelector<EditorSelection>;
|
|
|
242
242
|
*/
|
|
243
243
|
declare const getValue: EditorSelector<Array<PortableTextBlock>>;
|
|
244
244
|
/**
|
|
245
|
-
*
|
|
246
|
-
|
|
247
|
-
|
|
245
|
+
* Check whether an annotation is active in the given `snapshot`.
|
|
246
|
+
*
|
|
247
|
+
* @public
|
|
248
|
+
*/
|
|
249
|
+
declare function isActiveAnnotation(annotation: string, options?: {
|
|
250
|
+
/**
|
|
251
|
+
* Choose whether the annotation has to take up the entire selection in the
|
|
252
|
+
* `snapshot` or if the annotation can be partially selected.
|
|
253
|
+
*
|
|
254
|
+
* Defaults to 'full'
|
|
255
|
+
*/
|
|
256
|
+
mode?: 'partial' | 'full';
|
|
257
|
+
}): EditorSelector<boolean>;
|
|
248
258
|
/**
|
|
249
259
|
* @public
|
|
250
260
|
*/
|
package/lib/selectors/index.d.ts
CHANGED
|
@@ -242,9 +242,19 @@ declare const getTrimmedSelection: EditorSelector<EditorSelection>;
|
|
|
242
242
|
*/
|
|
243
243
|
declare const getValue: EditorSelector<Array<PortableTextBlock>>;
|
|
244
244
|
/**
|
|
245
|
-
*
|
|
246
|
-
|
|
247
|
-
|
|
245
|
+
* Check whether an annotation is active in the given `snapshot`.
|
|
246
|
+
*
|
|
247
|
+
* @public
|
|
248
|
+
*/
|
|
249
|
+
declare function isActiveAnnotation(annotation: string, options?: {
|
|
250
|
+
/**
|
|
251
|
+
* Choose whether the annotation has to take up the entire selection in the
|
|
252
|
+
* `snapshot` or if the annotation can be partially selected.
|
|
253
|
+
*
|
|
254
|
+
* Defaults to 'full'
|
|
255
|
+
*/
|
|
256
|
+
mode?: 'partial' | 'full';
|
|
257
|
+
}): EditorSelector<boolean>;
|
|
248
258
|
/**
|
|
249
259
|
* @public
|
|
250
260
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@xstate/react": "^6.0.0",
|
|
72
72
|
"debug": "^4.4.1",
|
|
73
73
|
"get-random-values-esm": "^1.0.2",
|
|
74
|
-
"immer": "^10.1.
|
|
74
|
+
"immer": "^10.1.3",
|
|
75
75
|
"lodash": "^4.17.21",
|
|
76
76
|
"lodash.startcase": "^4.4.0",
|
|
77
77
|
"react-compiler-runtime": "19.1.0-rc.3",
|
|
@@ -79,17 +79,16 @@
|
|
|
79
79
|
"slate-dom": "^0.118.1",
|
|
80
80
|
"slate-react": "0.117.4",
|
|
81
81
|
"xstate": "^5.21.0",
|
|
82
|
-
"@portabletext/block-tools": "^3.5.
|
|
83
|
-
"@portabletext/schema": "^1.2.0",
|
|
82
|
+
"@portabletext/block-tools": "^3.5.3",
|
|
84
83
|
"@portabletext/keyboard-shortcuts": "^1.1.1",
|
|
85
|
-
"@portabletext/patches": "^1.1.8"
|
|
84
|
+
"@portabletext/patches": "^1.1.8",
|
|
85
|
+
"@portabletext/schema": "^1.2.0"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
89
89
|
"@sanity/pkg-utils": "^8.1.4",
|
|
90
|
-
"@sanity/schema": "^4.6.
|
|
91
|
-
"@sanity/types": "^4.6.
|
|
92
|
-
"@testing-library/react": "^16.3.0",
|
|
90
|
+
"@sanity/schema": "^4.6.1",
|
|
91
|
+
"@sanity/types": "^4.6.1",
|
|
93
92
|
"@types/debug": "^4.1.12",
|
|
94
93
|
"@types/lodash": "^4.17.20",
|
|
95
94
|
"@types/lodash.startcase": "^4.4.9",
|
|
@@ -111,14 +110,14 @@
|
|
|
111
110
|
"vite": "^7.1.3",
|
|
112
111
|
"vitest": "^3.2.4",
|
|
113
112
|
"vitest-browser-react": "^1.0.1",
|
|
114
|
-
"@portabletext/sanity-bridge": "1.1.
|
|
115
|
-
"
|
|
116
|
-
"
|
|
113
|
+
"@portabletext/sanity-bridge": "1.1.8",
|
|
114
|
+
"@portabletext/test": "^0.0.0",
|
|
115
|
+
"racejar": "1.2.15"
|
|
117
116
|
},
|
|
118
117
|
"peerDependencies": {
|
|
119
|
-
"@portabletext/sanity-bridge": "^1.1.
|
|
120
|
-
"@sanity/schema": "^4.6.
|
|
121
|
-
"@sanity/types": "^4.6.
|
|
118
|
+
"@portabletext/sanity-bridge": "^1.1.8",
|
|
119
|
+
"@sanity/schema": "^4.6.1",
|
|
120
|
+
"@sanity/types": "^4.6.1",
|
|
122
121
|
"react": "^18.3 || ^19",
|
|
123
122
|
"rxjs": "^7.8.2"
|
|
124
123
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {getFocusTextBlock} from '../selectors'
|
|
2
2
|
import {isEmptyTextBlock} from '../utils'
|
|
3
|
-
import {raise} from './behavior.types.action'
|
|
3
|
+
import {execute, raise} from './behavior.types.action'
|
|
4
4
|
import {defineBehavior} from './behavior.types.behavior'
|
|
5
5
|
|
|
6
6
|
export const abstractInsertBehaviors = [
|
|
@@ -129,8 +129,65 @@ export const abstractInsertBehaviors = [
|
|
|
129
129
|
on: 'insert.break',
|
|
130
130
|
actions: [() => [raise({type: 'split'})]],
|
|
131
131
|
}),
|
|
132
|
+
defineBehavior({
|
|
133
|
+
on: 'insert.inline object',
|
|
134
|
+
actions: [
|
|
135
|
+
({snapshot, event}) => [
|
|
136
|
+
execute({
|
|
137
|
+
type: 'insert.block',
|
|
138
|
+
block: {
|
|
139
|
+
_type: snapshot.context.schema.block.name,
|
|
140
|
+
children: [
|
|
141
|
+
{
|
|
142
|
+
_type: event.inlineObject.name,
|
|
143
|
+
...event.inlineObject.value,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
placement: 'auto',
|
|
148
|
+
select: 'end',
|
|
149
|
+
}),
|
|
150
|
+
],
|
|
151
|
+
],
|
|
152
|
+
}),
|
|
132
153
|
defineBehavior({
|
|
133
154
|
on: 'insert.soft break',
|
|
134
155
|
actions: [() => [raise({type: 'insert.text', text: '\n'})]],
|
|
135
156
|
}),
|
|
157
|
+
defineBehavior({
|
|
158
|
+
on: 'insert.span',
|
|
159
|
+
guard: ({snapshot, event}) => {
|
|
160
|
+
const markDefs =
|
|
161
|
+
event.annotations?.map((annotation) => ({
|
|
162
|
+
_type: annotation.name,
|
|
163
|
+
_key: snapshot.context.keyGenerator(),
|
|
164
|
+
...annotation.value,
|
|
165
|
+
})) ?? []
|
|
166
|
+
|
|
167
|
+
return {markDefs}
|
|
168
|
+
},
|
|
169
|
+
actions: [
|
|
170
|
+
({snapshot, event}, {markDefs}) => [
|
|
171
|
+
execute({
|
|
172
|
+
type: 'insert.block',
|
|
173
|
+
block: {
|
|
174
|
+
_type: snapshot.context.schema.block.name,
|
|
175
|
+
children: [
|
|
176
|
+
{
|
|
177
|
+
_type: snapshot.context.schema.span.name,
|
|
178
|
+
text: event.text,
|
|
179
|
+
marks: [
|
|
180
|
+
...(event.decorators ?? []),
|
|
181
|
+
...markDefs.map((markDef) => markDef._key),
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
markDefs,
|
|
186
|
+
},
|
|
187
|
+
placement: 'auto',
|
|
188
|
+
select: 'end',
|
|
189
|
+
}),
|
|
190
|
+
],
|
|
191
|
+
],
|
|
192
|
+
}),
|
|
136
193
|
]
|
|
@@ -34,6 +34,28 @@ const addAnnotationOnCollapsedSelection = defineBehavior({
|
|
|
34
34
|
],
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* By default, same-type annotations can overlap. This Core Behavior ensures
|
|
39
|
+
* that annotations of the same type are mutually exclusive.
|
|
40
|
+
*/
|
|
41
|
+
const preventOverlappingAnnotations = defineBehavior({
|
|
42
|
+
// Given an `annotation.add` event
|
|
43
|
+
on: 'annotation.add',
|
|
44
|
+
// When the annotation is active in the selection
|
|
45
|
+
guard: ({snapshot, event}) =>
|
|
46
|
+
selectors.isActiveAnnotation(event.annotation.name, {mode: 'partial'})(
|
|
47
|
+
snapshot,
|
|
48
|
+
),
|
|
49
|
+
// Then the existing annotation is removed
|
|
50
|
+
actions: [
|
|
51
|
+
({event}) => [
|
|
52
|
+
raise({type: 'annotation.remove', annotation: event.annotation}),
|
|
53
|
+
raise(event),
|
|
54
|
+
],
|
|
55
|
+
],
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
export const coreAnnotationBehaviors = [
|
|
38
59
|
addAnnotationOnCollapsedSelection,
|
|
39
|
-
|
|
60
|
+
preventOverlappingAnnotations,
|
|
61
|
+
]
|
|
@@ -7,7 +7,7 @@ import {coreInsertBreakBehaviors} from './behavior.core.insert-break'
|
|
|
7
7
|
import {coreListBehaviors} from './behavior.core.lists'
|
|
8
8
|
|
|
9
9
|
export const coreBehaviorsConfig = [
|
|
10
|
-
coreAnnotationBehaviors
|
|
10
|
+
...coreAnnotationBehaviors,
|
|
11
11
|
coreDecoratorBehaviors.strongShortcut,
|
|
12
12
|
coreDecoratorBehaviors.emShortcut,
|
|
13
13
|
coreDecoratorBehaviors.underlineShortcut,
|
|
@@ -71,9 +71,7 @@ const syntheticBehaviorEventTypes = [
|
|
|
71
71
|
'delete',
|
|
72
72
|
'history.redo',
|
|
73
73
|
'history.undo',
|
|
74
|
-
'insert.inline object',
|
|
75
74
|
'insert.block',
|
|
76
|
-
'insert.span',
|
|
77
75
|
'insert.text',
|
|
78
76
|
'move.backward',
|
|
79
77
|
'move.block',
|
|
@@ -155,28 +153,12 @@ export type SyntheticBehaviorEvent =
|
|
|
155
153
|
| {
|
|
156
154
|
type: StrictExtract<SyntheticBehaviorEventType, 'history.undo'>
|
|
157
155
|
}
|
|
158
|
-
| {
|
|
159
|
-
type: StrictExtract<SyntheticBehaviorEventType, 'insert.inline object'>
|
|
160
|
-
inlineObject: {
|
|
161
|
-
name: string
|
|
162
|
-
value?: {[prop: string]: unknown}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
156
|
| {
|
|
166
157
|
type: StrictExtract<SyntheticBehaviorEventType, 'insert.block'>
|
|
167
158
|
block: BlockWithOptionalKey
|
|
168
159
|
placement: InsertPlacement
|
|
169
160
|
select?: 'start' | 'end' | 'none'
|
|
170
161
|
}
|
|
171
|
-
| {
|
|
172
|
-
type: StrictExtract<SyntheticBehaviorEventType, 'insert.span'>
|
|
173
|
-
text: string
|
|
174
|
-
annotations?: Array<{
|
|
175
|
-
name: string
|
|
176
|
-
value: {[prop: string]: unknown}
|
|
177
|
-
}>
|
|
178
|
-
decorators?: Array<string>
|
|
179
|
-
}
|
|
180
162
|
| {
|
|
181
163
|
type: StrictExtract<SyntheticBehaviorEventType, 'insert.text'>
|
|
182
164
|
text: string
|
|
@@ -238,7 +220,9 @@ const abstractBehaviorEventTypes = [
|
|
|
238
220
|
'deserialization.failure',
|
|
239
221
|
'insert.blocks',
|
|
240
222
|
'insert.break',
|
|
223
|
+
'insert.inline object',
|
|
241
224
|
'insert.soft break',
|
|
225
|
+
'insert.span',
|
|
242
226
|
'list item.add',
|
|
243
227
|
'list item.remove',
|
|
244
228
|
'list item.toggle',
|
|
@@ -392,9 +376,25 @@ type AbstractBehaviorEvent =
|
|
|
392
376
|
| {
|
|
393
377
|
type: StrictExtract<SyntheticBehaviorEventType, 'insert.break'>
|
|
394
378
|
}
|
|
379
|
+
| {
|
|
380
|
+
type: StrictExtract<SyntheticBehaviorEventType, 'insert.inline object'>
|
|
381
|
+
inlineObject: {
|
|
382
|
+
name: string
|
|
383
|
+
value?: {[prop: string]: unknown}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
395
386
|
| {
|
|
396
387
|
type: StrictExtract<SyntheticBehaviorEventType, 'insert.soft break'>
|
|
397
388
|
}
|
|
389
|
+
| {
|
|
390
|
+
type: StrictExtract<SyntheticBehaviorEventType, 'insert.span'>
|
|
391
|
+
text: string
|
|
392
|
+
annotations?: Array<{
|
|
393
|
+
name: string
|
|
394
|
+
value: {[prop: string]: unknown}
|
|
395
|
+
}>
|
|
396
|
+
decorators?: Array<string>
|
|
397
|
+
}
|
|
398
398
|
| {
|
|
399
399
|
type: StrictExtract<SyntheticBehaviorEventType, 'list item.add'>
|
|
400
400
|
listItem: string
|
|
@@ -94,24 +94,29 @@ describe(converterTextHtml.serialize.name, () => {
|
|
|
94
94
|
test('paragraph with decorators', () => {
|
|
95
95
|
expect(
|
|
96
96
|
converterTextHtml.serialize({
|
|
97
|
-
snapshot: createSnapshot(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
snapshot: createSnapshot(
|
|
98
|
+
defineSchema({
|
|
99
|
+
decorators: [{name: 'em'}, {name: 'code'}, {name: 'strong'}],
|
|
100
|
+
}),
|
|
101
|
+
{
|
|
102
|
+
anchor: {
|
|
103
|
+
path: [
|
|
104
|
+
{_key: decoratedParagraph._key},
|
|
105
|
+
'children',
|
|
106
|
+
{_key: decoratedParagraph.children[0]._key},
|
|
107
|
+
],
|
|
108
|
+
offset: 0,
|
|
109
|
+
},
|
|
110
|
+
focus: {
|
|
111
|
+
path: [
|
|
112
|
+
{_key: decoratedParagraph._key},
|
|
113
|
+
'children',
|
|
114
|
+
{_key: decoratedParagraph.children[2]._key},
|
|
115
|
+
],
|
|
116
|
+
offset: 4,
|
|
117
|
+
},
|
|
113
118
|
},
|
|
114
|
-
|
|
119
|
+
),
|
|
115
120
|
event: {
|
|
116
121
|
type: 'serialize',
|
|
117
122
|
originEvent: 'clipboard.copy',
|
|
@@ -181,6 +186,11 @@ describe(converterTextHtml.serialize.name, () => {
|
|
|
181
186
|
converterTextHtml.serialize({
|
|
182
187
|
snapshot: createTestSnapshot({
|
|
183
188
|
context: {
|
|
189
|
+
schema: compileSchema(
|
|
190
|
+
defineSchema({
|
|
191
|
+
lists: [{name: 'bullet'}, {name: 'number'}],
|
|
192
|
+
}),
|
|
193
|
+
),
|
|
184
194
|
converters: [],
|
|
185
195
|
value: [
|
|
186
196
|
{
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'
|
|
8
8
|
import {expect, test} from 'vitest'
|
|
9
9
|
import type {EditorSelection} from '..'
|
|
10
|
-
import {schemaDefinition} from '
|
|
10
|
+
import {schemaDefinition} from '../../tests/PortableTextEditorTester'
|
|
11
11
|
import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
|
|
12
12
|
import {createConverterTextPlain} from './converter.text-plain'
|
|
13
13
|
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -426,6 +426,22 @@ export function createEditableAPI(
|
|
|
426
426
|
addAnnotation: (type, value) => {
|
|
427
427
|
let paths: ReturnType<EditableAPI['addAnnotation']>
|
|
428
428
|
|
|
429
|
+
const snapshot = getEditorSnapshot({
|
|
430
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
431
|
+
slateEditorInstance: editor,
|
|
432
|
+
})
|
|
433
|
+
|
|
434
|
+
if (isActiveAnnotation(type.name, {mode: 'partial'})(snapshot)) {
|
|
435
|
+
editorActor.send({
|
|
436
|
+
type: 'behavior event',
|
|
437
|
+
behaviorEvent: {
|
|
438
|
+
type: 'annotation.remove',
|
|
439
|
+
annotation: {name: type.name},
|
|
440
|
+
},
|
|
441
|
+
editor,
|
|
442
|
+
})
|
|
443
|
+
}
|
|
444
|
+
|
|
429
445
|
Editor.withoutNormalizing(editor, () => {
|
|
430
446
|
paths = addAnnotationOperationImplementation({
|
|
431
447
|
context: {
|
|
@@ -12,7 +12,7 @@ describe(parseBlock.name, () => {
|
|
|
12
12
|
keyGenerator: createTestKeyGenerator(),
|
|
13
13
|
schema: compileSchema(defineSchema({})),
|
|
14
14
|
},
|
|
15
|
-
options: {
|
|
15
|
+
options: {validateFields: true},
|
|
16
16
|
}),
|
|
17
17
|
).toBe(undefined)
|
|
18
18
|
})
|
|
@@ -25,7 +25,7 @@ describe(parseBlock.name, () => {
|
|
|
25
25
|
keyGenerator: createTestKeyGenerator(),
|
|
26
26
|
schema: compileSchema(defineSchema({})),
|
|
27
27
|
},
|
|
28
|
-
options: {
|
|
28
|
+
options: {validateFields: true},
|
|
29
29
|
}),
|
|
30
30
|
).toBe(undefined)
|
|
31
31
|
})
|
|
@@ -39,7 +39,7 @@ describe(parseBlock.name, () => {
|
|
|
39
39
|
keyGenerator: createTestKeyGenerator(),
|
|
40
40
|
schema: compileSchema(defineSchema({})),
|
|
41
41
|
},
|
|
42
|
-
options: {
|
|
42
|
+
options: {validateFields: true},
|
|
43
43
|
}),
|
|
44
44
|
).toBe(undefined)
|
|
45
45
|
})
|
|
@@ -54,7 +54,7 @@ describe(parseBlock.name, () => {
|
|
|
54
54
|
defineSchema({blockObjects: [{name: 'image'}]}),
|
|
55
55
|
),
|
|
56
56
|
},
|
|
57
|
-
options: {
|
|
57
|
+
options: {validateFields: true},
|
|
58
58
|
}),
|
|
59
59
|
).toBe(undefined)
|
|
60
60
|
})
|
|
@@ -69,7 +69,7 @@ describe(parseBlock.name, () => {
|
|
|
69
69
|
defineSchema({blockObjects: [{name: 'image'}]}),
|
|
70
70
|
),
|
|
71
71
|
},
|
|
72
|
-
options: {
|
|
72
|
+
options: {validateFields: true},
|
|
73
73
|
}),
|
|
74
74
|
).toEqual({
|
|
75
75
|
_key: 'k0',
|
|
@@ -87,7 +87,7 @@ describe(parseBlock.name, () => {
|
|
|
87
87
|
keyGenerator: createTestKeyGenerator(),
|
|
88
88
|
schema: compileSchema(defineSchema({})),
|
|
89
89
|
},
|
|
90
|
-
options: {
|
|
90
|
+
options: {validateFields: true},
|
|
91
91
|
}),
|
|
92
92
|
).toEqual({
|
|
93
93
|
_key: 'k0',
|
|
@@ -114,7 +114,7 @@ describe(parseBlock.name, () => {
|
|
|
114
114
|
keyGenerator: createTestKeyGenerator(),
|
|
115
115
|
schema: {...schema, block: {...schema.block, name: 'text'}},
|
|
116
116
|
},
|
|
117
|
-
options: {
|
|
117
|
+
options: {validateFields: true},
|
|
118
118
|
}),
|
|
119
119
|
).toEqual({
|
|
120
120
|
_key: 'k0',
|
|
@@ -149,7 +149,7 @@ describe(parseBlock.name, () => {
|
|
|
149
149
|
keyGenerator: createTestKeyGenerator(),
|
|
150
150
|
schema: compileSchema(defineSchema({})),
|
|
151
151
|
},
|
|
152
|
-
options: {
|
|
152
|
+
options: {validateFields: true},
|
|
153
153
|
}),
|
|
154
154
|
).toBe(undefined)
|
|
155
155
|
})
|
|
@@ -188,7 +188,7 @@ describe(parseBlock.name, () => {
|
|
|
188
188
|
}),
|
|
189
189
|
),
|
|
190
190
|
},
|
|
191
|
-
options: {
|
|
191
|
+
options: {validateFields: true},
|
|
192
192
|
}),
|
|
193
193
|
).toEqual({
|
|
194
194
|
_key: 'k0',
|
|
@@ -236,7 +236,7 @@ describe(parseBlock.name, () => {
|
|
|
236
236
|
keyGenerator: createTestKeyGenerator(),
|
|
237
237
|
schema: compileSchema(defineSchema({lists: [{name: 'bullet'}]})),
|
|
238
238
|
},
|
|
239
|
-
options: {
|
|
239
|
+
options: {validateFields: true},
|
|
240
240
|
}),
|
|
241
241
|
).toEqual({
|
|
242
242
|
_key: 'k0',
|
|
@@ -263,7 +263,7 @@ describe(parseBlock.name, () => {
|
|
|
263
263
|
keyGenerator: createTestKeyGenerator(),
|
|
264
264
|
schema: compileSchema(defineSchema({lists: [{name: 'bullet'}]})),
|
|
265
265
|
},
|
|
266
|
-
options: {
|
|
266
|
+
options: {validateFields: true},
|
|
267
267
|
}),
|
|
268
268
|
).toEqual({
|
|
269
269
|
_key: 'k0',
|
|
@@ -290,7 +290,7 @@ describe(parseBlock.name, () => {
|
|
|
290
290
|
keyGenerator: createTestKeyGenerator(),
|
|
291
291
|
schema: compileSchema(defineSchema({})),
|
|
292
292
|
},
|
|
293
|
-
options: {
|
|
293
|
+
options: {validateFields: true},
|
|
294
294
|
}),
|
|
295
295
|
).toEqual({
|
|
296
296
|
_type: 'block',
|
|
@@ -320,7 +320,7 @@ describe(parseBlock.name, () => {
|
|
|
320
320
|
}),
|
|
321
321
|
),
|
|
322
322
|
},
|
|
323
|
-
options: {
|
|
323
|
+
options: {validateFields: true},
|
|
324
324
|
}),
|
|
325
325
|
).toEqual({
|
|
326
326
|
_type: 'block',
|
|
@@ -351,7 +351,7 @@ describe(parseBlock.name, () => {
|
|
|
351
351
|
}),
|
|
352
352
|
),
|
|
353
353
|
},
|
|
354
|
-
options: {
|
|
354
|
+
options: {validateFields: true},
|
|
355
355
|
}),
|
|
356
356
|
).toEqual({
|
|
357
357
|
_type: 'block',
|
|
@@ -382,7 +382,7 @@ describe(parseSpan.name, () => {
|
|
|
382
382
|
schema: compileSchema(defineSchema({})),
|
|
383
383
|
},
|
|
384
384
|
markDefKeyMap: new Map(),
|
|
385
|
-
options: {
|
|
385
|
+
options: {validateFields: true},
|
|
386
386
|
}),
|
|
387
387
|
).toBe(undefined)
|
|
388
388
|
})
|
|
@@ -396,7 +396,7 @@ describe(parseSpan.name, () => {
|
|
|
396
396
|
schema: compileSchema(defineSchema({})),
|
|
397
397
|
},
|
|
398
398
|
markDefKeyMap: new Map(),
|
|
399
|
-
options: {
|
|
399
|
+
options: {validateFields: true},
|
|
400
400
|
}),
|
|
401
401
|
).toBe(undefined)
|
|
402
402
|
})
|
|
@@ -410,7 +410,7 @@ describe(parseSpan.name, () => {
|
|
|
410
410
|
schema: compileSchema(defineSchema({})),
|
|
411
411
|
},
|
|
412
412
|
markDefKeyMap: new Map(),
|
|
413
|
-
options: {
|
|
413
|
+
options: {validateFields: true},
|
|
414
414
|
}),
|
|
415
415
|
).toBe(undefined)
|
|
416
416
|
})
|
|
@@ -424,7 +424,7 @@ describe(parseSpan.name, () => {
|
|
|
424
424
|
schema: compileSchema(defineSchema({})),
|
|
425
425
|
},
|
|
426
426
|
markDefKeyMap: new Map(),
|
|
427
|
-
options: {
|
|
427
|
+
options: {validateFields: true},
|
|
428
428
|
}),
|
|
429
429
|
).toBe(undefined)
|
|
430
430
|
})
|
|
@@ -438,7 +438,7 @@ describe(parseSpan.name, () => {
|
|
|
438
438
|
schema: compileSchema(defineSchema({})),
|
|
439
439
|
},
|
|
440
440
|
markDefKeyMap: new Map(),
|
|
441
|
-
options: {
|
|
441
|
+
options: {validateFields: true},
|
|
442
442
|
}),
|
|
443
443
|
).toEqual({
|
|
444
444
|
_key: 'k0',
|
|
@@ -457,7 +457,7 @@ describe(parseSpan.name, () => {
|
|
|
457
457
|
schema: compileSchema(defineSchema({})),
|
|
458
458
|
},
|
|
459
459
|
markDefKeyMap: new Map(),
|
|
460
|
-
options: {
|
|
460
|
+
options: {validateFields: true},
|
|
461
461
|
}),
|
|
462
462
|
).toEqual({
|
|
463
463
|
_key: 'k0',
|
|
@@ -479,7 +479,7 @@ describe(parseSpan.name, () => {
|
|
|
479
479
|
schema: compileSchema(defineSchema({})),
|
|
480
480
|
},
|
|
481
481
|
markDefKeyMap: new Map(),
|
|
482
|
-
options: {
|
|
482
|
+
options: {validateFields: true},
|
|
483
483
|
}),
|
|
484
484
|
).toEqual({
|
|
485
485
|
_key: 'k0',
|
|
@@ -501,7 +501,7 @@ describe(parseSpan.name, () => {
|
|
|
501
501
|
schema: compileSchema(defineSchema({decorators: [{name: 'strong'}]})),
|
|
502
502
|
},
|
|
503
503
|
markDefKeyMap: new Map(),
|
|
504
|
-
options: {
|
|
504
|
+
options: {validateFields: true},
|
|
505
505
|
}),
|
|
506
506
|
).toEqual({
|
|
507
507
|
_key: 'k0',
|
|
@@ -523,7 +523,7 @@ describe(parseSpan.name, () => {
|
|
|
523
523
|
schema: compileSchema(defineSchema({decorators: [{name: 'strong'}]})),
|
|
524
524
|
},
|
|
525
525
|
markDefKeyMap: new Map(),
|
|
526
|
-
options: {
|
|
526
|
+
options: {validateFields: true},
|
|
527
527
|
}),
|
|
528
528
|
).toEqual({
|
|
529
529
|
_key: 'k0',
|