@portabletext/editor 1.12.0 → 1.12.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/lib/index.d.mts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.esm.js +121 -29
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +121 -29
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +121 -29
- package/lib/index.mjs.map +1 -1
- package/package.json +12 -12
- package/src/editor/behavior/behavior.action-utils.insert-block.ts +3 -1
- package/src/editor/behavior/behavior.markdown.ts +23 -17
- package/src/editor/behavior/behavior.types.ts +2 -2
- package/src/editor/behavior/behavior.utils.get-selection-text.ts +92 -0
- package/src/editor/behavior/behavior.utils.get-start-point.ts +26 -0
- package/src/editor/behavior/behavior.utils.is-keyed-segment.ts +5 -0
- package/src/editor/behavior/behavior.utils.reverse-selection.ts +21 -0
- package/src/editor/behavior/behavior.utilts.get-text-before.ts +31 -0
package/lib/index.js
CHANGED
|
@@ -343,21 +343,6 @@ function looksLikeUrl(text) {
|
|
|
343
343
|
}
|
|
344
344
|
return looksLikeUrl2;
|
|
345
345
|
}
|
|
346
|
-
function isPortableTextSpan(node) {
|
|
347
|
-
return node._type === "span" && "text" in node && typeof node.text == "string" && (typeof node.marks > "u" || Array.isArray(node.marks) && node.marks.every((mark) => typeof mark == "string"));
|
|
348
|
-
}
|
|
349
|
-
function isPortableTextBlock(node) {
|
|
350
|
-
return (
|
|
351
|
-
// A block doesn't _have_ to be named 'block' - to differentiate between
|
|
352
|
-
// allowed child types and marks, one might name them differently
|
|
353
|
-
typeof node._type == "string" && // Toolkit-types like nested spans are @-prefixed
|
|
354
|
-
node._type[0] !== "@" && // `markDefs` isn't _required_ per say, but if it's there, it needs to be an array
|
|
355
|
-
(!("markDefs" in node) || !node.markDefs || Array.isArray(node.markDefs) && // Every mark definition needs to have an `_key` to be mappable in child spans
|
|
356
|
-
node.markDefs.every((def) => typeof def._key == "string")) && // `children` is required and needs to be an array
|
|
357
|
-
"children" in node && Array.isArray(node.children) && // All children are objects with `_type` (usually spans, but can contain other stuff)
|
|
358
|
-
node.children.every((child) => typeof child == "object" && "_type" in child)
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
346
|
function blockOffsetToSpanSelectionPoint({
|
|
362
347
|
value,
|
|
363
348
|
blockOffset
|
|
@@ -410,6 +395,87 @@ function spanSelectionPointToBlockOffset({
|
|
|
410
395
|
}
|
|
411
396
|
}
|
|
412
397
|
}
|
|
398
|
+
function isKeyedSegment$1(segment) {
|
|
399
|
+
return typeof segment == "object" && segment !== null && "_key" in segment;
|
|
400
|
+
}
|
|
401
|
+
function reverseSelection(selection) {
|
|
402
|
+
return selection && (selection.backward ? {
|
|
403
|
+
anchor: selection.focus,
|
|
404
|
+
focus: selection.anchor,
|
|
405
|
+
backward: !1
|
|
406
|
+
} : {
|
|
407
|
+
anchor: selection.focus,
|
|
408
|
+
focus: selection.anchor,
|
|
409
|
+
backward: !0
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
function getSelectionText({
|
|
413
|
+
value,
|
|
414
|
+
selection
|
|
415
|
+
}) {
|
|
416
|
+
let text = "";
|
|
417
|
+
if (!value || !selection)
|
|
418
|
+
return text;
|
|
419
|
+
const forwardSelection = selection.backward ? reverseSelection(selection) : selection;
|
|
420
|
+
if (!forwardSelection)
|
|
421
|
+
return text;
|
|
422
|
+
for (const block of value)
|
|
423
|
+
if (!(isKeyedSegment$1(forwardSelection.anchor.path[0]) && block._key !== forwardSelection.anchor.path[0]._key) && types.isPortableTextTextBlock(block)) {
|
|
424
|
+
for (const child of block.children)
|
|
425
|
+
if (types.isPortableTextSpan(child)) {
|
|
426
|
+
if (isKeyedSegment$1(forwardSelection.anchor.path[2]) && child._key === forwardSelection.anchor.path[2]._key && isKeyedSegment$1(forwardSelection.focus.path[2]) && child._key === forwardSelection.focus.path[2]._key) {
|
|
427
|
+
text = text + child.text.slice(forwardSelection.anchor.offset, forwardSelection.focus.offset);
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
if (isKeyedSegment$1(forwardSelection.anchor.path[2]) && child._key === forwardSelection.anchor.path[2]._key) {
|
|
431
|
+
text = text + child.text.slice(forwardSelection.anchor.offset);
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (isKeyedSegment$1(forwardSelection.focus.path[2]) && child._key === forwardSelection.focus.path[2]._key) {
|
|
435
|
+
text = text + child.text.slice(0, forwardSelection.focus.offset);
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (isKeyedSegment$1(forwardSelection.focus.path[0]) && block._key === forwardSelection.focus.path[0]._key)
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
return text;
|
|
443
|
+
}
|
|
444
|
+
function getStartPoint({
|
|
445
|
+
node,
|
|
446
|
+
path
|
|
447
|
+
}) {
|
|
448
|
+
return types.isPortableTextTextBlock(node) ? {
|
|
449
|
+
path: [...path, "children", {
|
|
450
|
+
_key: node.children[0]._key
|
|
451
|
+
}],
|
|
452
|
+
offset: 0
|
|
453
|
+
} : {
|
|
454
|
+
path,
|
|
455
|
+
offset: 0
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
function getBlockTextBefore({
|
|
459
|
+
value,
|
|
460
|
+
point
|
|
461
|
+
}) {
|
|
462
|
+
const key = isKeyedSegment$1(point.path[0]) ? point.path[0]._key : void 0, block = key ? value.find((block2) => block2._key === key) : void 0;
|
|
463
|
+
if (!block)
|
|
464
|
+
return "";
|
|
465
|
+
const startPoint = getStartPoint({
|
|
466
|
+
node: block,
|
|
467
|
+
path: [{
|
|
468
|
+
_key: block._key
|
|
469
|
+
}]
|
|
470
|
+
});
|
|
471
|
+
return getSelectionText({
|
|
472
|
+
value,
|
|
473
|
+
selection: {
|
|
474
|
+
anchor: startPoint,
|
|
475
|
+
focus: point
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
}
|
|
413
479
|
function createMarkdownBehaviors(config) {
|
|
414
480
|
const automaticBlockquoteOnSpace = {
|
|
415
481
|
on: "insert text",
|
|
@@ -482,11 +548,24 @@ function createMarkdownBehaviors(config) {
|
|
|
482
548
|
}), focusBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context);
|
|
483
549
|
if (!hrObject || !focusBlock || !selectionCollapsed)
|
|
484
550
|
return !1;
|
|
485
|
-
const
|
|
486
|
-
|
|
551
|
+
const textBefore = getBlockTextBefore({
|
|
552
|
+
value: context.value,
|
|
553
|
+
point: context.selection.focus
|
|
554
|
+
}), hrBlockOffsets = {
|
|
555
|
+
anchor: {
|
|
556
|
+
path: focusBlock.path,
|
|
557
|
+
offset: 0
|
|
558
|
+
},
|
|
559
|
+
focus: {
|
|
560
|
+
path: focusBlock.path,
|
|
561
|
+
offset: 3
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
return textBefore === `${hrCharacter}${hrCharacter}` ? {
|
|
487
565
|
hrObject,
|
|
488
566
|
focusBlock,
|
|
489
|
-
hrCharacter
|
|
567
|
+
hrCharacter,
|
|
568
|
+
hrBlockOffsets
|
|
490
569
|
} : !1;
|
|
491
570
|
},
|
|
492
571
|
actions: [(_, {
|
|
@@ -496,17 +575,14 @@ function createMarkdownBehaviors(config) {
|
|
|
496
575
|
text: hrCharacter
|
|
497
576
|
}], (_, {
|
|
498
577
|
hrObject,
|
|
499
|
-
|
|
578
|
+
hrBlockOffsets
|
|
500
579
|
}) => [{
|
|
501
580
|
type: "insert block object",
|
|
502
|
-
placement: "
|
|
581
|
+
placement: "before",
|
|
503
582
|
blockObject: hrObject
|
|
504
583
|
}, {
|
|
505
|
-
type: "delete
|
|
506
|
-
|
|
507
|
-
}, {
|
|
508
|
-
type: "insert text block",
|
|
509
|
-
placement: "after"
|
|
584
|
+
type: "delete text",
|
|
585
|
+
...hrBlockOffsets
|
|
510
586
|
}]]
|
|
511
587
|
}, automaticHrOnPaste = {
|
|
512
588
|
on: "paste",
|
|
@@ -672,9 +748,9 @@ function createMarkdownBehaviors(config) {
|
|
|
672
748
|
listItemLength: 1,
|
|
673
749
|
style: defaultStyle
|
|
674
750
|
};
|
|
675
|
-
const looksLikeOrderedList = /^1
|
|
751
|
+
const looksLikeOrderedList = /^1\./.test(blockText), orderedListStyle = config.orderedListStyle?.({
|
|
676
752
|
schema: context.schema
|
|
677
|
-
}), caretAtTheEndOfOrderedList =
|
|
753
|
+
}), caretAtTheEndOfOrderedList = blockOffset.offset === 2;
|
|
678
754
|
return defaultStyle && caretAtTheEndOfOrderedList && looksLikeOrderedList && orderedListStyle !== void 0 ? {
|
|
679
755
|
focusTextBlock,
|
|
680
756
|
listItem: orderedListStyle,
|
|
@@ -4106,6 +4182,21 @@ function createWithPortableTextLists(types2) {
|
|
|
4106
4182
|
}, editor;
|
|
4107
4183
|
};
|
|
4108
4184
|
}
|
|
4185
|
+
function isPortableTextSpan(node) {
|
|
4186
|
+
return node._type === "span" && "text" in node && typeof node.text == "string" && (typeof node.marks > "u" || Array.isArray(node.marks) && node.marks.every((mark) => typeof mark == "string"));
|
|
4187
|
+
}
|
|
4188
|
+
function isPortableTextBlock(node) {
|
|
4189
|
+
return (
|
|
4190
|
+
// A block doesn't _have_ to be named 'block' - to differentiate between
|
|
4191
|
+
// allowed child types and marks, one might name them differently
|
|
4192
|
+
typeof node._type == "string" && // Toolkit-types like nested spans are @-prefixed
|
|
4193
|
+
node._type[0] !== "@" && // `markDefs` isn't _required_ per say, but if it's there, it needs to be an array
|
|
4194
|
+
(!("markDefs" in node) || !node.markDefs || Array.isArray(node.markDefs) && // Every mark definition needs to have an `_key` to be mappable in child spans
|
|
4195
|
+
node.markDefs.every((def) => typeof def._key == "string")) && // `children` is required and needs to be an array
|
|
4196
|
+
"children" in node && Array.isArray(node.children) && // All children are objects with `_type` (usually spans, but can contain other stuff)
|
|
4197
|
+
node.children.every((child) => typeof child == "object" && "_type" in child)
|
|
4198
|
+
);
|
|
4199
|
+
}
|
|
4109
4200
|
function getPreviousSpan({
|
|
4110
4201
|
editor,
|
|
4111
4202
|
blockPath,
|
|
@@ -4831,8 +4922,9 @@ function insertBlock({
|
|
|
4831
4922
|
offset: 0
|
|
4832
4923
|
}
|
|
4833
4924
|
});
|
|
4834
|
-
} else
|
|
4835
|
-
|
|
4925
|
+
} else placement === "before" ? slate.Transforms.insertNodes(editor, block, {
|
|
4926
|
+
at: focusBlockPath
|
|
4927
|
+
}) : slate.Editor.insertNode(editor, block);
|
|
4836
4928
|
focusBlock && isEqualToEmptyEditor([focusBlock], schema2) && slate.Transforms.removeNodes(editor, {
|
|
4837
4929
|
at: focusBlockPath
|
|
4838
4930
|
});
|