@portabletext/editor 1.1.1 → 1.1.2
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/README.md +3 -0
- package/lib/index.d.mts +1667 -0
- package/lib/index.d.ts +1667 -0
- package/lib/index.esm.js +305 -153
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +305 -154
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +305 -153
- package/lib/index.mjs.map +1 -1
- package/package.json +23 -22
- package/src/editor/Editable.tsx +30 -31
- package/src/editor/PortableTextEditor.tsx +23 -6
- package/src/editor/__tests__/PortableTextEditor.test.tsx +9 -9
- package/src/editor/__tests__/PortableTextEditorTester.tsx +2 -5
- package/src/editor/__tests__/RangeDecorations.test.tsx +2 -2
- package/src/editor/__tests__/handleClick.test.tsx +27 -7
- package/src/editor/__tests__/insert-block.test.tsx +4 -4
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +7 -7
- package/src/editor/__tests__/self-solving.test.tsx +176 -0
- package/src/editor/components/Leaf.tsx +28 -23
- package/src/editor/components/Synchronizer.tsx +60 -32
- package/src/editor/editor-machine.ts +195 -0
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +11 -13
- package/src/editor/hooks/useSyncValue.test.tsx +9 -9
- package/src/editor/hooks/useSyncValue.ts +14 -13
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +1 -1
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +28 -28
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +17 -17
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +8 -8
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +5 -5
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +2 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +46 -46
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +22 -11
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +9 -9
- package/src/editor/plugins/createWithInsertData.ts +4 -8
- package/src/editor/plugins/createWithObjectKeys.ts +7 -0
- package/src/editor/plugins/createWithPatches.ts +5 -6
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +10 -2
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +20 -4
- package/src/editor/plugins/createWithPortableTextSelections.ts +4 -5
- package/src/editor/plugins/createWithSchemaTypes.ts +9 -0
- package/src/editor/plugins/index.ts +18 -8
- package/src/index.ts +9 -3
- package/src/utils/__tests__/dmpToOperations.test.ts +1 -1
- package/src/utils/__tests__/operationToPatches.test.ts +61 -61
- package/src/utils/__tests__/patchToOperations.test.ts +39 -39
- package/src/utils/__tests__/ranges.test.ts +1 -1
- package/src/utils/__tests__/valueNormalization.test.tsx +14 -2
- package/src/utils/__tests__/values.test.ts +17 -17
- package/src/utils/validateValue.ts +0 -22
- package/src/editor/__tests__/utils.ts +0 -44
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
1
|
import {render, waitFor} from '@testing-library/react'
|
|
3
2
|
import {createRef, type RefObject} from 'react'
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest'
|
|
4
4
|
import {
|
|
5
5
|
PortableTextEditorTester,
|
|
6
6
|
schemaType,
|
|
@@ -29,7 +29,7 @@ describe('plugin:withPortableTextMarksModel', () => {
|
|
|
29
29
|
style: 'normal',
|
|
30
30
|
},
|
|
31
31
|
]
|
|
32
|
-
const onChange =
|
|
32
|
+
const onChange = vi.fn()
|
|
33
33
|
await waitFor(() => {
|
|
34
34
|
render(
|
|
35
35
|
<PortableTextEditorTester
|
|
@@ -50,21 +50,21 @@ describe('plugin:withPortableTextMarksModel', () => {
|
|
|
50
50
|
})
|
|
51
51
|
PortableTextEditor.toggleMark(editor, 'strong')
|
|
52
52
|
expect(PortableTextEditor.getValue(editor)).toMatchInlineSnapshot(`
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
[
|
|
54
|
+
{
|
|
55
55
|
"_key": "a",
|
|
56
56
|
"_type": "myTestBlockType",
|
|
57
|
-
"children":
|
|
58
|
-
|
|
57
|
+
"children": [
|
|
58
|
+
{
|
|
59
59
|
"_key": "a1",
|
|
60
60
|
"_type": "span",
|
|
61
|
-
"marks":
|
|
61
|
+
"marks": [
|
|
62
62
|
"strong",
|
|
63
63
|
],
|
|
64
64
|
"text": "1234",
|
|
65
65
|
},
|
|
66
66
|
],
|
|
67
|
-
"markDefs":
|
|
67
|
+
"markDefs": [],
|
|
68
68
|
"style": "normal",
|
|
69
69
|
},
|
|
70
70
|
]
|
|
@@ -79,35 +79,35 @@ describe('plugin:withPortableTextMarksModel', () => {
|
|
|
79
79
|
PortableTextEditor.toggleMark(editorRef.current, 'strong')
|
|
80
80
|
expect(PortableTextEditor.getValue(editorRef.current))
|
|
81
81
|
.toMatchInlineSnapshot(`
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
[
|
|
83
|
+
{
|
|
84
84
|
"_key": "a",
|
|
85
85
|
"_type": "myTestBlockType",
|
|
86
|
-
"children":
|
|
87
|
-
|
|
86
|
+
"children": [
|
|
87
|
+
{
|
|
88
88
|
"_key": "a1",
|
|
89
89
|
"_type": "span",
|
|
90
|
-
"marks":
|
|
90
|
+
"marks": [
|
|
91
91
|
"strong",
|
|
92
92
|
],
|
|
93
93
|
"text": "1",
|
|
94
94
|
},
|
|
95
|
-
|
|
95
|
+
{
|
|
96
96
|
"_key": "2",
|
|
97
97
|
"_type": "span",
|
|
98
|
-
"marks":
|
|
98
|
+
"marks": [],
|
|
99
99
|
"text": "23",
|
|
100
100
|
},
|
|
101
|
-
|
|
101
|
+
{
|
|
102
102
|
"_key": "1",
|
|
103
103
|
"_type": "span",
|
|
104
|
-
"marks":
|
|
104
|
+
"marks": [
|
|
105
105
|
"strong",
|
|
106
106
|
],
|
|
107
107
|
"text": "4",
|
|
108
108
|
},
|
|
109
109
|
],
|
|
110
|
-
"markDefs":
|
|
110
|
+
"markDefs": [],
|
|
111
111
|
"style": "normal",
|
|
112
112
|
},
|
|
113
113
|
]
|
|
@@ -122,21 +122,21 @@ describe('plugin:withPortableTextMarksModel', () => {
|
|
|
122
122
|
})
|
|
123
123
|
PortableTextEditor.toggleMark(editor, 'strong')
|
|
124
124
|
expect(PortableTextEditor.getValue(editor)).toMatchInlineSnapshot(`
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
[
|
|
126
|
+
{
|
|
127
127
|
"_key": "a",
|
|
128
128
|
"_type": "myTestBlockType",
|
|
129
|
-
"children":
|
|
130
|
-
|
|
129
|
+
"children": [
|
|
130
|
+
{
|
|
131
131
|
"_key": "a1",
|
|
132
132
|
"_type": "span",
|
|
133
|
-
"marks":
|
|
133
|
+
"marks": [
|
|
134
134
|
"strong",
|
|
135
135
|
],
|
|
136
136
|
"text": "1234",
|
|
137
137
|
},
|
|
138
138
|
],
|
|
139
|
-
"markDefs":
|
|
139
|
+
"markDefs": [],
|
|
140
140
|
"style": "normal",
|
|
141
141
|
},
|
|
142
142
|
]
|
|
@@ -175,7 +175,7 @@ Array [
|
|
|
175
175
|
style: 'normal',
|
|
176
176
|
},
|
|
177
177
|
]
|
|
178
|
-
const onChange =
|
|
178
|
+
const onChange = vi.fn()
|
|
179
179
|
|
|
180
180
|
render(
|
|
181
181
|
<PortableTextEditorTester
|
|
@@ -307,7 +307,7 @@ Array [
|
|
|
307
307
|
offset: 0,
|
|
308
308
|
},
|
|
309
309
|
}
|
|
310
|
-
const onChange =
|
|
310
|
+
const onChange = vi.fn()
|
|
311
311
|
await waitFor(() => {
|
|
312
312
|
render(
|
|
313
313
|
<PortableTextEditorTester
|
|
@@ -324,47 +324,47 @@ Array [
|
|
|
324
324
|
PortableTextEditor.select(editor, sel)
|
|
325
325
|
PortableTextEditor.delete(editor, sel)
|
|
326
326
|
expect(PortableTextEditor.getValue(editor)).toMatchInlineSnapshot(`
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
[
|
|
328
|
+
{
|
|
329
329
|
"_key": "5fc57af23597",
|
|
330
330
|
"_type": "myTestBlockType",
|
|
331
|
-
"children":
|
|
332
|
-
|
|
331
|
+
"children": [
|
|
332
|
+
{
|
|
333
333
|
"_key": "be1c67c6971a",
|
|
334
334
|
"_type": "span",
|
|
335
|
-
"marks":
|
|
335
|
+
"marks": [],
|
|
336
336
|
"text": "This is a ",
|
|
337
337
|
},
|
|
338
|
-
|
|
338
|
+
{
|
|
339
339
|
"_key": "11c8c9f783a8",
|
|
340
340
|
"_type": "span",
|
|
341
|
-
"marks":
|
|
341
|
+
"marks": [
|
|
342
342
|
"fde1fd54b544",
|
|
343
343
|
],
|
|
344
344
|
"text": "link",
|
|
345
345
|
},
|
|
346
|
-
|
|
346
|
+
{
|
|
347
347
|
"_key": "576c748e0cd2",
|
|
348
348
|
"_type": "span",
|
|
349
|
-
"marks":
|
|
349
|
+
"marks": [],
|
|
350
350
|
"text": "This is ",
|
|
351
351
|
},
|
|
352
|
-
|
|
352
|
+
{
|
|
353
353
|
"_key": "f3d73d3833bf",
|
|
354
354
|
"_type": "span",
|
|
355
|
-
"marks":
|
|
355
|
+
"marks": [
|
|
356
356
|
"7b6d3d5de30c",
|
|
357
357
|
],
|
|
358
358
|
"text": "another",
|
|
359
359
|
},
|
|
360
360
|
],
|
|
361
|
-
"markDefs":
|
|
362
|
-
|
|
361
|
+
"markDefs": [
|
|
362
|
+
{
|
|
363
363
|
"_key": "fde1fd54b544",
|
|
364
364
|
"_type": "link",
|
|
365
365
|
"url": "1",
|
|
366
366
|
},
|
|
367
|
-
|
|
367
|
+
{
|
|
368
368
|
"_key": "7b6d3d5de30c",
|
|
369
369
|
"_type": "link",
|
|
370
370
|
"url": "2",
|
|
@@ -419,7 +419,7 @@ Array [
|
|
|
419
419
|
focus: {path: [{_key: 'bb'}, 'children', {_key: 'sb'}], offset: 0},
|
|
420
420
|
anchor: {path: [{_key: 'bb'}, 'children', {_key: 'sb'}], offset: 0},
|
|
421
421
|
}
|
|
422
|
-
const onChange =
|
|
422
|
+
const onChange = vi.fn()
|
|
423
423
|
|
|
424
424
|
render(
|
|
425
425
|
<PortableTextEditorTester
|
|
@@ -522,7 +522,7 @@ Array [
|
|
|
522
522
|
style: 'normal',
|
|
523
523
|
},
|
|
524
524
|
]
|
|
525
|
-
const onChange =
|
|
525
|
+
const onChange = vi.fn()
|
|
526
526
|
|
|
527
527
|
render(
|
|
528
528
|
<PortableTextEditorTester
|
|
@@ -592,7 +592,7 @@ Array [
|
|
|
592
592
|
style: 'normal',
|
|
593
593
|
},
|
|
594
594
|
]
|
|
595
|
-
const onChange =
|
|
595
|
+
const onChange = vi.fn()
|
|
596
596
|
await waitFor(() => {
|
|
597
597
|
render(
|
|
598
598
|
<PortableTextEditorTester
|
|
@@ -647,7 +647,7 @@ Array [
|
|
|
647
647
|
style: 'normal',
|
|
648
648
|
},
|
|
649
649
|
]
|
|
650
|
-
const onChange =
|
|
650
|
+
const onChange = vi.fn()
|
|
651
651
|
await waitFor(() => {
|
|
652
652
|
render(
|
|
653
653
|
<PortableTextEditorTester
|
|
@@ -703,7 +703,7 @@ Array [
|
|
|
703
703
|
style: 'normal',
|
|
704
704
|
},
|
|
705
705
|
]
|
|
706
|
-
const onChange =
|
|
706
|
+
const onChange = vi.fn()
|
|
707
707
|
await waitFor(() => {
|
|
708
708
|
render(
|
|
709
709
|
<PortableTextEditorTester
|
|
@@ -859,7 +859,7 @@ Array [
|
|
|
859
859
|
],
|
|
860
860
|
},
|
|
861
861
|
]
|
|
862
|
-
const onChange =
|
|
862
|
+
const onChange = vi.fn()
|
|
863
863
|
await waitFor(() => {
|
|
864
864
|
render(
|
|
865
865
|
<PortableTextEditorTester
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
1
|
import {render, waitFor} from '@testing-library/react'
|
|
3
2
|
import {createRef, type RefObject} from 'react'
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest'
|
|
4
4
|
import {
|
|
5
5
|
PortableTextEditorTester,
|
|
6
6
|
schemaType,
|
|
@@ -41,7 +41,7 @@ const initialValue = [
|
|
|
41
41
|
describe('plugin:withPortableTextSelections', () => {
|
|
42
42
|
it('will report that a selection is made backward', async () => {
|
|
43
43
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
44
|
-
const onChange =
|
|
44
|
+
const onChange = vi.fn()
|
|
45
45
|
render(
|
|
46
46
|
<PortableTextEditorTester
|
|
47
47
|
onChange={onChange}
|
|
@@ -54,34 +54,45 @@ describe('plugin:withPortableTextSelections', () => {
|
|
|
54
54
|
anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 9},
|
|
55
55
|
focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 7},
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
await waitFor(() => {
|
|
59
|
+
if (editorRef.current) {
|
|
60
|
+
expect(onChange).toHaveBeenCalledWith({
|
|
61
|
+
type: 'value',
|
|
62
|
+
value: initialValue,
|
|
63
|
+
})
|
|
64
|
+
expect(onChange).toHaveBeenCalledWith({type: 'ready'})
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
57
68
|
await waitFor(() => {
|
|
58
69
|
if (editorRef.current) {
|
|
59
70
|
PortableTextEditor.focus(editorRef.current)
|
|
60
71
|
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
61
72
|
expect(PortableTextEditor.getSelection(editorRef.current))
|
|
62
73
|
.toMatchInlineSnapshot(`
|
|
63
|
-
|
|
64
|
-
"anchor":
|
|
74
|
+
{
|
|
75
|
+
"anchor": {
|
|
65
76
|
"offset": 9,
|
|
66
|
-
"path":
|
|
67
|
-
|
|
77
|
+
"path": [
|
|
78
|
+
{
|
|
68
79
|
"_key": "b",
|
|
69
80
|
},
|
|
70
81
|
"children",
|
|
71
|
-
|
|
82
|
+
{
|
|
72
83
|
"_key": "b1",
|
|
73
84
|
},
|
|
74
85
|
],
|
|
75
86
|
},
|
|
76
87
|
"backward": true,
|
|
77
|
-
"focus":
|
|
88
|
+
"focus": {
|
|
78
89
|
"offset": 7,
|
|
79
|
-
"path":
|
|
80
|
-
|
|
90
|
+
"path": [
|
|
91
|
+
{
|
|
81
92
|
"_key": "a",
|
|
82
93
|
},
|
|
83
94
|
"children",
|
|
84
|
-
|
|
95
|
+
{
|
|
85
96
|
"_key": "a1",
|
|
86
97
|
},
|
|
87
98
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
1
|
import {render, waitFor} from '@testing-library/react'
|
|
3
2
|
import {createRef, type RefObject} from 'react'
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest'
|
|
4
4
|
import {
|
|
5
5
|
PortableTextEditorTester,
|
|
6
6
|
schemaType,
|
|
@@ -46,7 +46,7 @@ const initialSelection = {
|
|
|
46
46
|
describe('plugin:withUndoRedo', () => {
|
|
47
47
|
it('preserves the keys when undoing ', async () => {
|
|
48
48
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
49
|
-
const onChange =
|
|
49
|
+
const onChange = vi.fn()
|
|
50
50
|
render(
|
|
51
51
|
<PortableTextEditorTester
|
|
52
52
|
onChange={onChange}
|
|
@@ -77,19 +77,19 @@ describe('plugin:withUndoRedo', () => {
|
|
|
77
77
|
)
|
|
78
78
|
expect(PortableTextEditor.getValue(editorRef.current))
|
|
79
79
|
.toMatchInlineSnapshot(`
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
[
|
|
81
|
+
{
|
|
82
82
|
"_key": "a",
|
|
83
83
|
"_type": "myTestBlockType",
|
|
84
|
-
"children":
|
|
85
|
-
|
|
84
|
+
"children": [
|
|
85
|
+
{
|
|
86
86
|
"_key": "a1",
|
|
87
87
|
"_type": "span",
|
|
88
|
-
"marks":
|
|
88
|
+
"marks": [],
|
|
89
89
|
"text": "Block A",
|
|
90
90
|
},
|
|
91
91
|
],
|
|
92
|
-
"markDefs":
|
|
92
|
+
"markDefs": [],
|
|
93
93
|
"style": "normal",
|
|
94
94
|
},
|
|
95
95
|
]
|
|
@@ -103,7 +103,7 @@ describe('plugin:withUndoRedo', () => {
|
|
|
103
103
|
})
|
|
104
104
|
it('preserves the keys when redoing ', async () => {
|
|
105
105
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
106
|
-
const onChange =
|
|
106
|
+
const onChange = vi.fn()
|
|
107
107
|
|
|
108
108
|
render(
|
|
109
109
|
<PortableTextEditorTester
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isEqualToEmptyEditor,
|
|
16
16
|
toSlateValue,
|
|
17
17
|
} from '../../utils/values'
|
|
18
|
+
import type {EditorActor} from '../editor-machine'
|
|
18
19
|
|
|
19
20
|
const debug = debugWithName('plugin:withInsertData')
|
|
20
21
|
|
|
@@ -23,7 +24,7 @@ const debug = debugWithName('plugin:withInsertData')
|
|
|
23
24
|
*
|
|
24
25
|
*/
|
|
25
26
|
export function createWithInsertData(
|
|
26
|
-
|
|
27
|
+
editorActor: EditorActor,
|
|
27
28
|
schemaTypes: PortableTextMemberSchemaTypes,
|
|
28
29
|
keyGenerator: () => string,
|
|
29
30
|
) {
|
|
@@ -158,9 +159,8 @@ export function createWithInsertData(
|
|
|
158
159
|
// Bail out if it's not valid
|
|
159
160
|
if (!validation.valid && !validation.resolution?.autoResolve) {
|
|
160
161
|
const errorDescription = `${validation.resolution?.description}`
|
|
161
|
-
|
|
162
|
+
editorActor.send({
|
|
162
163
|
type: 'error',
|
|
163
|
-
level: 'warning',
|
|
164
164
|
name: 'pasteError',
|
|
165
165
|
description: errorDescription,
|
|
166
166
|
data: validation,
|
|
@@ -180,7 +180,6 @@ export function createWithInsertData(
|
|
|
180
180
|
debug('No selection, not inserting')
|
|
181
181
|
return false
|
|
182
182
|
}
|
|
183
|
-
change$.next({type: 'loading', isLoading: true}) // This could potentially take some time
|
|
184
183
|
const html = data.getData('text/html')
|
|
185
184
|
const text = data.getData('text/plain')
|
|
186
185
|
|
|
@@ -232,9 +231,8 @@ export function createWithInsertData(
|
|
|
232
231
|
// Bail out if it's not valid
|
|
233
232
|
if (!validation.valid) {
|
|
234
233
|
const errorDescription = `Could not validate the resulting portable text to insert.\n${validation.resolution?.description}\nTry to insert as plain text (shift-paste) instead.`
|
|
235
|
-
|
|
234
|
+
editorActor.send({
|
|
236
235
|
type: 'error',
|
|
237
|
-
level: 'warning',
|
|
238
236
|
name: 'pasteError',
|
|
239
237
|
description: errorDescription,
|
|
240
238
|
data: validation,
|
|
@@ -246,10 +244,8 @@ export function createWithInsertData(
|
|
|
246
244
|
`Inserting ${insertedType} fragment at ${JSON.stringify(editor.selection)}`,
|
|
247
245
|
)
|
|
248
246
|
_insertFragment(editor, fragment, schemaTypes)
|
|
249
|
-
change$.next({type: 'loading', isLoading: false})
|
|
250
247
|
return true
|
|
251
248
|
}
|
|
252
|
-
change$.next({type: 'loading', isLoading: false})
|
|
253
249
|
return false
|
|
254
250
|
}
|
|
255
251
|
|
|
@@ -5,12 +5,14 @@ import type {
|
|
|
5
5
|
} from '../../types/editor'
|
|
6
6
|
import {isChangingRemotely} from '../../utils/withChanges'
|
|
7
7
|
import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
|
|
8
|
+
import type {EditorActor} from '../editor-machine'
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* This plugin makes sure that every new node in the editor get a new _key prop when created
|
|
11
12
|
*
|
|
12
13
|
*/
|
|
13
14
|
export function createWithObjectKeys(
|
|
15
|
+
editorActor: EditorActor,
|
|
14
16
|
schemaTypes: PortableTextMemberSchemaTypes,
|
|
15
17
|
keyGenerator: () => string,
|
|
16
18
|
) {
|
|
@@ -75,12 +77,17 @@ export function createWithObjectKeys(
|
|
|
75
77
|
if (Element.isElement(node) && node._type === schemaTypes.block.name) {
|
|
76
78
|
// Set key on block itself
|
|
77
79
|
if (!node._key) {
|
|
80
|
+
editorActor.send({type: 'normalizing'})
|
|
78
81
|
Transforms.setNodes(editor, {_key: keyGenerator()}, {at: path})
|
|
82
|
+
editorActor.send({type: 'done normalizing'})
|
|
83
|
+
return
|
|
79
84
|
}
|
|
80
85
|
// Set keys on it's children
|
|
81
86
|
for (const [child, childPath] of Node.children(editor, path)) {
|
|
82
87
|
if (!child._key) {
|
|
88
|
+
editorActor.send({type: 'normalizing'})
|
|
83
89
|
Transforms.setNodes(editor, {_key: keyGenerator()}, {at: childPath})
|
|
90
|
+
editorActor.send({type: 'done normalizing'})
|
|
84
91
|
return
|
|
85
92
|
}
|
|
86
93
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {insert, setIfMissing, unset, type Patch} from '@portabletext/patches'
|
|
2
|
-
import type {Subject} from 'rxjs'
|
|
3
2
|
import {
|
|
4
3
|
Editor,
|
|
5
4
|
type Descendant,
|
|
@@ -14,7 +13,6 @@ import {
|
|
|
14
13
|
type SplitNodeOperation,
|
|
15
14
|
} from 'slate'
|
|
16
15
|
import type {
|
|
17
|
-
EditorChange,
|
|
18
16
|
PatchObservable,
|
|
19
17
|
PortableTextMemberSchemaTypes,
|
|
20
18
|
PortableTextSlateEditor,
|
|
@@ -32,6 +30,7 @@ import {
|
|
|
32
30
|
PATCHING,
|
|
33
31
|
withoutPatching,
|
|
34
32
|
} from '../../utils/withoutPatching'
|
|
33
|
+
import type {EditorActor} from '../editor-machine'
|
|
35
34
|
import {withoutSaving} from './createWithUndoRedo'
|
|
36
35
|
|
|
37
36
|
const debug = debugWithName('plugin:withPatches')
|
|
@@ -81,7 +80,7 @@ export interface PatchFunctions {
|
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
interface Options {
|
|
84
|
-
|
|
83
|
+
editorActor: EditorActor
|
|
85
84
|
keyGenerator: () => string
|
|
86
85
|
patches$?: PatchObservable
|
|
87
86
|
patchFunctions: PatchFunctions
|
|
@@ -90,7 +89,7 @@ interface Options {
|
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
export function createWithPatches({
|
|
93
|
-
|
|
92
|
+
editorActor,
|
|
94
93
|
patches$,
|
|
95
94
|
patchFunctions,
|
|
96
95
|
readOnly,
|
|
@@ -281,7 +280,7 @@ export function createWithPatches({
|
|
|
281
280
|
)
|
|
282
281
|
) {
|
|
283
282
|
patches = [...patches, unset([])]
|
|
284
|
-
|
|
283
|
+
editorActor.send({
|
|
285
284
|
type: 'unset',
|
|
286
285
|
previousValue: fromSlateValue(
|
|
287
286
|
previousChildren,
|
|
@@ -299,7 +298,7 @@ export function createWithPatches({
|
|
|
299
298
|
// Emit all patches
|
|
300
299
|
if (patches.length > 0) {
|
|
301
300
|
patches.forEach((patch) => {
|
|
302
|
-
|
|
301
|
+
editorActor.send({
|
|
303
302
|
type: 'patch',
|
|
304
303
|
patch: {...patch, origin: 'local'},
|
|
305
304
|
})
|
|
@@ -4,10 +4,12 @@ import type {
|
|
|
4
4
|
PortableTextSlateEditor,
|
|
5
5
|
} from '../../types/editor'
|
|
6
6
|
import {debugWithName} from '../../utils/debug'
|
|
7
|
+
import type {EditorActor} from '../editor-machine'
|
|
7
8
|
|
|
8
9
|
const debug = debugWithName('plugin:withPortableTextBlockStyle')
|
|
9
10
|
|
|
10
11
|
export function createWithPortableTextBlockStyle(
|
|
12
|
+
editorActor: EditorActor,
|
|
11
13
|
types: PortableTextMemberSchemaTypes,
|
|
12
14
|
): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
13
15
|
const defaultStyle = types.styles[0].value
|
|
@@ -17,9 +19,10 @@ export function createWithPortableTextBlockStyle(
|
|
|
17
19
|
// Extend Slate's default normalization to reset split node to normal style
|
|
18
20
|
// if there is no text at the right end of the split.
|
|
19
21
|
const {normalizeNode} = editor
|
|
22
|
+
|
|
20
23
|
editor.normalizeNode = (nodeEntry) => {
|
|
21
|
-
normalizeNode(nodeEntry)
|
|
22
24
|
const [, path] = nodeEntry
|
|
25
|
+
|
|
23
26
|
for (const op of editor.operations) {
|
|
24
27
|
if (
|
|
25
28
|
op.type === 'split_node' &&
|
|
@@ -32,16 +35,21 @@ export function createWithPortableTextBlockStyle(
|
|
|
32
35
|
const [child] = Editor.node(editor, [op.path[0] + 1, 0])
|
|
33
36
|
if (SlateText.isText(child) && child.text === '') {
|
|
34
37
|
debug(`Normalizing split node to ${defaultStyle} style`, op)
|
|
38
|
+
editorActor.send({type: 'normalizing'})
|
|
35
39
|
Transforms.setNodes(
|
|
36
40
|
editor,
|
|
37
41
|
{style: defaultStyle},
|
|
38
42
|
{at: [op.path[0] + 1], voids: false},
|
|
39
43
|
)
|
|
40
|
-
|
|
44
|
+
editorActor.send({type: 'done normalizing'})
|
|
45
|
+
return
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
}
|
|
49
|
+
|
|
50
|
+
normalizeNode(nodeEntry)
|
|
44
51
|
}
|
|
52
|
+
|
|
45
53
|
editor.pteHasBlockStyle = (style: string): boolean => {
|
|
46
54
|
if (!editor.selection) {
|
|
47
55
|
return false
|