@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.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 onlyText = focusBlock.node.children.every(isPortableTextSpan), blockText = focusBlock.node.children.map((child) => child.text ?? "").join("");
486
- return onlyText && blockText === `${hrCharacter}${hrCharacter}` ? {
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
- focusBlock
578
+ hrBlockOffsets
500
579
  }) => [{
501
580
  type: "insert block object",
502
- placement: "after",
581
+ placement: "before",
503
582
  blockObject: hrObject
504
583
  }, {
505
- type: "delete block",
506
- blockPath: focusBlock.path
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./.test(focusSpan.node.text), orderedListStyle = config.orderedListStyle?.({
751
+ const looksLikeOrderedList = /^1\./.test(blockText), orderedListStyle = config.orderedListStyle?.({
676
752
  schema: context.schema
677
- }), caretAtTheEndOfOrderedList = context.selection.focus.offset === 2;
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
- slate.Editor.insertNode(editor, block);
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
  });