@portabletext/editor 3.0.6 → 3.0.8
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-dts/index.d.ts +2 -2
- package/lib/_chunks-es/util.slice-blocks.js +1 -8
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/index.js +112 -131
- package/lib/index.js.map +1 -1
- package/package.json +9 -9
- package/src/converters/converter.portable-text.deserialize.test.ts +0 -13
- package/src/editor/Editable.tsx +3 -11
- package/src/editor/create-editor.ts +1 -7
- package/src/editor/create-slate-editor.tsx +13 -13
- package/src/editor/plugins/createWithEditableAPI.ts +68 -75
- package/src/editor/plugins/createWithPatches.ts +20 -23
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +19 -0
- package/src/editor/range-decorations-machine.ts +1 -1
- package/src/editor/weakMaps.ts +0 -2
- package/src/history/slate-plugin.history.ts +1 -5
- package/src/internal-utils/__tests__/values.test.ts +1 -121
- package/src/internal-utils/applyPatch.ts +1 -1
- package/src/internal-utils/operation-to-patches.test.ts +31 -6
- package/src/internal-utils/operation-to-patches.ts +10 -16
- package/src/internal-utils/values.test.ts +0 -7
- package/src/internal-utils/values.ts +70 -34
- package/src/operations/behavior.operation.block.unset.ts +12 -36
- package/src/operations/behavior.operation.child.unset.ts +33 -15
- package/src/utils/parse-blocks.test.ts +0 -16
- package/src/utils/parse-blocks.ts +6 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.8",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@portabletext/to-html": "^4.0.1",
|
|
66
66
|
"@xstate/react": "^6.0.0",
|
|
67
67
|
"debug": "^4.4.3",
|
|
68
|
-
"immer": "^
|
|
68
|
+
"immer": "^11.0.0",
|
|
69
69
|
"lodash": "^4.17.21",
|
|
70
70
|
"lodash.startcase": "^4.4.0",
|
|
71
71
|
"react-compiler-runtime": "1.0.0",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"slate-dom": "^0.119.0",
|
|
74
74
|
"slate-react": "0.119.0",
|
|
75
75
|
"xstate": "^5.24.0",
|
|
76
|
-
"@portabletext/block-tools": "^4.1.
|
|
76
|
+
"@portabletext/block-tools": "^4.1.3",
|
|
77
77
|
"@portabletext/keyboard-shortcuts": "^2.1.0",
|
|
78
78
|
"@portabletext/patches": "^2.0.0",
|
|
79
79
|
"@portabletext/schema": "^2.0.0"
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
83
83
|
"@sanity/pkg-utils": "^9.0.3",
|
|
84
|
-
"@sanity/schema": "^4.
|
|
85
|
-
"@sanity/types": "^4.
|
|
84
|
+
"@sanity/schema": "^4.19.0",
|
|
85
|
+
"@sanity/types": "^4.19.0",
|
|
86
86
|
"@types/debug": "^4.1.12",
|
|
87
87
|
"@types/lodash": "^4.17.20",
|
|
88
88
|
"@types/lodash.startcase": "^4.4.9",
|
|
@@ -106,14 +106,14 @@
|
|
|
106
106
|
"vite": "^7.1.12",
|
|
107
107
|
"vitest": "^4.0.9",
|
|
108
108
|
"vitest-browser-react": "^2.0.2",
|
|
109
|
-
"@portabletext/sanity-bridge": "1.2.
|
|
109
|
+
"@portabletext/sanity-bridge": "1.2.6",
|
|
110
110
|
"@portabletext/test": "^1.0.0",
|
|
111
111
|
"racejar": "2.0.0"
|
|
112
112
|
},
|
|
113
113
|
"peerDependencies": {
|
|
114
|
-
"@portabletext/sanity-bridge": "^1.2.
|
|
115
|
-
"@sanity/schema": "^4.
|
|
116
|
-
"@sanity/types": "^4.
|
|
114
|
+
"@portabletext/sanity-bridge": "^1.2.6",
|
|
115
|
+
"@sanity/schema": "^4.19.0",
|
|
116
|
+
"@sanity/types": "^4.19.0",
|
|
117
117
|
"react": "^18.3 || ^19",
|
|
118
118
|
"rxjs": "^7.8.2"
|
|
119
119
|
},
|
|
@@ -81,7 +81,6 @@ describe(converterPortableText.deserialize, () => {
|
|
|
81
81
|
marks: [],
|
|
82
82
|
},
|
|
83
83
|
],
|
|
84
|
-
markDefs: [],
|
|
85
84
|
},
|
|
86
85
|
],
|
|
87
86
|
})
|
|
@@ -117,7 +116,6 @@ describe(converterPortableText.deserialize, () => {
|
|
|
117
116
|
marks: [],
|
|
118
117
|
},
|
|
119
118
|
],
|
|
120
|
-
markDefs: [],
|
|
121
119
|
},
|
|
122
120
|
],
|
|
123
121
|
})
|
|
@@ -263,8 +261,6 @@ describe(converterPortableText.deserialize, () => {
|
|
|
263
261
|
marks: [],
|
|
264
262
|
},
|
|
265
263
|
],
|
|
266
|
-
markDefs: [],
|
|
267
|
-
style: 'normal',
|
|
268
264
|
},
|
|
269
265
|
])
|
|
270
266
|
})
|
|
@@ -299,8 +295,6 @@ describe(converterPortableText.deserialize, () => {
|
|
|
299
295
|
marks: [],
|
|
300
296
|
},
|
|
301
297
|
],
|
|
302
|
-
markDefs: [],
|
|
303
|
-
style: 'normal',
|
|
304
298
|
},
|
|
305
299
|
])
|
|
306
300
|
})
|
|
@@ -336,8 +330,6 @@ describe(converterPortableText.deserialize, () => {
|
|
|
336
330
|
marks: [],
|
|
337
331
|
},
|
|
338
332
|
],
|
|
339
|
-
markDefs: [],
|
|
340
|
-
style: 'normal',
|
|
341
333
|
},
|
|
342
334
|
])
|
|
343
335
|
})
|
|
@@ -377,7 +369,6 @@ describe(converterPortableText.deserialize, () => {
|
|
|
377
369
|
marks: [],
|
|
378
370
|
},
|
|
379
371
|
],
|
|
380
|
-
markDefs: [],
|
|
381
372
|
style: 'h1',
|
|
382
373
|
},
|
|
383
374
|
])
|
|
@@ -415,9 +406,7 @@ describe(converterPortableText.deserialize, () => {
|
|
|
415
406
|
marks: [],
|
|
416
407
|
},
|
|
417
408
|
],
|
|
418
|
-
markDefs: [],
|
|
419
409
|
level: 1,
|
|
420
|
-
style: 'normal',
|
|
421
410
|
},
|
|
422
411
|
])
|
|
423
412
|
})
|
|
@@ -458,10 +447,8 @@ describe(converterPortableText.deserialize, () => {
|
|
|
458
447
|
marks: [],
|
|
459
448
|
},
|
|
460
449
|
],
|
|
461
|
-
markDefs: [],
|
|
462
450
|
listItem: 'bullet',
|
|
463
451
|
level: 1,
|
|
464
|
-
style: 'normal',
|
|
465
452
|
},
|
|
466
453
|
])
|
|
467
454
|
})
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -25,7 +25,7 @@ import {getEventPosition} from '../internal-utils/event-position'
|
|
|
25
25
|
import {normalizeSelection} from '../internal-utils/selection'
|
|
26
26
|
import {slateRangeToSelection} from '../internal-utils/slate-utils'
|
|
27
27
|
import {toSlateRange} from '../internal-utils/to-slate-range'
|
|
28
|
-
import {
|
|
28
|
+
import {isEqualToEmptyEditor} from '../internal-utils/values'
|
|
29
29
|
import type {
|
|
30
30
|
EditorSelection,
|
|
31
31
|
OnCopyFn,
|
|
@@ -51,7 +51,6 @@ import {createWithHotkeys} from './plugins/createWithHotKeys'
|
|
|
51
51
|
import {rangeDecorationsMachine} from './range-decorations-machine'
|
|
52
52
|
import {RelayActorContext} from './relay-actor-context'
|
|
53
53
|
import {validateSelectionMachine} from './validate-selection-machine'
|
|
54
|
-
import {KEY_TO_VALUE_ELEMENT} from './weakMaps'
|
|
55
54
|
|
|
56
55
|
const debug = debugWithName('component:Editable')
|
|
57
56
|
|
|
@@ -250,10 +249,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
250
249
|
debug(`Selection from props ${JSON.stringify(propsSelection)}`)
|
|
251
250
|
const normalizedSelection = normalizeSelection(
|
|
252
251
|
propsSelection,
|
|
253
|
-
|
|
254
|
-
slateEditor.children,
|
|
255
|
-
editorActor.getSnapshot().context.schema.block.name,
|
|
256
|
-
),
|
|
252
|
+
slateEditor.value,
|
|
257
253
|
)
|
|
258
254
|
if (normalizedSelection !== null) {
|
|
259
255
|
debug(
|
|
@@ -401,11 +397,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
401
397
|
// Handle incoming pasting events in the editor
|
|
402
398
|
const handlePaste = useCallback(
|
|
403
399
|
(event: ClipboardEvent<HTMLDivElement>): Promise<void> | void => {
|
|
404
|
-
const value =
|
|
405
|
-
slateEditor.children,
|
|
406
|
-
editorActor.getSnapshot().context.schema.block.name,
|
|
407
|
-
KEY_TO_VALUE_ELEMENT.get(slateEditor),
|
|
408
|
-
)
|
|
400
|
+
const value = slateEditor.value
|
|
409
401
|
const ptRange = slateEditor.selection
|
|
410
402
|
? slateRangeToSelection({
|
|
411
403
|
schema: editorActor.getSnapshot().context.schema,
|
|
@@ -9,7 +9,6 @@ import {createCoreConverters} from '../converters/converters.core'
|
|
|
9
9
|
import type {Editor, EditorConfig} from '../editor'
|
|
10
10
|
import {debugWithName} from '../internal-utils/debug'
|
|
11
11
|
import {compileType} from '../internal-utils/schema'
|
|
12
|
-
import {fromSlateValue} from '../internal-utils/values'
|
|
13
12
|
import {corePriority} from '../priority/priority.core'
|
|
14
13
|
import {createEditorPriority} from '../priority/priority.types'
|
|
15
14
|
import type {EditableAPI, PortableTextSlateEditor} from '../types/editor'
|
|
@@ -23,7 +22,6 @@ import {mutationMachine, type MutationActor} from './mutation-machine'
|
|
|
23
22
|
import {createEditableAPI} from './plugins/createWithEditableAPI'
|
|
24
23
|
import {relayMachine, type RelayActor} from './relay-machine'
|
|
25
24
|
import {syncMachine, type SyncActor} from './sync-machine'
|
|
26
|
-
import {KEY_TO_VALUE_ELEMENT} from './weakMaps'
|
|
27
25
|
|
|
28
26
|
const debug = debugWithName('setup')
|
|
29
27
|
|
|
@@ -266,11 +264,7 @@ function createActors(config: {
|
|
|
266
264
|
config.editorActor.send({
|
|
267
265
|
...event,
|
|
268
266
|
type: 'internal.patch',
|
|
269
|
-
value:
|
|
270
|
-
config.slateEditor.children,
|
|
271
|
-
config.editorActor.getSnapshot().context.schema.block.name,
|
|
272
|
-
KEY_TO_VALUE_ELEMENT.get(config.slateEditor),
|
|
273
|
-
),
|
|
267
|
+
value: config.slateEditor.value,
|
|
274
268
|
})
|
|
275
269
|
break
|
|
276
270
|
|
|
@@ -8,7 +8,7 @@ import type {PortableTextSlateEditor} from '../types/editor'
|
|
|
8
8
|
import type {EditorActor} from './editor-machine'
|
|
9
9
|
import {withPlugins} from './plugins/with-plugins'
|
|
10
10
|
import type {RelayActor} from './relay-machine'
|
|
11
|
-
import {KEY_TO_SLATE_ELEMENT
|
|
11
|
+
import {KEY_TO_SLATE_ELEMENT} from './weakMaps'
|
|
12
12
|
|
|
13
13
|
const debug = debugWithName('setup')
|
|
14
14
|
|
|
@@ -26,25 +26,25 @@ export type SlateEditor = {
|
|
|
26
26
|
export function createSlateEditor(config: SlateEditorConfig): SlateEditor {
|
|
27
27
|
debug('Creating new Slate editor instance')
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const placeholderBlock = createPlaceholderBlock(
|
|
30
|
+
config.editorActor.getSnapshot().context,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const editor = createEditor()
|
|
34
|
+
editor.decoratedRanges = []
|
|
35
|
+
editor.decoratorState = {}
|
|
36
|
+
editor.value = [placeholderBlock]
|
|
37
|
+
editor.blockIndexMap = new Map<string, number>()
|
|
38
|
+
editor.listIndexMap = new Map<string, number>()
|
|
39
|
+
|
|
40
|
+
const instance = withPlugins(withReact(editor), {
|
|
30
41
|
editorActor: config.editorActor,
|
|
31
42
|
relayActor: config.relayActor,
|
|
32
43
|
subscriptions: config.subscriptions,
|
|
33
44
|
})
|
|
34
45
|
|
|
35
|
-
KEY_TO_VALUE_ELEMENT.set(instance, {})
|
|
36
46
|
KEY_TO_SLATE_ELEMENT.set(instance, {})
|
|
37
47
|
|
|
38
|
-
instance.decoratedRanges = []
|
|
39
|
-
instance.decoratorState = {}
|
|
40
|
-
|
|
41
|
-
const placeholderBlock = createPlaceholderBlock(
|
|
42
|
-
config.editorActor.getSnapshot().context,
|
|
43
|
-
)
|
|
44
|
-
instance.value = [placeholderBlock]
|
|
45
|
-
instance.blockIndexMap = new Map<string, number>()
|
|
46
|
-
instance.listIndexMap = new Map<string, number>()
|
|
47
|
-
|
|
48
48
|
buildIndexMaps(
|
|
49
49
|
{
|
|
50
50
|
schema: config.editorActor.getSnapshot().context.schema,
|
|
@@ -4,16 +4,8 @@ import type {
|
|
|
4
4
|
PortableTextBlock,
|
|
5
5
|
PortableTextChild,
|
|
6
6
|
PortableTextObject,
|
|
7
|
-
PortableTextTextBlock,
|
|
8
7
|
} from '@sanity/types'
|
|
9
|
-
import {
|
|
10
|
-
Editor,
|
|
11
|
-
Node,
|
|
12
|
-
Range,
|
|
13
|
-
Element as SlateElement,
|
|
14
|
-
Text,
|
|
15
|
-
Transforms,
|
|
16
|
-
} from 'slate'
|
|
8
|
+
import {Editor, Range, Element as SlateElement, Text, Transforms} from 'slate'
|
|
17
9
|
import type {DOMNode} from 'slate-dom'
|
|
18
10
|
import {ReactEditor} from 'slate-react'
|
|
19
11
|
import {buildIndexMaps} from '../../internal-utils/build-index-maps'
|
|
@@ -25,7 +17,6 @@ import {
|
|
|
25
17
|
slateRangeToSelection,
|
|
26
18
|
} from '../../internal-utils/slate-utils'
|
|
27
19
|
import {toSlateRange} from '../../internal-utils/to-slate-range'
|
|
28
|
-
import {fromSlateBlock, fromSlateValue} from '../../internal-utils/values'
|
|
29
20
|
import {getActiveAnnotationsMarks} from '../../selectors/selector.get-active-annotation-marks'
|
|
30
21
|
import {getActiveDecorators} from '../../selectors/selector.get-active-decorators'
|
|
31
22
|
import {getFocusBlock} from '../../selectors/selector.get-focus-block'
|
|
@@ -38,9 +29,13 @@ import type {
|
|
|
38
29
|
EditorSelection,
|
|
39
30
|
PortableTextSlateEditor,
|
|
40
31
|
} from '../../types/editor'
|
|
32
|
+
import {
|
|
33
|
+
getBlockKeyFromSelectionPoint,
|
|
34
|
+
getChildKeyFromSelectionPoint,
|
|
35
|
+
} from '../../utils/util.selection-point'
|
|
41
36
|
import type {EditorActor} from '../editor-machine'
|
|
42
37
|
import {getEditorSnapshot} from '../editor-selector'
|
|
43
|
-
import {
|
|
38
|
+
import {SLATE_TO_PORTABLE_TEXT_RANGE} from '../weakMaps'
|
|
44
39
|
|
|
45
40
|
const debug = debugWithName('API:editable')
|
|
46
41
|
|
|
@@ -151,36 +146,43 @@ export function createEditableAPI(
|
|
|
151
146
|
editor.onChange()
|
|
152
147
|
},
|
|
153
148
|
focusBlock: (): PortableTextBlock | undefined => {
|
|
154
|
-
if (editor.selection) {
|
|
155
|
-
|
|
156
|
-
editor,
|
|
157
|
-
editor.selection.focus.path.slice(0, 1),
|
|
158
|
-
)
|
|
159
|
-
if (block) {
|
|
160
|
-
return fromSlateBlock(
|
|
161
|
-
block,
|
|
162
|
-
types.block.name,
|
|
163
|
-
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
164
|
-
)
|
|
165
|
-
}
|
|
149
|
+
if (!editor.selection) {
|
|
150
|
+
return undefined
|
|
166
151
|
}
|
|
167
|
-
|
|
152
|
+
|
|
153
|
+
const focusBlockIndex = editor.selection.focus.path.at(0)
|
|
154
|
+
|
|
155
|
+
if (focusBlockIndex === undefined) {
|
|
156
|
+
return undefined
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return editor.value.at(focusBlockIndex)
|
|
168
160
|
},
|
|
169
161
|
focusChild: (): PortableTextChild | undefined => {
|
|
170
|
-
if (editor.selection) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
162
|
+
if (!editor.selection) {
|
|
163
|
+
return undefined
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const focusBlockIndex = editor.selection.focus.path.at(0)
|
|
167
|
+
const focusChildIndex = editor.selection.focus.path.at(1)
|
|
168
|
+
|
|
169
|
+
const block =
|
|
170
|
+
focusBlockIndex !== undefined
|
|
171
|
+
? editor.value.at(focusBlockIndex)
|
|
172
|
+
: undefined
|
|
173
|
+
|
|
174
|
+
if (!block) {
|
|
175
|
+
return undefined
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (isTextBlock(editorActor.getSnapshot().context, block)) {
|
|
179
|
+
if (focusChildIndex === undefined) {
|
|
180
|
+
return undefined
|
|
182
181
|
}
|
|
182
|
+
|
|
183
|
+
return block.children.at(focusChildIndex)
|
|
183
184
|
}
|
|
185
|
+
|
|
184
186
|
return undefined
|
|
185
187
|
},
|
|
186
188
|
insertChild: <TSchemaType extends {name: string}>(
|
|
@@ -257,43 +259,38 @@ export function createEditableAPI(
|
|
|
257
259
|
PortableTextBlock | PortableTextChild | undefined,
|
|
258
260
|
Path | undefined,
|
|
259
261
|
] => {
|
|
260
|
-
const
|
|
261
|
-
context: {
|
|
262
|
-
schema: editorActor.getSnapshot().context.schema,
|
|
263
|
-
value: editor.value,
|
|
264
|
-
selection: {focus: {path, offset: 0}, anchor: {path, offset: 0}},
|
|
265
|
-
},
|
|
266
|
-
blockIndexMap: editor.blockIndexMap,
|
|
267
|
-
})
|
|
262
|
+
const blockKey = getBlockKeyFromSelectionPoint({path, offset: 0})
|
|
268
263
|
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
264
|
+
if (!blockKey) {
|
|
265
|
+
return [undefined, undefined]
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const blockIndex = editor.blockIndexMap.get(blockKey)
|
|
269
|
+
|
|
270
|
+
if (blockIndex === undefined) {
|
|
271
|
+
return [undefined, undefined]
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const block = editor.value.at(blockIndex)
|
|
275
|
+
|
|
276
|
+
if (!block) {
|
|
277
|
+
return [undefined, undefined]
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const childKey = getChildKeyFromSelectionPoint({path, offset: 0})
|
|
281
|
+
|
|
282
|
+
if (path.length === 1 && !childKey) {
|
|
283
|
+
return [block, [{_key: block._key}]]
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (isTextBlock(editorActor.getSnapshot().context, block) && childKey) {
|
|
287
|
+
const child = block.children.find((child) => child._key === childKey)
|
|
288
|
+
|
|
289
|
+
if (child) {
|
|
290
|
+
return [child, [{_key: block._key}, 'children', {_key: child._key}]]
|
|
295
291
|
}
|
|
296
292
|
}
|
|
293
|
+
|
|
297
294
|
return [undefined, undefined]
|
|
298
295
|
},
|
|
299
296
|
findDOMNode: (
|
|
@@ -542,11 +539,7 @@ export function createEditableAPI(
|
|
|
542
539
|
return ptRange
|
|
543
540
|
},
|
|
544
541
|
getValue: () => {
|
|
545
|
-
return
|
|
546
|
-
editor.children,
|
|
547
|
-
types.block.name,
|
|
548
|
-
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
549
|
-
)
|
|
542
|
+
return editor.value
|
|
550
543
|
},
|
|
551
544
|
isCollapsedSelection: () => {
|
|
552
545
|
return !!editor.selection && Range.isCollapsed(editor.selection)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {insert, setIfMissing, unset, type Patch} from '@portabletext/patches'
|
|
2
|
-
import
|
|
2
|
+
import type {PortableTextBlock} from '@portabletext/schema'
|
|
3
|
+
import {Editor, type Operation} from 'slate'
|
|
3
4
|
import {pluginWithoutHistory} from '../../history/slate-plugin.without-history'
|
|
4
5
|
import {getCurrentUndoStepId} from '../../history/undo-step'
|
|
5
6
|
import {createApplyPatch} from '../../internal-utils/applyPatch'
|
|
@@ -14,11 +15,11 @@ import {
|
|
|
14
15
|
setNodePatch,
|
|
15
16
|
splitNodePatch,
|
|
16
17
|
} from '../../internal-utils/operation-to-patches'
|
|
17
|
-
import {
|
|
18
|
+
import {isEqualToEmptyEditor} from '../../internal-utils/values'
|
|
18
19
|
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
19
20
|
import type {EditorActor} from '../editor-machine'
|
|
20
21
|
import type {RelayActor} from '../relay-machine'
|
|
21
|
-
import {IS_PROCESSING_REMOTE_CHANGES
|
|
22
|
+
import {IS_PROCESSING_REMOTE_CHANGES} from '../weakMaps'
|
|
22
23
|
import {withRemoteChanges} from '../withChanges'
|
|
23
24
|
import {isPatching, PATCHING, withoutPatching} from '../withoutPatching'
|
|
24
25
|
|
|
@@ -36,16 +37,16 @@ export function createWithPatches({
|
|
|
36
37
|
relayActor,
|
|
37
38
|
subscriptions,
|
|
38
39
|
}: Options): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
39
|
-
// The previous editor
|
|
40
|
-
// The editor.
|
|
41
|
-
let
|
|
40
|
+
// The previous editor value are needed to figure out the _key of deleted nodes
|
|
41
|
+
// The editor.value would no longer contain that information if the node is already deleted.
|
|
42
|
+
let previousValue: PortableTextBlock[]
|
|
42
43
|
|
|
43
44
|
const applyPatch = createApplyPatch(editorActor.getSnapshot().context.schema)
|
|
44
45
|
|
|
45
46
|
return function withPatches(editor: PortableTextSlateEditor) {
|
|
46
47
|
IS_PROCESSING_REMOTE_CHANGES.set(editor, false)
|
|
47
48
|
PATCHING.set(editor, true)
|
|
48
|
-
|
|
49
|
+
previousValue = [...editor.value]
|
|
49
50
|
|
|
50
51
|
const {apply} = editor
|
|
51
52
|
let bufferedPatches: Patch[] = []
|
|
@@ -106,10 +107,10 @@ export function createWithPatches({
|
|
|
106
107
|
let patches: Patch[] = []
|
|
107
108
|
|
|
108
109
|
// Update previous children here before we apply
|
|
109
|
-
|
|
110
|
+
previousValue = editor.value
|
|
110
111
|
|
|
111
112
|
const editorWasEmpty = isEqualToEmptyEditor(
|
|
112
|
-
|
|
113
|
+
previousValue,
|
|
113
114
|
editorActor.getSnapshot().context.schema,
|
|
114
115
|
)
|
|
115
116
|
|
|
@@ -117,7 +118,7 @@ export function createWithPatches({
|
|
|
117
118
|
apply(operation)
|
|
118
119
|
|
|
119
120
|
const editorIsEmpty = isEqualToEmptyEditor(
|
|
120
|
-
editor.
|
|
121
|
+
editor.value,
|
|
121
122
|
editorActor.getSnapshot().context.schema,
|
|
122
123
|
)
|
|
123
124
|
|
|
@@ -136,7 +137,7 @@ export function createWithPatches({
|
|
|
136
137
|
!editorIsEmpty &&
|
|
137
138
|
operation.type !== 'set_selection'
|
|
138
139
|
) {
|
|
139
|
-
patches.push(insert(
|
|
140
|
+
patches.push(insert(previousValue, 'before', [0]))
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
switch (operation.type) {
|
|
@@ -147,7 +148,7 @@ export function createWithPatches({
|
|
|
147
148
|
editorActor.getSnapshot().context.schema,
|
|
148
149
|
editor.children,
|
|
149
150
|
operation,
|
|
150
|
-
|
|
151
|
+
previousValue,
|
|
151
152
|
),
|
|
152
153
|
]
|
|
153
154
|
break
|
|
@@ -158,7 +159,7 @@ export function createWithPatches({
|
|
|
158
159
|
editorActor.getSnapshot().context.schema,
|
|
159
160
|
editor.children,
|
|
160
161
|
operation,
|
|
161
|
-
|
|
162
|
+
previousValue,
|
|
162
163
|
),
|
|
163
164
|
]
|
|
164
165
|
break
|
|
@@ -167,7 +168,7 @@ export function createWithPatches({
|
|
|
167
168
|
...patches,
|
|
168
169
|
...removeNodePatch(
|
|
169
170
|
editorActor.getSnapshot().context.schema,
|
|
170
|
-
|
|
171
|
+
previousValue,
|
|
171
172
|
operation,
|
|
172
173
|
),
|
|
173
174
|
]
|
|
@@ -179,7 +180,7 @@ export function createWithPatches({
|
|
|
179
180
|
editorActor.getSnapshot().context.schema,
|
|
180
181
|
editor.children,
|
|
181
182
|
operation,
|
|
182
|
-
|
|
183
|
+
previousValue,
|
|
183
184
|
),
|
|
184
185
|
]
|
|
185
186
|
break
|
|
@@ -190,7 +191,7 @@ export function createWithPatches({
|
|
|
190
191
|
editorActor.getSnapshot().context.schema,
|
|
191
192
|
editor.children,
|
|
192
193
|
operation,
|
|
193
|
-
|
|
194
|
+
previousValue,
|
|
194
195
|
),
|
|
195
196
|
]
|
|
196
197
|
break
|
|
@@ -211,7 +212,7 @@ export function createWithPatches({
|
|
|
211
212
|
editorActor.getSnapshot().context.schema,
|
|
212
213
|
editor.children,
|
|
213
214
|
operation,
|
|
214
|
-
|
|
215
|
+
previousValue,
|
|
215
216
|
),
|
|
216
217
|
]
|
|
217
218
|
break
|
|
@@ -220,7 +221,7 @@ export function createWithPatches({
|
|
|
220
221
|
...patches,
|
|
221
222
|
...moveNodePatch(
|
|
222
223
|
editorActor.getSnapshot().context.schema,
|
|
223
|
-
|
|
224
|
+
previousValue,
|
|
224
225
|
operation,
|
|
225
226
|
),
|
|
226
227
|
]
|
|
@@ -240,11 +241,7 @@ export function createWithPatches({
|
|
|
240
241
|
patches = [...patches, unset([])]
|
|
241
242
|
relayActor.send({
|
|
242
243
|
type: 'unset',
|
|
243
|
-
previousValue
|
|
244
|
-
previousChildren,
|
|
245
|
-
editorActor.getSnapshot().context.schema.block.name,
|
|
246
|
-
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
247
|
-
),
|
|
244
|
+
previousValue,
|
|
248
245
|
})
|
|
249
246
|
}
|
|
250
247
|
|
|
@@ -30,6 +30,9 @@ export function createWithPortableTextMarkModel(
|
|
|
30
30
|
const decorators = editorActor
|
|
31
31
|
.getSnapshot()
|
|
32
32
|
.context.schema.decorators.map((t) => t.name)
|
|
33
|
+
const defaultStyle = editorActor
|
|
34
|
+
.getSnapshot()
|
|
35
|
+
.context.schema.styles.at(0)?.name
|
|
33
36
|
|
|
34
37
|
// Extend Slate's default normalization. Merge spans with same set of .marks when doing merge_node operations, and clean up markDefs / marks
|
|
35
38
|
editor.normalizeNode = (nodeEntry) => {
|
|
@@ -74,6 +77,22 @@ export function createWithPortableTextMarkModel(
|
|
|
74
77
|
return
|
|
75
78
|
}
|
|
76
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Add missing .style to block nodes
|
|
82
|
+
*/
|
|
83
|
+
if (
|
|
84
|
+
defaultStyle &&
|
|
85
|
+
editor.isTextBlock(node) &&
|
|
86
|
+
typeof node.style === 'undefined'
|
|
87
|
+
) {
|
|
88
|
+
debug('Adding .style to block node')
|
|
89
|
+
|
|
90
|
+
withNormalizeNode(editor, () => {
|
|
91
|
+
Transforms.setNodes(editor, {style: defaultStyle}, {at: path})
|
|
92
|
+
})
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
77
96
|
/**
|
|
78
97
|
* Add missing .marks to span nodes
|
|
79
98
|
*/
|
|
@@ -357,7 +357,7 @@ function createDecorate(
|
|
|
357
357
|
slateEditor: PortableTextSlateEditor,
|
|
358
358
|
) {
|
|
359
359
|
return function decorate([node, path]: NodeEntry): Array<BaseRange> {
|
|
360
|
-
if (isEqualToEmptyEditor(slateEditor.
|
|
360
|
+
if (isEqualToEmptyEditor(slateEditor.value, schema)) {
|
|
361
361
|
return [
|
|
362
362
|
{
|
|
363
363
|
anchor: {
|
package/src/editor/weakMaps.ts
CHANGED
|
@@ -7,8 +7,6 @@ export const IS_PROCESSING_REMOTE_CHANGES: WeakMap<Editor, boolean> =
|
|
|
7
7
|
|
|
8
8
|
export const KEY_TO_SLATE_ELEMENT: WeakMap<Editor, any | undefined> =
|
|
9
9
|
new WeakMap()
|
|
10
|
-
export const KEY_TO_VALUE_ELEMENT: WeakMap<Editor, any | undefined> =
|
|
11
|
-
new WeakMap()
|
|
12
10
|
|
|
13
11
|
// Keep object relation to slate range in the portable-text-range
|
|
14
12
|
export const SLATE_TO_PORTABLE_TEXT_RANGE = new WeakMap<
|
|
@@ -8,7 +8,6 @@ import type {Operation} from 'slate'
|
|
|
8
8
|
import type {EditorActor} from '../editor/editor-machine'
|
|
9
9
|
import {isChangingRemotely} from '../editor/withChanges'
|
|
10
10
|
import {debugWithName} from '../internal-utils/debug'
|
|
11
|
-
import {fromSlateValue} from '../internal-utils/values'
|
|
12
11
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
13
12
|
import {getRemotePatches} from './remote-patches'
|
|
14
13
|
import {isRedoing} from './slate-plugin.redoing'
|
|
@@ -29,10 +28,7 @@ export function pluginHistory({
|
|
|
29
28
|
}): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
30
29
|
return (editor: PortableTextSlateEditor) => {
|
|
31
30
|
const remotePatches = getRemotePatches(editor)
|
|
32
|
-
let previousSnapshot: PortableTextBlock
|
|
33
|
-
editor.children,
|
|
34
|
-
editorActor.getSnapshot().context.schema.block.name,
|
|
35
|
-
)
|
|
31
|
+
let previousSnapshot: Array<PortableTextBlock> | undefined = editor.value
|
|
36
32
|
let previousUndoStepId = getCurrentUndoStepId(editor)
|
|
37
33
|
|
|
38
34
|
subscriptions.push(() => {
|