@portabletext/editor 1.2.0 → 1.2.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/index.js CHANGED
@@ -3347,6 +3347,9 @@ function createWithPortableTextLists(types2) {
3347
3347
  }, editor;
3348
3348
  };
3349
3349
  }
3350
+ function isPortableTextSpan(node) {
3351
+ 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"));
3352
+ }
3350
3353
  function isPortableTextBlock(node) {
3351
3354
  return (
3352
3355
  // A block doesn't _have_ to be named 'block' - to differentiate between
@@ -3512,6 +3515,71 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3512
3515
  apply2(op);
3513
3516
  return;
3514
3517
  }
3518
+ if (op.type === "set_selection" && slate.Editor.marks(editor) && op.properties && op.newProperties && op.properties.anchor && op.properties.focus && op.newProperties.anchor && op.newProperties.focus) {
3519
+ const previousSelectionIsCollapsed = slate.Range.isCollapsed({
3520
+ anchor: op.properties.anchor,
3521
+ focus: op.properties.focus
3522
+ }), newSelectionIsCollapsed = slate.Range.isCollapsed({
3523
+ anchor: op.newProperties.anchor,
3524
+ focus: op.newProperties.focus
3525
+ });
3526
+ if (previousSelectionIsCollapsed && newSelectionIsCollapsed) {
3527
+ const focusSpan = Array.from(
3528
+ slate.Editor.nodes(editor, {
3529
+ mode: "lowest",
3530
+ at: op.properties.focus,
3531
+ match: (n) => editor.isTextSpan(n),
3532
+ voids: !1
3533
+ })
3534
+ )[0]?.[0], newFocusSpan = Array.from(
3535
+ slate.Editor.nodes(editor, {
3536
+ mode: "lowest",
3537
+ at: op.newProperties.focus,
3538
+ match: (n) => editor.isTextSpan(n),
3539
+ voids: !1
3540
+ })
3541
+ )[0]?.[0], movedToNextSpan = focusSpan && newFocusSpan && op.newProperties.focus.path[0] === op.properties.focus.path[0] && op.newProperties.focus.path[1] === op.properties.focus.path[1] + 1 && focusSpan.text.length === op.properties.focus.offset && op.newProperties.focus.offset === 0, movedToPreviousSpan = focusSpan && newFocusSpan && op.newProperties.focus.path[0] === op.properties.focus.path[0] && op.newProperties.focus.path[1] === op.properties.focus.path[1] - 1 && op.properties.focus.offset === 0 && newFocusSpan.text.length === op.newProperties.focus.offset;
3542
+ if (movedToNextSpan || movedToPreviousSpan)
3543
+ return;
3544
+ }
3545
+ }
3546
+ if (op.type === "insert_node") {
3547
+ const { selection } = editor;
3548
+ if (selection) {
3549
+ const [_block, blockPath] = slate.Editor.node(editor, selection, { depth: 1 }), previousSpan = getPreviousSpan({
3550
+ editor,
3551
+ blockPath,
3552
+ spanPath: op.path
3553
+ }), previousSpanAnnotations = previousSpan ? previousSpan.marks?.filter((mark) => !decorators.includes(mark)) : [], nextSpan = getNextSpan({
3554
+ editor,
3555
+ blockPath,
3556
+ spanPath: [op.path[0], op.path[1] - 1]
3557
+ }), nextSpanAnnotations = nextSpan ? nextSpan.marks?.filter((mark) => !decorators.includes(mark)) : [], annotationsEnding = previousSpanAnnotations?.filter(
3558
+ (annotation) => !nextSpanAnnotations?.includes(annotation)
3559
+ ) ?? [];
3560
+ if (annotationsEnding.length > 0 && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsEnding.includes(mark))) {
3561
+ slate.Transforms.insertNodes(editor, {
3562
+ ...op.node,
3563
+ marks: op.node.marks?.filter(
3564
+ (mark) => !annotationsEnding.includes(mark)
3565
+ ) ?? []
3566
+ });
3567
+ return;
3568
+ }
3569
+ const annotationsStarting = nextSpanAnnotations?.filter(
3570
+ (annotation) => !previousSpanAnnotations?.includes(annotation)
3571
+ ) ?? [];
3572
+ if (annotationsStarting.length > 0 && isPortableTextSpan(op.node) && op.node.marks?.some((mark) => annotationsStarting.includes(mark))) {
3573
+ slate.Transforms.insertNodes(editor, {
3574
+ ...op.node,
3575
+ marks: op.node.marks?.filter(
3576
+ (mark) => !annotationsStarting.includes(mark)
3577
+ ) ?? []
3578
+ });
3579
+ return;
3580
+ }
3581
+ }
3582
+ }
3515
3583
  if (op.type === "insert_text") {
3516
3584
  const { selection } = editor, collapsedSelection = selection ? slate.Range.isCollapsed(selection) : !1;
3517
3585
  if (selection && collapsedSelection) {
@@ -3528,25 +3596,41 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3528
3596
  (mark) => decorators.includes(mark)
3529
3597
  ), spanHasAnnotations = marks.length > marksWithoutAnnotations.length, spanIsEmpty = span.text.length === 0, atTheBeginningOfSpan = selection.anchor.offset === 0, atTheEndOfSpan = selection.anchor.offset === span.text.length, previousSpan = getPreviousSpan({ editor, blockPath, spanPath }), nextSpan = getNextSpan({ editor, blockPath, spanPath }), nextSpanAnnotations = nextSpan?.marks?.filter((mark) => !decorators.includes(mark)) ?? [], spanAnnotations = marks.filter(
3530
3598
  (mark) => !decorators.includes(mark)
3531
- ), previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
3599
+ ), previousSpanHasAnnotations = previousSpan ? previousSpan.marks?.some((mark) => !decorators.includes(mark)) : !1, previousSpanHasSameAnnotations = previousSpan ? previousSpan.marks?.filter((mark) => !decorators.includes(mark)).every((mark) => marks.includes(mark)) : !1, previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
3532
3600
  (mark) => !decorators.includes(mark) && marks.includes(mark)
3533
3601
  ) : !1, previousSpanHasSameMarks = previousSpan ? previousSpan.marks?.every((mark) => marks.includes(mark)) : !1, nextSpanSharesSomeAnnotations = spanAnnotations.some(
3534
3602
  (mark) => nextSpanAnnotations?.includes(mark)
3535
3603
  );
3536
3604
  if (spanHasAnnotations && !spanIsEmpty) {
3537
3605
  if (atTheBeginningOfSpan) {
3538
- previousSpanHasSameMarks ? slate.Transforms.insertNodes(editor, {
3539
- _type: "span",
3540
- _key: editorActor.getSnapshot().context.keyGenerator(),
3541
- text: op.text,
3542
- marks: previousSpan?.marks ?? []
3543
- }) : previousSpanHasSameAnnotation ? apply2(op) : slate.Transforms.insertNodes(editor, {
3544
- _type: "span",
3545
- _key: editorActor.getSnapshot().context.keyGenerator(),
3546
- text: op.text,
3547
- marks: []
3548
- });
3549
- return;
3606
+ if (previousSpanHasSameMarks) {
3607
+ slate.Transforms.insertNodes(editor, {
3608
+ _type: "span",
3609
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3610
+ text: op.text,
3611
+ marks: previousSpan?.marks ?? []
3612
+ });
3613
+ return;
3614
+ } else if (previousSpanHasSameAnnotations) {
3615
+ slate.Transforms.insertNodes(editor, {
3616
+ _type: "span",
3617
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3618
+ text: op.text,
3619
+ marks: previousSpan?.marks ?? []
3620
+ });
3621
+ return;
3622
+ } else if (previousSpanHasSameAnnotation) {
3623
+ apply2(op);
3624
+ return;
3625
+ } else if (!previousSpan) {
3626
+ slate.Transforms.insertNodes(editor, {
3627
+ _type: "span",
3628
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3629
+ text: op.text,
3630
+ marks: []
3631
+ });
3632
+ return;
3633
+ }
3550
3634
  }
3551
3635
  if (atTheEndOfSpan) {
3552
3636
  if (nextSpan && nextSpanSharesSomeAnnotations && nextSpanAnnotations.length < spanAnnotations.length || !nextSpanSharesSomeAnnotations) {
@@ -3574,7 +3658,7 @@ function createWithPortableTextMarkModel(editorActor, types2) {
3574
3658
  _type: "span",
3575
3659
  _key: editorActor.getSnapshot().context.keyGenerator(),
3576
3660
  text: op.text,
3577
- marks: (previousSpan.marks ?? []).filter(
3661
+ marks: previousSpanHasAnnotations ? [] : (previousSpan.marks ?? []).filter(
3578
3662
  (mark) => decorators.includes(mark)
3579
3663
  )
3580
3664
  });