@portabletext/editor 1.5.1 → 1.5.3
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 +1 -1
- package/lib/index.d.mts +74 -18
- package/lib/index.d.ts +74 -18
- package/lib/index.esm.js +178 -140
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +178 -140
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +178 -140
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/editor/behavior/behavior.core.block-objects.ts +4 -4
- package/src/editor/behavior/behavior.core.lists.ts +1 -1
- package/src/editor/behavior/behavior.core.ts +17 -2
- package/src/editor/behavior/behavior.markdown.ts +5 -0
- package/src/editor/define-schema.ts +22 -2
- package/src/editor/editor-machine.ts +2 -4
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +18 -0
- package/src/index.ts +2 -1
package/lib/index.js
CHANGED
|
@@ -119,6 +119,148 @@ function getNextBlock(context) {
|
|
|
119
119
|
function isEmptyTextBlock(block) {
|
|
120
120
|
return block.children.length === 1 && block.children[0].text === "";
|
|
121
121
|
}
|
|
122
|
+
const breakingBlockObject = {
|
|
123
|
+
on: "insert break",
|
|
124
|
+
guard: ({
|
|
125
|
+
context
|
|
126
|
+
}) => !!getFocusBlockObject(context),
|
|
127
|
+
actions: [() => [{
|
|
128
|
+
type: "insert text block",
|
|
129
|
+
decorators: []
|
|
130
|
+
}]]
|
|
131
|
+
}, deletingEmptyTextBlockAfterBlockObject = {
|
|
132
|
+
on: "delete backward",
|
|
133
|
+
guard: ({
|
|
134
|
+
context
|
|
135
|
+
}) => {
|
|
136
|
+
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), previousBlock = getPreviousBlock(context);
|
|
137
|
+
return !focusTextBlock || !selectionCollapsed || !previousBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !types.isPortableTextTextBlock(previousBlock.node) ? {
|
|
138
|
+
focusTextBlock,
|
|
139
|
+
previousBlock
|
|
140
|
+
} : !1;
|
|
141
|
+
},
|
|
142
|
+
actions: [(_, {
|
|
143
|
+
focusTextBlock,
|
|
144
|
+
previousBlock
|
|
145
|
+
}) => [{
|
|
146
|
+
type: "delete",
|
|
147
|
+
selection: {
|
|
148
|
+
anchor: {
|
|
149
|
+
path: focusTextBlock.path,
|
|
150
|
+
offset: 0
|
|
151
|
+
},
|
|
152
|
+
focus: {
|
|
153
|
+
path: focusTextBlock.path,
|
|
154
|
+
offset: 0
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}, {
|
|
158
|
+
type: "select",
|
|
159
|
+
selection: {
|
|
160
|
+
anchor: {
|
|
161
|
+
path: previousBlock.path,
|
|
162
|
+
offset: 0
|
|
163
|
+
},
|
|
164
|
+
focus: {
|
|
165
|
+
path: previousBlock.path,
|
|
166
|
+
offset: 0
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}]]
|
|
170
|
+
}, deletingEmptyTextBlockBeforeBlockObject = {
|
|
171
|
+
on: "delete forward",
|
|
172
|
+
guard: ({
|
|
173
|
+
context
|
|
174
|
+
}) => {
|
|
175
|
+
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), nextBlock = getNextBlock(context);
|
|
176
|
+
return !focusTextBlock || !selectionCollapsed || !nextBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !types.isPortableTextTextBlock(nextBlock.node) ? {
|
|
177
|
+
focusTextBlock,
|
|
178
|
+
nextBlock
|
|
179
|
+
} : !1;
|
|
180
|
+
},
|
|
181
|
+
actions: [(_, {
|
|
182
|
+
focusTextBlock,
|
|
183
|
+
nextBlock
|
|
184
|
+
}) => [{
|
|
185
|
+
type: "delete",
|
|
186
|
+
selection: {
|
|
187
|
+
anchor: {
|
|
188
|
+
path: focusTextBlock.path,
|
|
189
|
+
offset: 0
|
|
190
|
+
},
|
|
191
|
+
focus: {
|
|
192
|
+
path: focusTextBlock.path,
|
|
193
|
+
offset: 0
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}, {
|
|
197
|
+
type: "select",
|
|
198
|
+
selection: {
|
|
199
|
+
anchor: {
|
|
200
|
+
path: nextBlock.path,
|
|
201
|
+
offset: 0
|
|
202
|
+
},
|
|
203
|
+
focus: {
|
|
204
|
+
path: nextBlock.path,
|
|
205
|
+
offset: 0
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}]]
|
|
209
|
+
}, coreBlockObjectBehaviors = {
|
|
210
|
+
breakingBlockObject,
|
|
211
|
+
deletingEmptyTextBlockAfterBlockObject,
|
|
212
|
+
deletingEmptyTextBlockBeforeBlockObject
|
|
213
|
+
}, clearListOnBackspace = {
|
|
214
|
+
on: "delete backward",
|
|
215
|
+
guard: ({
|
|
216
|
+
context
|
|
217
|
+
}) => {
|
|
218
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
219
|
+
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level === 1 ? {
|
|
220
|
+
focusTextBlock
|
|
221
|
+
} : !1;
|
|
222
|
+
},
|
|
223
|
+
actions: [(_, {
|
|
224
|
+
focusTextBlock
|
|
225
|
+
}) => [{
|
|
226
|
+
type: "unset block",
|
|
227
|
+
props: ["listItem", "level"],
|
|
228
|
+
paths: [focusTextBlock.path]
|
|
229
|
+
}]]
|
|
230
|
+
}, unindentListOnBackspace = {
|
|
231
|
+
on: "delete backward",
|
|
232
|
+
guard: ({
|
|
233
|
+
context
|
|
234
|
+
}) => {
|
|
235
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
236
|
+
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level !== void 0 && focusTextBlock.node.level > 1 ? {
|
|
237
|
+
focusTextBlock,
|
|
238
|
+
level: focusTextBlock.node.level - 1
|
|
239
|
+
} : !1;
|
|
240
|
+
},
|
|
241
|
+
actions: [(_, {
|
|
242
|
+
focusTextBlock,
|
|
243
|
+
level
|
|
244
|
+
}) => [{
|
|
245
|
+
type: "set block",
|
|
246
|
+
level,
|
|
247
|
+
paths: [focusTextBlock.path]
|
|
248
|
+
}]]
|
|
249
|
+
}, coreListBehaviors = {
|
|
250
|
+
clearListOnBackspace,
|
|
251
|
+
unindentListOnBackspace
|
|
252
|
+
}, softReturn = {
|
|
253
|
+
on: "insert soft break",
|
|
254
|
+
actions: [() => [{
|
|
255
|
+
type: "insert text",
|
|
256
|
+
text: `
|
|
257
|
+
`
|
|
258
|
+
}]]
|
|
259
|
+
}, coreBehaviors = [softReturn, coreBlockObjectBehaviors.breakingBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject, coreListBehaviors.clearListOnBackspace, coreListBehaviors.unindentListOnBackspace], coreBehavior = {
|
|
260
|
+
softReturn,
|
|
261
|
+
blockObjects: coreBlockObjectBehaviors,
|
|
262
|
+
lists: coreListBehaviors
|
|
263
|
+
};
|
|
122
264
|
function createMarkdownBehaviors(config) {
|
|
123
265
|
const automaticStyleOnSpace = {
|
|
124
266
|
on: "insert text",
|
|
@@ -150,6 +292,10 @@ function createMarkdownBehaviors(config) {
|
|
|
150
292
|
focusSpan,
|
|
151
293
|
style
|
|
152
294
|
}) => [{
|
|
295
|
+
type: "unset block",
|
|
296
|
+
props: ["listItem", "level"],
|
|
297
|
+
paths: [focusTextBlock.path]
|
|
298
|
+
}, {
|
|
153
299
|
type: "set block",
|
|
154
300
|
style,
|
|
155
301
|
paths: [focusTextBlock.path]
|
|
@@ -303,7 +449,9 @@ function defineSchema(definition) {
|
|
|
303
449
|
function compileSchemaDefinition(definition) {
|
|
304
450
|
const blockObjects = definition?.blockObjects?.map((blockObject) => types.defineType({
|
|
305
451
|
type: "object",
|
|
306
|
-
|
|
452
|
+
// Very naive way to work around `SanitySchema.compile` adding default
|
|
453
|
+
// fields to objects with the name `image`
|
|
454
|
+
name: blockObject.name === "image" ? "tmp-image" : blockObject.name,
|
|
307
455
|
title: blockObject.title,
|
|
308
456
|
icon: blockObject.icon,
|
|
309
457
|
fields: []
|
|
@@ -350,8 +498,18 @@ function compileSchemaDefinition(definition) {
|
|
|
350
498
|
}]
|
|
351
499
|
}), schema$1 = schema.Schema.compile({
|
|
352
500
|
types: [portableTextSchema, ...blockObjects, ...inlineObjects]
|
|
353
|
-
}).get("portable-text");
|
|
354
|
-
return
|
|
501
|
+
}).get("portable-text"), pteSchema = getPortableTextMemberSchemaTypes(schema$1);
|
|
502
|
+
return {
|
|
503
|
+
...pteSchema,
|
|
504
|
+
blockObjects: pteSchema.blockObjects.map((blockObject) => blockObject.name === "tmp-image" ? {
|
|
505
|
+
...blockObject,
|
|
506
|
+
name: "image",
|
|
507
|
+
type: {
|
|
508
|
+
...blockObject.type,
|
|
509
|
+
name: "image"
|
|
510
|
+
}
|
|
511
|
+
} : blockObject)
|
|
512
|
+
};
|
|
355
513
|
}
|
|
356
514
|
const rootName = "sanity-pte:";
|
|
357
515
|
debug__default.default(rootName);
|
|
@@ -3526,22 +3684,30 @@ function createWithPortableTextMarkModel(editorActor, types2) {
|
|
|
3526
3684
|
editor,
|
|
3527
3685
|
blockPath,
|
|
3528
3686
|
spanPath: [op.path[0], op.path[1] - 1]
|
|
3529
|
-
}), nextSpanAnnotations = nextSpan ? nextSpan.marks?.filter((mark) => !decorators.includes(mark)) : [], annotationsEnding = previousSpanAnnotations?.filter((annotation) => !nextSpanAnnotations?.includes(annotation)) ?? [];
|
|
3530
|
-
if (
|
|
3687
|
+
}), nextSpanAnnotations = nextSpan ? nextSpan.marks?.filter((mark) => !decorators.includes(mark)) : [], annotationsEnding = previousSpanAnnotations?.filter((annotation) => !nextSpanAnnotations?.includes(annotation)) ?? [], atTheEndOfAnnotation = annotationsEnding.length > 0;
|
|
3688
|
+
if (atTheEndOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsEnding.includes(mark))) {
|
|
3531
3689
|
slate.Transforms.insertNodes(editor, {
|
|
3532
3690
|
...op.node,
|
|
3533
3691
|
marks: op.node.marks?.filter((mark) => !annotationsEnding.includes(mark)) ?? []
|
|
3534
3692
|
});
|
|
3535
3693
|
return;
|
|
3536
3694
|
}
|
|
3537
|
-
const annotationsStarting = nextSpanAnnotations?.filter((annotation) => !previousSpanAnnotations?.includes(annotation)) ?? [];
|
|
3538
|
-
if (
|
|
3695
|
+
const annotationsStarting = nextSpanAnnotations?.filter((annotation) => !previousSpanAnnotations?.includes(annotation)) ?? [], atTheStartOfAnnotation = annotationsStarting.length > 0;
|
|
3696
|
+
if (atTheStartOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsStarting.includes(mark))) {
|
|
3539
3697
|
slate.Transforms.insertNodes(editor, {
|
|
3540
3698
|
...op.node,
|
|
3541
3699
|
marks: op.node.marks?.filter((mark) => !annotationsStarting.includes(mark)) ?? []
|
|
3542
3700
|
});
|
|
3543
3701
|
return;
|
|
3544
3702
|
}
|
|
3703
|
+
const nextSpanDecorators = nextSpan?.marks?.filter((mark) => decorators.includes(mark)) ?? [];
|
|
3704
|
+
if (nextSpanDecorators.length > 0 && atTheEndOfAnnotation && !atTheStartOfAnnotation && isPortableTextSpan(op.node) && op.node.marks?.length === 0) {
|
|
3705
|
+
slate.Transforms.insertNodes(editor, {
|
|
3706
|
+
...op.node,
|
|
3707
|
+
marks: nextSpanDecorators
|
|
3708
|
+
});
|
|
3709
|
+
return;
|
|
3710
|
+
}
|
|
3545
3711
|
}
|
|
3546
3712
|
}
|
|
3547
3713
|
if (op.type === "insert_text") {
|
|
@@ -5318,137 +5484,7 @@ function performDefaultAction({
|
|
|
5318
5484
|
});
|
|
5319
5485
|
}
|
|
5320
5486
|
}
|
|
5321
|
-
const
|
|
5322
|
-
on: "insert break",
|
|
5323
|
-
guard: ({
|
|
5324
|
-
context
|
|
5325
|
-
}) => !!getFocusBlockObject(context),
|
|
5326
|
-
actions: [() => [{
|
|
5327
|
-
type: "insert text block",
|
|
5328
|
-
decorators: []
|
|
5329
|
-
}]]
|
|
5330
|
-
}, deletingEmptyTextBlockAfterBlockObject = {
|
|
5331
|
-
on: "delete backward",
|
|
5332
|
-
guard: ({
|
|
5333
|
-
context
|
|
5334
|
-
}) => {
|
|
5335
|
-
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), previousBlock = getPreviousBlock(context);
|
|
5336
|
-
return !focusTextBlock || !selectionCollapsed || !previousBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !types.isPortableTextTextBlock(previousBlock.node) ? {
|
|
5337
|
-
focusTextBlock,
|
|
5338
|
-
previousBlock
|
|
5339
|
-
} : !1;
|
|
5340
|
-
},
|
|
5341
|
-
actions: [(_, {
|
|
5342
|
-
focusTextBlock,
|
|
5343
|
-
previousBlock
|
|
5344
|
-
}) => [{
|
|
5345
|
-
type: "delete",
|
|
5346
|
-
selection: {
|
|
5347
|
-
anchor: {
|
|
5348
|
-
path: focusTextBlock.path,
|
|
5349
|
-
offset: 0
|
|
5350
|
-
},
|
|
5351
|
-
focus: {
|
|
5352
|
-
path: focusTextBlock.path,
|
|
5353
|
-
offset: 0
|
|
5354
|
-
}
|
|
5355
|
-
}
|
|
5356
|
-
}, {
|
|
5357
|
-
type: "select",
|
|
5358
|
-
selection: {
|
|
5359
|
-
anchor: {
|
|
5360
|
-
path: previousBlock.path,
|
|
5361
|
-
offset: 0
|
|
5362
|
-
},
|
|
5363
|
-
focus: {
|
|
5364
|
-
path: previousBlock.path,
|
|
5365
|
-
offset: 0
|
|
5366
|
-
}
|
|
5367
|
-
}
|
|
5368
|
-
}]]
|
|
5369
|
-
}, deletingEmptyTextBlockBeforeBlockObject = {
|
|
5370
|
-
on: "delete forward",
|
|
5371
|
-
guard: ({
|
|
5372
|
-
context
|
|
5373
|
-
}) => {
|
|
5374
|
-
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), nextBlock = getNextBlock(context);
|
|
5375
|
-
return !focusTextBlock || !selectionCollapsed || !nextBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !types.isPortableTextTextBlock(nextBlock.node) ? {
|
|
5376
|
-
focusTextBlock,
|
|
5377
|
-
nextBlock
|
|
5378
|
-
} : !1;
|
|
5379
|
-
},
|
|
5380
|
-
actions: [(_, {
|
|
5381
|
-
focusTextBlock,
|
|
5382
|
-
nextBlock
|
|
5383
|
-
}) => [{
|
|
5384
|
-
type: "delete",
|
|
5385
|
-
selection: {
|
|
5386
|
-
anchor: {
|
|
5387
|
-
path: focusTextBlock.path,
|
|
5388
|
-
offset: 0
|
|
5389
|
-
},
|
|
5390
|
-
focus: {
|
|
5391
|
-
path: focusTextBlock.path,
|
|
5392
|
-
offset: 0
|
|
5393
|
-
}
|
|
5394
|
-
}
|
|
5395
|
-
}, {
|
|
5396
|
-
type: "select",
|
|
5397
|
-
selection: {
|
|
5398
|
-
anchor: {
|
|
5399
|
-
path: nextBlock.path,
|
|
5400
|
-
offset: 0
|
|
5401
|
-
},
|
|
5402
|
-
focus: {
|
|
5403
|
-
path: nextBlock.path,
|
|
5404
|
-
offset: 0
|
|
5405
|
-
}
|
|
5406
|
-
}
|
|
5407
|
-
}]]
|
|
5408
|
-
}, coreBlockObjectBehaviors = [breakingVoidBlock, deletingEmptyTextBlockAfterBlockObject, deletingEmptyTextBlockBeforeBlockObject], clearListOnBackspace = {
|
|
5409
|
-
on: "delete backward",
|
|
5410
|
-
guard: ({
|
|
5411
|
-
context
|
|
5412
|
-
}) => {
|
|
5413
|
-
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
5414
|
-
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level === 1 ? {
|
|
5415
|
-
focusTextBlock
|
|
5416
|
-
} : !1;
|
|
5417
|
-
},
|
|
5418
|
-
actions: [(_, {
|
|
5419
|
-
focusTextBlock
|
|
5420
|
-
}) => [{
|
|
5421
|
-
type: "unset block",
|
|
5422
|
-
props: ["listItem", "level"],
|
|
5423
|
-
paths: [focusTextBlock.path]
|
|
5424
|
-
}]]
|
|
5425
|
-
}, unindentListOnBackspace = {
|
|
5426
|
-
on: "delete backward",
|
|
5427
|
-
guard: ({
|
|
5428
|
-
context
|
|
5429
|
-
}) => {
|
|
5430
|
-
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
5431
|
-
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level !== void 0 && focusTextBlock.node.level > 1 ? {
|
|
5432
|
-
focusTextBlock,
|
|
5433
|
-
level: focusTextBlock.node.level - 1
|
|
5434
|
-
} : !1;
|
|
5435
|
-
},
|
|
5436
|
-
actions: [(_, {
|
|
5437
|
-
focusTextBlock,
|
|
5438
|
-
level
|
|
5439
|
-
}) => [{
|
|
5440
|
-
type: "set block",
|
|
5441
|
-
level,
|
|
5442
|
-
paths: [focusTextBlock.path]
|
|
5443
|
-
}]]
|
|
5444
|
-
}, coreListBehaviors = [clearListOnBackspace, unindentListOnBackspace], softReturn = {
|
|
5445
|
-
on: "insert soft break",
|
|
5446
|
-
actions: [() => [{
|
|
5447
|
-
type: "insert text",
|
|
5448
|
-
text: `
|
|
5449
|
-
`
|
|
5450
|
-
}]]
|
|
5451
|
-
}, coreBehaviors = [softReturn, ...coreBlockObjectBehaviors, ...coreListBehaviors], networkLogic = xstate.fromCallback(({
|
|
5487
|
+
const networkLogic = xstate.fromCallback(({
|
|
5452
5488
|
sendBack
|
|
5453
5489
|
}) => {
|
|
5454
5490
|
const onlineHandler = () => {
|
|
@@ -5474,7 +5510,7 @@ const breakingVoidBlock = {
|
|
|
5474
5510
|
"assign behaviors": xstate.assign({
|
|
5475
5511
|
behaviors: ({
|
|
5476
5512
|
event
|
|
5477
|
-
}) => (xstate.assertEvent(event, "update behaviors"),
|
|
5513
|
+
}) => (xstate.assertEvent(event, "update behaviors"), event.behaviors)
|
|
5478
5514
|
}),
|
|
5479
5515
|
"assign schema": xstate.assign({
|
|
5480
5516
|
schema: ({
|
|
@@ -5568,7 +5604,7 @@ const breakingVoidBlock = {
|
|
|
5568
5604
|
context: ({
|
|
5569
5605
|
input
|
|
5570
5606
|
}) => ({
|
|
5571
|
-
behaviors: input.behaviors
|
|
5607
|
+
behaviors: input.behaviors ?? coreBehaviors,
|
|
5572
5608
|
keyGenerator: input.keyGenerator,
|
|
5573
5609
|
pendingEvents: [],
|
|
5574
5610
|
schema: input.schema
|
|
@@ -6267,6 +6303,8 @@ function useEditor(config) {
|
|
|
6267
6303
|
}
|
|
6268
6304
|
exports.PortableTextEditable = PortableTextEditable;
|
|
6269
6305
|
exports.PortableTextEditor = PortableTextEditor;
|
|
6306
|
+
exports.coreBehavior = coreBehavior;
|
|
6307
|
+
exports.coreBehaviors = coreBehaviors;
|
|
6270
6308
|
exports.createMarkdownBehaviors = createMarkdownBehaviors;
|
|
6271
6309
|
exports.defineBehavior = defineBehavior;
|
|
6272
6310
|
exports.defineSchema = defineSchema;
|