@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
|
@@ -19,7 +19,6 @@ export function parseBlocks({
|
|
|
19
19
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
20
20
|
blocks: unknown
|
|
21
21
|
options: {
|
|
22
|
-
refreshKeys: boolean
|
|
23
22
|
validateFields: boolean
|
|
24
23
|
}
|
|
25
24
|
}): Array<PortableTextBlock> {
|
|
@@ -42,7 +41,6 @@ export function parseBlock({
|
|
|
42
41
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
43
42
|
block: unknown
|
|
44
43
|
options: {
|
|
45
|
-
refreshKeys: boolean
|
|
46
44
|
validateFields: boolean
|
|
47
45
|
}
|
|
48
46
|
}): PortableTextBlock | undefined {
|
|
@@ -59,7 +57,7 @@ export function parseBlockObject({
|
|
|
59
57
|
}: {
|
|
60
58
|
blockObject: unknown
|
|
61
59
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
62
|
-
options: {
|
|
60
|
+
options: {validateFields: boolean}
|
|
63
61
|
}): PortableTextObject | undefined {
|
|
64
62
|
if (!isTypedObject(blockObject)) {
|
|
65
63
|
return undefined
|
|
@@ -101,7 +99,7 @@ export function parseTextBlock({
|
|
|
101
99
|
}: {
|
|
102
100
|
block: unknown
|
|
103
101
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
104
|
-
options: {
|
|
102
|
+
options: {validateFields: boolean}
|
|
105
103
|
}): PortableTextTextBlock | undefined {
|
|
106
104
|
if (!isTypedObject(block)) {
|
|
107
105
|
return undefined
|
|
@@ -135,11 +133,8 @@ export function parseTextBlock({
|
|
|
135
133
|
return undefined
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
const _key =
|
|
139
|
-
? context.keyGenerator()
|
|
140
|
-
: typeof block._key === 'string'
|
|
141
|
-
? block._key
|
|
142
|
-
: context.keyGenerator()
|
|
136
|
+
const _key =
|
|
137
|
+
typeof block._key === 'string' ? block._key : context.keyGenerator()
|
|
143
138
|
|
|
144
139
|
const unparsedMarkDefs: Array<unknown> = Array.isArray(block.markDefs)
|
|
145
140
|
? block.markDefs
|
|
@@ -193,6 +188,7 @@ export function parseTextBlock({
|
|
|
193
188
|
parseInlineObject({inlineObject: child, context, options}),
|
|
194
189
|
)
|
|
195
190
|
.filter((child) => child !== undefined)
|
|
191
|
+
const marks = children.flatMap((child) => child.marks ?? [])
|
|
196
192
|
|
|
197
193
|
const parsedBlock: PortableTextTextBlock = {
|
|
198
194
|
_type: context.schema.block.name,
|
|
@@ -208,7 +204,7 @@ export function parseTextBlock({
|
|
|
208
204
|
marks: [],
|
|
209
205
|
},
|
|
210
206
|
],
|
|
211
|
-
markDefs,
|
|
207
|
+
markDefs: markDefs.filter((markDef) => marks.includes(markDef._key)),
|
|
212
208
|
...customFields,
|
|
213
209
|
}
|
|
214
210
|
|
|
@@ -250,7 +246,7 @@ export function parseSpan({
|
|
|
250
246
|
span: unknown
|
|
251
247
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
252
248
|
markDefKeyMap: Map<string, string>
|
|
253
|
-
options: {
|
|
249
|
+
options: {validateFields: boolean}
|
|
254
250
|
}): PortableTextSpan | undefined {
|
|
255
251
|
if (!isTypedObject(span)) {
|
|
256
252
|
return undefined
|
|
@@ -299,11 +295,7 @@ export function parseSpan({
|
|
|
299
295
|
|
|
300
296
|
return {
|
|
301
297
|
_type: 'span',
|
|
302
|
-
_key:
|
|
303
|
-
? context.keyGenerator()
|
|
304
|
-
: typeof span._key === 'string'
|
|
305
|
-
? span._key
|
|
306
|
-
: context.keyGenerator(),
|
|
298
|
+
_key: typeof span._key === 'string' ? span._key : context.keyGenerator(),
|
|
307
299
|
text: typeof span.text === 'string' ? span.text : '',
|
|
308
300
|
marks,
|
|
309
301
|
...(options.validateFields ? {} : customFields),
|
|
@@ -317,7 +309,7 @@ export function parseInlineObject({
|
|
|
317
309
|
}: {
|
|
318
310
|
inlineObject: unknown
|
|
319
311
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
320
|
-
options: {
|
|
312
|
+
options: {validateFields: boolean}
|
|
321
313
|
}): PortableTextObject | undefined {
|
|
322
314
|
if (!isTypedObject(inlineObject)) {
|
|
323
315
|
return undefined
|
|
@@ -348,7 +340,7 @@ export function parseAnnotation({
|
|
|
348
340
|
}: {
|
|
349
341
|
annotation: TypedObject
|
|
350
342
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
351
|
-
options: {
|
|
343
|
+
options: {validateFields: boolean}
|
|
352
344
|
}): PortableTextObject | undefined {
|
|
353
345
|
if (!isTypedObject(annotation)) {
|
|
354
346
|
return undefined
|
|
@@ -381,7 +373,7 @@ function parseObject({
|
|
|
381
373
|
context: Pick<EditorContext, 'keyGenerator'> & {
|
|
382
374
|
schemaType: EditorSchema['blockObjects'][0]
|
|
383
375
|
}
|
|
384
|
-
options: {
|
|
376
|
+
options: {validateFields: boolean}
|
|
385
377
|
}): PortableTextObject {
|
|
386
378
|
const {_type, _key, ...customFields} = object
|
|
387
379
|
|
|
@@ -404,11 +396,8 @@ function parseObject({
|
|
|
404
396
|
|
|
405
397
|
return {
|
|
406
398
|
_type: context.schemaType.name,
|
|
407
|
-
_key:
|
|
408
|
-
? context.keyGenerator()
|
|
409
|
-
: typeof object._key === 'string'
|
|
410
|
-
? object._key
|
|
411
|
-
: context.keyGenerator(),
|
|
399
|
+
_key:
|
|
400
|
+
typeof object._key === 'string' ? object._key : context.keyGenerator(),
|
|
412
401
|
...values,
|
|
413
402
|
}
|
|
414
403
|
}
|
|
@@ -5,13 +5,16 @@ import {page} from '@vitest/browser/context'
|
|
|
5
5
|
import React from 'react'
|
|
6
6
|
import {expect, vi} from 'vitest'
|
|
7
7
|
import {render} from 'vitest-browser-react'
|
|
8
|
+
import type {Context} from '../../gherkin-tests-v2/step-context'
|
|
9
|
+
import type {NativeBehaviorEvent} from '../behaviors'
|
|
8
10
|
import type {Editor} from '../editor'
|
|
9
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
PortableTextEditable,
|
|
13
|
+
type PortableTextEditableProps,
|
|
14
|
+
} from '../editor/Editable'
|
|
10
15
|
import type {EditorActor} from '../editor/editor-machine'
|
|
11
16
|
import {EditorProvider} from '../editor/editor-provider'
|
|
12
|
-
import type {EditorEmittedEvent} from '../editor/relay-machine'
|
|
13
17
|
import {EditorRefPlugin} from '../plugins/plugin.editor-ref'
|
|
14
|
-
import {EventListenerPlugin} from '../plugins/plugin.event-listener'
|
|
15
18
|
import {InternalEditorAfterRefPlugin} from '../plugins/plugin.internal.editor-actor-ref'
|
|
16
19
|
import {InternalSlateEditorRefPlugin} from '../plugins/plugin.internal.slate-editor-ref'
|
|
17
20
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
@@ -22,12 +25,12 @@ export async function createTestEditor(
|
|
|
22
25
|
keyGenerator?: () => string
|
|
23
26
|
schemaDefinition?: SchemaDefinition
|
|
24
27
|
children?: React.ReactNode
|
|
28
|
+
editableProps?: PortableTextEditableProps
|
|
25
29
|
} = {},
|
|
26
|
-
) {
|
|
30
|
+
): Promise<Pick<Context, 'editor' | 'locator'>> {
|
|
27
31
|
const editorRef = React.createRef<Editor>()
|
|
28
32
|
const editorActorRef = React.createRef<EditorActor>()
|
|
29
33
|
const slateRef = React.createRef<PortableTextSlateEditor>()
|
|
30
|
-
const onEvent = vi.fn<() => EditorEmittedEvent>()
|
|
31
34
|
const keyGenerator = options.keyGenerator ?? createTestKeyGenerator()
|
|
32
35
|
|
|
33
36
|
render(
|
|
@@ -41,8 +44,7 @@ export async function createTestEditor(
|
|
|
41
44
|
<EditorRefPlugin ref={editorRef} />
|
|
42
45
|
<InternalEditorAfterRefPlugin ref={editorActorRef} />
|
|
43
46
|
<InternalSlateEditorRefPlugin ref={slateRef} />
|
|
44
|
-
<
|
|
45
|
-
<PortableTextEditable />
|
|
47
|
+
<PortableTextEditable {...options.editableProps} />
|
|
46
48
|
{options.children}
|
|
47
49
|
</EditorProvider>,
|
|
48
50
|
)
|
|
@@ -51,27 +53,19 @@ export async function createTestEditor(
|
|
|
51
53
|
|
|
52
54
|
await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
|
|
53
55
|
|
|
54
|
-
function
|
|
56
|
+
function sendNativeEvent(event: NativeBehaviorEvent) {
|
|
55
57
|
editorActorRef.current?.send({
|
|
56
58
|
type: 'behavior event',
|
|
57
|
-
behaviorEvent:
|
|
58
|
-
type: 'clipboard.paste',
|
|
59
|
-
originEvent: {dataTransfer},
|
|
60
|
-
position: {
|
|
61
|
-
selection: editorRef.current?.getSnapshot().context.selection!,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
59
|
+
behaviorEvent: event,
|
|
64
60
|
editor: slateRef.current!,
|
|
65
61
|
})
|
|
66
62
|
}
|
|
67
63
|
|
|
68
64
|
return {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
editor: {
|
|
66
|
+
...editorRef.current!,
|
|
67
|
+
sendNativeEvent,
|
|
68
|
+
},
|
|
72
69
|
locator,
|
|
73
|
-
onEvent,
|
|
74
|
-
slateRef,
|
|
75
|
-
paste,
|
|
76
70
|
}
|
|
77
71
|
}
|
|
@@ -31,7 +31,7 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
|
|
|
31
31
|
...operation.annotation.value,
|
|
32
32
|
},
|
|
33
33
|
context,
|
|
34
|
-
options: {
|
|
34
|
+
options: {validateFields: true},
|
|
35
35
|
})
|
|
36
36
|
|
|
37
37
|
if (!parsedAnnotation) {
|
|
@@ -116,22 +116,11 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
const marks = span.marks ?? []
|
|
119
|
-
const existingSameTypeAnnotations = marks.filter((mark) =>
|
|
120
|
-
markDefs.some(
|
|
121
|
-
(markDef) =>
|
|
122
|
-
markDef._key === mark && markDef._type === parsedAnnotation._type,
|
|
123
|
-
),
|
|
124
|
-
)
|
|
125
119
|
|
|
126
120
|
Transforms.setNodes(
|
|
127
121
|
editor,
|
|
128
122
|
{
|
|
129
|
-
marks: [
|
|
130
|
-
...marks.filter(
|
|
131
|
-
(mark) => !existingSameTypeAnnotations.includes(mark),
|
|
132
|
-
),
|
|
133
|
-
annotationKey,
|
|
134
|
-
],
|
|
123
|
+
marks: [...marks, annotationKey],
|
|
135
124
|
},
|
|
136
125
|
{at: path},
|
|
137
126
|
)
|
|
@@ -51,7 +51,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
|
|
|
51
51
|
const updatedTextBlock = parseBlock({
|
|
52
52
|
context,
|
|
53
53
|
block: omit(parsedBlock, propsToRemove),
|
|
54
|
-
options: {
|
|
54
|
+
options: {validateFields: true},
|
|
55
55
|
})
|
|
56
56
|
|
|
57
57
|
if (!updatedTextBlock) {
|
|
@@ -81,7 +81,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
|
|
|
81
81
|
parsedBlock,
|
|
82
82
|
operation.props.filter((prop) => prop !== '_type'),
|
|
83
83
|
),
|
|
84
|
-
options: {
|
|
84
|
+
options: {validateFields: true},
|
|
85
85
|
})
|
|
86
86
|
|
|
87
87
|
if (!updatedBlockObject) {
|
|
@@ -24,7 +24,7 @@ export const insertBlockOperationImplementation: BehaviorOperationImplementation
|
|
|
24
24
|
const parsedBlock = parseBlock({
|
|
25
25
|
block: operation.block,
|
|
26
26
|
context,
|
|
27
|
-
options: {
|
|
27
|
+
options: {validateFields: true},
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
if (!parsedBlock) {
|
|
@@ -18,8 +18,6 @@ import {childSetOperationImplementation} from './behavior.operation.child.set'
|
|
|
18
18
|
import {childUnsetOperationImplementation} from './behavior.operation.child.unset'
|
|
19
19
|
import {decoratorAddOperationImplementation} from './behavior.operation.decorator.add'
|
|
20
20
|
import {deleteOperationImplementation} from './behavior.operation.delete'
|
|
21
|
-
import {insertInlineObjectOperationImplementation} from './behavior.operation.insert-inline-object'
|
|
22
|
-
import {insertSpanOperationImplementation} from './behavior.operation.insert-span'
|
|
23
21
|
import {insertBlockOperationImplementation} from './behavior.operation.insert.block'
|
|
24
22
|
import {insertTextOperationImplementation} from './behavior.operation.insert.text'
|
|
25
23
|
import {moveBackwardOperationImplementation} from './behavior.operation.move.backward'
|
|
@@ -68,8 +66,6 @@ const behaviorOperationImplementations: BehaviorOperationImplementations = {
|
|
|
68
66
|
'history.redo': historyRedoOperationImplementation,
|
|
69
67
|
'history.undo': historyUndoOperationImplementation,
|
|
70
68
|
'insert.block': insertBlockOperationImplementation,
|
|
71
|
-
'insert.inline object': insertInlineObjectOperationImplementation,
|
|
72
|
-
'insert.span': insertSpanOperationImplementation,
|
|
73
69
|
'insert.text': insertTextOperationImplementation,
|
|
74
70
|
'move.backward': moveBackwardOperationImplementation,
|
|
75
71
|
'move.block': moveBlockOperationImplementation,
|
|
@@ -170,20 +166,6 @@ export function performOperation({
|
|
|
170
166
|
})
|
|
171
167
|
break
|
|
172
168
|
}
|
|
173
|
-
case 'insert.inline object': {
|
|
174
|
-
behaviorOperationImplementations['insert.inline object']({
|
|
175
|
-
context,
|
|
176
|
-
operation: operation,
|
|
177
|
-
})
|
|
178
|
-
break
|
|
179
|
-
}
|
|
180
|
-
case 'insert.span': {
|
|
181
|
-
behaviorOperationImplementations['insert.span']({
|
|
182
|
-
context,
|
|
183
|
-
operation: operation,
|
|
184
|
-
})
|
|
185
|
-
break
|
|
186
|
-
}
|
|
187
169
|
case 'insert.text': {
|
|
188
170
|
behaviorOperationImplementations['insert.text']({
|
|
189
171
|
context,
|
|
@@ -1,117 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {page, userEvent} from '@vitest/browser/context'
|
|
4
|
-
import React from 'react'
|
|
1
|
+
import {getTersePt} from '@portabletext/test'
|
|
2
|
+
import {userEvent} from '@vitest/browser/context'
|
|
5
3
|
import {describe, expect, test, vi} from 'vitest'
|
|
6
|
-
import {
|
|
7
|
-
import {EditorProvider, PortableTextEditable, type Editor} from '..'
|
|
8
|
-
import {EditorRefPlugin} from './plugin.editor-ref'
|
|
4
|
+
import {createTestEditor} from '../internal-utils/test-editor'
|
|
9
5
|
import {AutoCloseBracketsPlugin} from './plugin.internal.auto-close-brackets'
|
|
10
6
|
|
|
11
7
|
describe(AutoCloseBracketsPlugin.name, () => {
|
|
12
8
|
test('One-character text insertion', async () => {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
initialConfig={{
|
|
18
|
-
keyGenerator: createTestKeyGenerator(),
|
|
19
|
-
schemaDefinition: defineSchema({}),
|
|
20
|
-
}}
|
|
21
|
-
>
|
|
22
|
-
<EditorRefPlugin ref={editorRef} />
|
|
23
|
-
<PortableTextEditable />
|
|
24
|
-
<AutoCloseBracketsPlugin />
|
|
25
|
-
</EditorProvider>,
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
const locator = page.getByRole('textbox')
|
|
29
|
-
await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
|
|
9
|
+
const {editor, locator} = await createTestEditor({
|
|
10
|
+
children: <AutoCloseBracketsPlugin />,
|
|
11
|
+
})
|
|
12
|
+
|
|
30
13
|
await userEvent.click(locator)
|
|
31
14
|
|
|
32
|
-
|
|
15
|
+
editor.send({type: 'insert.text', text: '('})
|
|
33
16
|
|
|
34
17
|
await vi.waitFor(() => {
|
|
35
|
-
expect(getTersePt(
|
|
36
|
-
'()',
|
|
37
|
-
])
|
|
18
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['()'])
|
|
38
19
|
})
|
|
39
20
|
|
|
40
21
|
await userEvent.type(locator, 'foo')
|
|
41
22
|
|
|
42
23
|
await vi.waitFor(() => {
|
|
43
|
-
expect(getTersePt(
|
|
44
|
-
'(foo)',
|
|
45
|
-
])
|
|
24
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['(foo)'])
|
|
46
25
|
})
|
|
47
26
|
|
|
48
|
-
|
|
27
|
+
editor.send({type: 'history.undo'})
|
|
49
28
|
|
|
50
29
|
await vi.waitFor(() => {
|
|
51
|
-
expect(getTersePt(
|
|
52
|
-
'()',
|
|
53
|
-
])
|
|
30
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['()'])
|
|
54
31
|
})
|
|
55
32
|
|
|
56
|
-
|
|
33
|
+
editor.send({type: 'history.undo'})
|
|
57
34
|
|
|
58
35
|
await vi.waitFor(() => {
|
|
59
|
-
expect(getTersePt(
|
|
60
|
-
'(',
|
|
61
|
-
])
|
|
36
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['('])
|
|
62
37
|
})
|
|
63
38
|
})
|
|
64
39
|
|
|
65
40
|
test('Two-character text insertion', async () => {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
initialConfig={{
|
|
71
|
-
keyGenerator: createTestKeyGenerator(),
|
|
72
|
-
schemaDefinition: defineSchema({}),
|
|
73
|
-
}}
|
|
74
|
-
>
|
|
75
|
-
<EditorRefPlugin ref={editorRef} />
|
|
76
|
-
<PortableTextEditable />
|
|
77
|
-
<AutoCloseBracketsPlugin />
|
|
78
|
-
</EditorProvider>,
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
const locator = page.getByRole('textbox')
|
|
82
|
-
await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
|
|
41
|
+
const {editor, locator} = await createTestEditor({
|
|
42
|
+
children: <AutoCloseBracketsPlugin />,
|
|
43
|
+
})
|
|
44
|
+
|
|
83
45
|
await userEvent.click(locator)
|
|
84
46
|
|
|
85
|
-
|
|
47
|
+
editor.send({type: 'insert.text', text: '(f'})
|
|
86
48
|
|
|
87
49
|
await vi.waitFor(() => {
|
|
88
|
-
expect(getTersePt(
|
|
89
|
-
'(f)',
|
|
90
|
-
])
|
|
50
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['(f)'])
|
|
91
51
|
})
|
|
92
52
|
|
|
93
53
|
await userEvent.type(locator, 'oo')
|
|
94
54
|
|
|
95
55
|
await vi.waitFor(() => {
|
|
96
|
-
expect(getTersePt(
|
|
97
|
-
'(foo)',
|
|
98
|
-
])
|
|
56
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['(foo)'])
|
|
99
57
|
})
|
|
100
58
|
|
|
101
|
-
|
|
59
|
+
editor.send({type: 'history.undo'})
|
|
102
60
|
|
|
103
61
|
await vi.waitFor(() => {
|
|
104
|
-
expect(getTersePt(
|
|
105
|
-
'(f)',
|
|
106
|
-
])
|
|
62
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['(f)'])
|
|
107
63
|
})
|
|
108
64
|
|
|
109
|
-
|
|
65
|
+
editor.send({type: 'history.undo'})
|
|
110
66
|
|
|
111
67
|
await vi.waitFor(() => {
|
|
112
|
-
expect(getTersePt(
|
|
113
|
-
'(f',
|
|
114
|
-
])
|
|
68
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['(f'])
|
|
115
69
|
})
|
|
116
70
|
})
|
|
117
71
|
})
|
|
@@ -1,58 +1,40 @@
|
|
|
1
1
|
import {defineSchema} from '@portabletext/schema'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import React from 'react'
|
|
2
|
+
import {getTersePt} from '@portabletext/test'
|
|
3
|
+
import {userEvent} from '@vitest/browser/context'
|
|
5
4
|
import {describe, expect, test, vi} from 'vitest'
|
|
6
|
-
import {
|
|
7
|
-
import {PortableTextEditable, type Editor} from '..'
|
|
8
|
-
import {EditorProvider} from '../editor/editor-provider'
|
|
5
|
+
import {createTestEditor} from '../internal-utils/test-editor'
|
|
9
6
|
import {getTextMarks} from '../internal-utils/text-marks'
|
|
10
|
-
import {EditorRefPlugin} from './plugin.editor-ref'
|
|
11
7
|
import {MarkdownPlugin} from './plugin.markdown'
|
|
12
8
|
|
|
13
9
|
describe(MarkdownPlugin.name, () => {
|
|
14
10
|
test('Scenario: Undoing bold shortcut', async () => {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
render(
|
|
18
|
-
<EditorProvider
|
|
19
|
-
initialConfig={{
|
|
20
|
-
keyGenerator: createTestKeyGenerator(),
|
|
21
|
-
schemaDefinition: defineSchema({decorators: [{name: 'strong'}]}),
|
|
22
|
-
}}
|
|
23
|
-
>
|
|
24
|
-
<EditorRefPlugin ref={editorRef} />
|
|
25
|
-
<PortableTextEditable />
|
|
11
|
+
const {editor, locator} = await createTestEditor({
|
|
12
|
+
children: (
|
|
26
13
|
<MarkdownPlugin
|
|
27
14
|
config={{
|
|
28
15
|
boldDecorator: () => 'strong',
|
|
29
16
|
}}
|
|
30
17
|
/>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const locator = page.getByRole('textbox')
|
|
35
|
-
|
|
36
|
-
await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
|
|
18
|
+
),
|
|
19
|
+
schemaDefinition: defineSchema({decorators: [{name: 'strong'}]}),
|
|
20
|
+
})
|
|
37
21
|
|
|
38
22
|
await userEvent.type(locator, '**Hello world!**')
|
|
39
23
|
|
|
40
24
|
await vi.waitFor(() => {
|
|
41
|
-
expect(getTersePt(
|
|
42
|
-
'Hello world!',
|
|
43
|
-
])
|
|
25
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual(['Hello world!'])
|
|
44
26
|
})
|
|
45
27
|
|
|
46
28
|
await vi.waitFor(() => {
|
|
47
29
|
expect(
|
|
48
|
-
getTextMarks(
|
|
30
|
+
getTextMarks(editor.getSnapshot().context, 'Hello world!'),
|
|
49
31
|
).toEqual(['strong'])
|
|
50
32
|
})
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
editor.send({type: 'history.undo'})
|
|
53
35
|
|
|
54
36
|
await vi.waitFor(() => {
|
|
55
|
-
expect(getTersePt(
|
|
37
|
+
expect(getTersePt(editor.getSnapshot().context)).toEqual([
|
|
56
38
|
'**Hello world!**',
|
|
57
39
|
])
|
|
58
40
|
})
|