@portabletext/editor 7.7.0 → 7.8.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
@@ -5,11 +5,11 @@ import React, { createContext, useContext, useRef, useEffect, useLayoutEffect, u
5
5
  import { serializePath, isKeyedSegment, getNode, getParent, parentPath, getChildren, getNodeChildren } from "./_chunks-es/get-parent.js";
6
6
  import { isPath, getLeaf, isRange, isPoint, isObject, isLeafObject, getAncestor, pathContains, getSpan, isBeforePoint, getText, rangeIntersects, getTextBlock, getUnionSchema, getFirstChild } from "./_chunks-es/get-first-child.js";
7
7
  import { rangeEdges, isTextBlockNode, isBackwardRange, hasNode, getNodes, isAncestorPath, isEditableContainer, getSibling, isInline, isObject as isObject$1, isSpanNode, isBlock, getEnclosingBlock, getAncestors, getPathSubSchema, getBlock, resolveContainerAt, comparePaths, getEnclosingContainer, comparePoints$1 as comparePoints, isAfterPoint } from "./_chunks-es/get-path-sub-schema.js";
8
- import { isSpan, isTextBlock, compileSchema } from "@portabletext/schema";
8
+ import { isSpan, isTextBlock, getSubSchema, compileSchema } from "@portabletext/schema";
9
9
  import { defineSchema } from "@portabletext/schema";
10
10
  import scrollIntoView from "scroll-into-view-if-needed";
11
11
  import { createKeyboardShortcut, undo, redo, code, underline, italic as italic$1, bold as bold$1 } from "@portabletext/keyboard-shortcuts";
12
- import { rangesOverlap, getFocusInlineObject, isSelectionCollapsed as isSelectionCollapsed$1, getFocusTextBlock, getFocusSpan, getFragment, isSelectionExpanded, getSelectionStartBlock, getSelectionEndBlock, isOverlappingSelection, getFocusBlock, getSelectedBlocks, isSelectingEntireBlocks, getSelectedValue, isActiveAnnotation, getActiveAnnotationsMarks, getActiveDecorators, getCaretWordSelection, getSelectionStartChild, getSelectionEndChild, getPreviousSpan, getNextSpan, getSelectionStartPoint, getSelectionEndPoint, getFocusBlockObject, getLastBlock, getFirstBlock, isAtTheEndOfBlock, isAtTheStartOfBlock, getMarkState, getFocusListBlock, getNextBlock, getPreviousBlock, getSelectedTextBlocks, getRootAcceptedTypes, isActiveDecorator, getFocusChild, getActiveAnnotations, isActiveListItem, isActiveStyle } from "./_chunks-es/selector.is-at-the-start-of-block.js";
12
+ import { rangesOverlap, getFocusInlineObject, getFocusTextBlock, getFocusSpan, getFragment, isSelectionExpanded, getSelectionStartBlock, getSelectionEndBlock, isOverlappingSelection, isSelectionCollapsed as isSelectionCollapsed$1, getFocusBlock, getSelectedBlocks, isSelectingEntireBlocks, getSelectedValue, isActiveAnnotation, getActiveAnnotationsMarks, getActiveDecorators, getCaretWordSelection, getSelectionStartChild, getSelectionEndChild, getPreviousSpan, getNextSpan, getSelectionStartPoint, getSelectionEndPoint, getFocusBlockObject, getLastBlock, getFirstBlock, isAtTheEndOfBlock, isAtTheStartOfBlock, getRootAcceptedTypes, getMarkState, getFocusListBlock, getNextBlock, getPreviousBlock, getSelectedTextBlocks, isActiveDecorator, getFocusChild, getActiveAnnotations, isActiveListItem, isActiveStyle } from "./_chunks-es/selector.is-at-the-start-of-block.js";
13
13
  import { isEqualSelectionPoints, blockOffsetToSpanSelectionPoint, getBlockKeyFromSelectionPoint, getBlockEndPoint, getBlockStartPoint, isSelectionCollapsed, defaultKeyGenerator, parseBlocks, parseBlock, isListBlock, getSelectionStartPoint as getSelectionStartPoint$1, getSelectionEndPoint as getSelectionEndPoint$1, parseAnnotation, parseMarkDefs, parseSpan, parseInlineObject } from "./_chunks-es/util.slice-blocks.js";
14
14
  import rawDebug from "debug";
15
15
  import { isEmptyTextBlock, getTextBlockText } from "./_chunks-es/util.is-empty-text-block.js";
@@ -4046,6 +4046,9 @@ const debug = {
4046
4046
  syncValue: createDebugger("sync:value"),
4047
4047
  syncPatch: createDebugger("sync:patch")
4048
4048
  };
4049
+ function isDragEvent(event) {
4050
+ return "dataTransfer" in event;
4051
+ }
4049
4052
  function getEventPosition({
4050
4053
  editorActor,
4051
4054
  editorEngine,
@@ -4085,6 +4088,22 @@ function getEventPosition({
4085
4088
  }
4086
4089
  }
4087
4090
  };
4091
+ if (eventPositionBlock && !isEditor(eventNode) && isEditableContainer(editorEngine.snapshot, eventNode, eventPath) && isDragEvent(event))
4092
+ return {
4093
+ block: eventPositionBlock,
4094
+ isEditor: !1,
4095
+ isContainer: !0,
4096
+ selection: {
4097
+ anchor: {
4098
+ path: eventPath,
4099
+ offset: 0
4100
+ },
4101
+ focus: {
4102
+ path: eventPath,
4103
+ offset: 0
4104
+ }
4105
+ }
4106
+ };
4088
4107
  if (eventBlock && eventBlockPath && eventPositionBlock && !eventSelection && !isEventContainer(editorEngine, eventNode, eventPath))
4089
4108
  return {
4090
4109
  block: eventPositionBlock,
@@ -4227,16 +4246,6 @@ function getSelectionFromEvent(editor, event) {
4227
4246
  function isEventContainer(editorEngine, eventNode, eventPath) {
4228
4247
  return isEditor(eventNode) ? !0 : isEditableContainer(editorEngine.snapshot, eventNode, eventPath);
4229
4248
  }
4230
- function createEditorPriority(config) {
4231
- return {
4232
- id: defaultKeyGenerator(),
4233
- name: config?.name,
4234
- reference: config?.reference
4235
- };
4236
- }
4237
- const corePriority = createEditorPriority({
4238
- name: "core"
4239
- });
4240
4249
  function getDragSelection({
4241
4250
  eventSelection,
4242
4251
  snapshot
@@ -4306,6 +4315,16 @@ function getDragSelection({
4306
4315
  }
4307
4316
  return dragSelection;
4308
4317
  }
4318
+ function createEditorPriority(config) {
4319
+ return {
4320
+ id: defaultKeyGenerator(),
4321
+ name: config?.name,
4322
+ reference: config?.reference
4323
+ };
4324
+ }
4325
+ const corePriority = createEditorPriority({
4326
+ name: "core"
4327
+ });
4309
4328
  function createDropPositionBehaviorsConfig({
4310
4329
  setDropPosition
4311
4330
  }) {
@@ -6027,7 +6046,7 @@ function RenderLeaf(props) {
6027
6046
  }
6028
6047
  function RenderText(props) {
6029
6048
  const $ = c(10);
6030
- if (useContext(ParentContainerContext)) {
6049
+ if (useContext(NewPipelineContext)) {
6031
6050
  const t02 = props.attributes;
6032
6051
  let rest;
6033
6052
  if ($[0] !== t02) {
@@ -6123,7 +6142,7 @@ function validateSelection(editorEngine, editorElement) {
6123
6142
  const newDOMRange = DOMEditor.toDOMRange(editorEngine, editorEngine.snapshot.context.selection);
6124
6143
  (newDOMRange.startOffset !== existingDOMRange.startOffset || newDOMRange.endOffset !== existingDOMRange.endOffset) && (debug.selection("DOM range out of sync, validating selection"), domSelection?.removeAllRanges(), domSelection.addRange(newDOMRange));
6125
6144
  } catch {
6126
- debug.selection("Could not resolve selection, selecting top document"), applyDeselect(editorEngine), editorEngine.snapshot.context.value.length > 0 && applySelect(editorEngine, start(editorEngine, [])), editorEngine.onChange();
6145
+ debug.selection("Could not resolve selection, skipping DOM sync this tick");
6127
6146
  }
6128
6147
  }
6129
6148
  const PortableTextEditable = forwardRef(function(props, forwardedRef) {
@@ -6515,9 +6534,16 @@ const PortableTextEditable = forwardRef(function(props, forwardedRef) {
6515
6534
  console.warn("Could not find position for dragstart event");
6516
6535
  return;
6517
6536
  }
6537
+ const dragPosition = {
6538
+ ...position_4,
6539
+ selection: getDragSelection({
6540
+ snapshot: editorEngine.snapshot,
6541
+ eventSelection: position_4.selection
6542
+ })
6543
+ };
6518
6544
  return editorActor.send({
6519
6545
  type: "dragstart",
6520
- origin: position_4
6546
+ origin: dragPosition
6521
6547
  }), editorActor.send({
6522
6548
  type: "behavior event",
6523
6549
  behaviorEvent: {
@@ -6527,7 +6553,7 @@ const PortableTextEditable = forwardRef(function(props, forwardedRef) {
6527
6553
  clientY: event_8.clientY,
6528
6554
  dataTransfer: event_8.dataTransfer
6529
6555
  },
6530
- position: position_4
6556
+ position: dragPosition
6531
6557
  },
6532
6558
  editor: editorEngine
6533
6559
  }), !0;
@@ -11389,7 +11415,39 @@ function getCompoundClientRect(nodes) {
11389
11415
  }
11390
11416
  return new DOMRect(left, top, right - left, bottom - top);
11391
11417
  }
11418
+ function fitBlocksToDestination(snapshot, blocks) {
11419
+ if (blocks.length === 0)
11420
+ return [];
11421
+ const startBlock = getSelectionStartBlock(snapshot);
11422
+ if (!startBlock)
11423
+ return [...blocks];
11424
+ const resolvedAt = resolveContainerAt(snapshot.context.containers, snapshot.context.value, startBlock.path), subSchema = resolvedAt && "field" in resolvedAt && resolvedAt.of ? getSubSchema(snapshot.context.schema, resolvedAt.of) : getPathSubSchema(snapshot, startBlock.path), accepted = getRootAcceptedTypes(subSchema);
11425
+ if (accepted.size === 0)
11426
+ return [];
11427
+ const result = [];
11428
+ for (const block of blocks)
11429
+ fitOne(block, accepted, result);
11430
+ return result;
11431
+ }
11432
+ function fitOne(block, accepted, out) {
11433
+ if (accepted.has(block._type)) {
11434
+ out.push(block);
11435
+ return;
11436
+ }
11437
+ for (const value of Object.values(block))
11438
+ if (Array.isArray(value))
11439
+ for (const child of value)
11440
+ isBlockLike(child) && fitOne(child, accepted, out);
11441
+ }
11442
+ function isBlockLike(value) {
11443
+ return typeof value == "object" && value !== null && "_type" in value && typeof value._type == "string";
11444
+ }
11392
11445
  function isDropTargetingDragOrigin(dropSelection, dragOriginSelection, snapshot) {
11446
+ if (isCollapsedRange(dragOriginSelection)) {
11447
+ const originPath = dragOriginSelection.anchor.path;
11448
+ if (isAncestorPath(originPath, dropSelection.anchor.path) || isAncestorPath(originPath, dropSelection.focus.path))
11449
+ return !0;
11450
+ }
11393
11451
  if (!isOverlappingSelection(dropSelection)({
11394
11452
  ...snapshot,
11395
11453
  context: {
@@ -11428,25 +11486,18 @@ const coreDndBehaviors = [
11428
11486
  ...snapshot.context,
11429
11487
  selection: dragSelection
11430
11488
  }
11431
- }), draggedDomNodes = {
11432
- blockNodes: dom.getBlockNodes({
11433
- ...snapshot,
11434
- context: {
11435
- ...snapshot.context,
11436
- selection: dragSelection
11437
- }
11438
- }),
11439
- childNodes: dom.getChildNodes({
11440
- ...snapshot,
11441
- context: {
11442
- ...snapshot.context,
11443
- selection: dragSelection
11444
- }
11445
- })
11489
+ }), dragSnapshot = {
11490
+ ...snapshot,
11491
+ context: {
11492
+ ...snapshot.context,
11493
+ selection: dragSelection
11494
+ }
11446
11495
  };
11447
11496
  return {
11448
- dragSelection,
11449
- draggedDomNodes,
11497
+ draggedDomNodes: {
11498
+ blockNodes: dom.getBlockNodes(dragSnapshot),
11499
+ childNodes: dom.getChildNodes(dragSnapshot)
11500
+ },
11450
11501
  selectingEntireBlocks
11451
11502
  };
11452
11503
  },
@@ -11454,7 +11505,6 @@ const coreDndBehaviors = [
11454
11505
  dom,
11455
11506
  event
11456
11507
  }, {
11457
- dragSelection,
11458
11508
  draggedDomNodes,
11459
11509
  selectingEntireBlocks
11460
11510
  }) => {
@@ -11466,10 +11516,7 @@ const coreDndBehaviors = [
11466
11516
  const customGhost = dragGhost.querySelector("[data-pt-drag-ghost-element]");
11467
11517
  if (customGhost && dragGhost.replaceChildren(customGhost), dragGhost.setAttribute("data-dragged", ""), dragGhost.style.position = "absolute", dragGhost.style.left = "-99999px", dragGhost.style.boxSizing = "border-box", document.body.appendChild(dragGhost), customGhost) {
11468
11518
  const customGhostRect = customGhost.getBoundingClientRect(), x = event.originEvent.clientX - customGhostRect.left, y = event.originEvent.clientY - customGhostRect.top;
11469
- return dragGhost.style.width = `${customGhostRect.width}px`, dragGhost.style.height = `${customGhostRect.height}px`, [raise({
11470
- type: "select",
11471
- at: dragSelection
11472
- }), effect(() => {
11519
+ return dragGhost.style.width = `${customGhostRect.width}px`, dragGhost.style.height = `${customGhostRect.height}px`, [effect(() => {
11473
11520
  dom.setDragGhost({
11474
11521
  event,
11475
11522
  ghost: {
@@ -11481,10 +11528,7 @@ const coreDndBehaviors = [
11481
11528
  }), forward(event)];
11482
11529
  } else {
11483
11530
  const blocksDomRect = getCompoundClientRect(draggedDomNodes.blockNodes), x = event.originEvent.clientX - blocksDomRect.left, y = event.originEvent.clientY - blocksDomRect.top;
11484
- return dragGhost.style.width = `${blocksDomRect.width}px`, dragGhost.style.height = `${blocksDomRect.height}px`, [raise({
11485
- type: "select",
11486
- at: dragSelection
11487
- }), effect(() => {
11531
+ return dragGhost.style.width = `${blocksDomRect.width}px`, dragGhost.style.height = `${blocksDomRect.height}px`, [effect(() => {
11488
11532
  dom.setDragGhost({
11489
11533
  event,
11490
11534
  ghost: {
@@ -11501,10 +11545,7 @@ const coreDndBehaviors = [
11501
11545
  dragGhost.appendChild(child);
11502
11546
  dragGhost.style.position = "absolute", dragGhost.style.left = "-99999px", dragGhost.style.boxSizing = "border-box", document.body.appendChild(dragGhost);
11503
11547
  const childrenDomRect = getCompoundClientRect(draggedDomNodes.childNodes), x = event.originEvent.clientX - childrenDomRect.left, y = event.originEvent.clientY - childrenDomRect.top;
11504
- return dragGhost.style.width = `${childrenDomRect.width}px`, dragGhost.style.height = `${childrenDomRect.height}px`, [raise({
11505
- type: "select",
11506
- at: dragSelection
11507
- }), effect(() => {
11548
+ return dragGhost.style.width = `${childrenDomRect.width}px`, dragGhost.style.height = `${childrenDomRect.height}px`, [effect(() => {
11508
11549
  dom.setDragGhost({
11509
11550
  event,
11510
11551
  ghost: {
@@ -11593,48 +11634,52 @@ const coreDndBehaviors = [
11593
11634
  const dragOrigin = event.originEvent.dragOrigin, dragSelection = getDragSelection({
11594
11635
  eventSelection: dragOrigin.selection,
11595
11636
  snapshot
11596
- }), dropPosition = event.originEvent.position.selection, droppingOnDragOrigin = dragOrigin ? isDropTargetingDragOrigin(dropPosition, dragSelection, snapshot) : !1, draggingEntireBlocks = isSelectingEntireBlocks({
11637
+ }), dropPosition = event.originEvent.position.selection, droppingOnDragOrigin = dragOrigin ? isDropTargetingDragOrigin(dropPosition, dragSelection, snapshot) : !1, dragSnapshot = {
11597
11638
  ...snapshot,
11598
11639
  context: {
11599
11640
  ...snapshot.context,
11600
11641
  selection: dragSelection
11601
11642
  }
11602
- }), draggedBlocks = getFragment({
11643
+ }, draggingEntireBlocks = isSelectingEntireBlocks(dragSnapshot), draggedNodes = getFragment(dragSnapshot), fittedBlocks = fitBlocksToDestination({
11644
+ ...snapshot,
11603
11645
  context: {
11604
11646
  ...snapshot.context,
11605
- selection: dragSelection
11647
+ selection: dropPosition
11606
11648
  }
11607
- });
11649
+ }, event.data);
11608
11650
  return droppingOnDragOrigin ? !1 : {
11609
11651
  dropPosition,
11610
11652
  draggingEntireBlocks,
11611
- draggedBlocks,
11653
+ draggedNodes,
11612
11654
  dragOrigin,
11613
- originEvent: event.originEvent
11655
+ originEvent: event.originEvent,
11656
+ fittedBlocks
11614
11657
  };
11615
11658
  },
11616
- actions: [({
11617
- event
11618
- }, {
11659
+ actions: [(_, {
11619
11660
  draggingEntireBlocks,
11620
- draggedBlocks,
11661
+ draggedNodes,
11621
11662
  dragOrigin,
11622
11663
  dropPosition,
11623
- originEvent
11624
- }) => [raise({
11625
- type: "select",
11626
- at: dropPosition
11627
- }), ...draggingEntireBlocks ? draggedBlocks.map((block) => raise({
11628
- type: "delete.block",
11629
- at: block.path
11630
- })) : [raise({
11631
- type: "delete",
11632
- at: dragOrigin.selection
11633
- })], raise({
11634
- type: "insert.blocks",
11635
- blocks: event.data,
11636
- placement: draggingEntireBlocks ? originEvent.position.block === "start" ? "before" : originEvent.position.block === "end" ? "after" : "auto" : "auto"
11637
- })]]
11664
+ originEvent,
11665
+ fittedBlocks
11666
+ }) => {
11667
+ const deleteEvents = draggingEntireBlocks ? draggedNodes.map((entry) => raise({
11668
+ type: "unset",
11669
+ at: entry.path
11670
+ })) : [raise({
11671
+ type: "delete",
11672
+ at: dragOrigin.selection
11673
+ })];
11674
+ return [raise({
11675
+ type: "select",
11676
+ at: dropPosition
11677
+ }), ...deleteEvents, raise({
11678
+ type: "insert.blocks",
11679
+ blocks: fittedBlocks,
11680
+ placement: draggingEntireBlocks ? originEvent.position.block === "start" ? "before" : originEvent.position.block === "end" ? "after" : "auto" : "auto"
11681
+ })];
11682
+ }]
11638
11683
  })
11639
11684
  ], coreInsertBehaviors = [defineBehavior({
11640
11685
  on: "insert.text",
@@ -14850,35 +14895,7 @@ const abstractAnnotationBehaviors = [defineBehavior({
14850
14895
  ...event,
14851
14896
  type: "delete"
14852
14897
  })]]
14853
- })];
14854
- function fitBlocksToDestination(snapshot, blocks) {
14855
- if (blocks.length === 0)
14856
- return [];
14857
- const startBlock = getSelectionStartBlock(snapshot);
14858
- if (!startBlock)
14859
- return [...blocks];
14860
- const subSchema = getPathSubSchema(snapshot, startBlock.path), accepted = getRootAcceptedTypes(subSchema);
14861
- if (accepted.size === 0)
14862
- return [];
14863
- const result = [];
14864
- for (const block of blocks)
14865
- fitOne(block, accepted, result);
14866
- return result;
14867
- }
14868
- function fitOne(block, accepted, out) {
14869
- if (accepted.has(block._type)) {
14870
- out.push(block);
14871
- return;
14872
- }
14873
- for (const value of Object.values(block))
14874
- if (Array.isArray(value))
14875
- for (const child of value)
14876
- isBlockLike(child) && fitOne(child, accepted, out);
14877
- }
14878
- function isBlockLike(value) {
14879
- return typeof value == "object" && value !== null && "_type" in value && typeof value._type == "string";
14880
- }
14881
- const mimeTypePriority = ["application/x-portable-text", "application/json", "text/markdown", "text/html", "text/plain"];
14898
+ })], mimeTypePriority = ["application/x-portable-text", "application/json", "text/markdown", "text/html", "text/plain"];
14882
14899
  function getFirstAvailableData({
14883
14900
  dataTransfer,
14884
14901
  startAfter
@@ -16052,13 +16069,22 @@ const abstractInsertBehaviors = [
16052
16069
  event
16053
16070
  }) => {
16054
16071
  const converter = snapshot.context.converters.find((converter2) => converter2.mimeType === event.mimeType);
16055
- return converter ? converter.serialize({
16056
- snapshot,
16072
+ if (!converter)
16073
+ return !1;
16074
+ const snapshotForConverter = event.originEvent.type === "drag.dragstart" ? {
16075
+ ...snapshot,
16076
+ context: {
16077
+ ...snapshot.context,
16078
+ selection: event.originEvent.position.selection
16079
+ }
16080
+ } : snapshot;
16081
+ return converter.serialize({
16082
+ snapshot: snapshotForConverter,
16057
16083
  event: {
16058
16084
  type: "serialize",
16059
16085
  originEvent: event.originEvent.type
16060
16086
  }
16061
- }) : !1;
16087
+ });
16062
16088
  },
16063
16089
  actions: [({
16064
16090
  event