@portabletext/editor 1.27.0 → 1.30.0

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.
Files changed (79) hide show
  1. package/README.md +5 -5
  2. package/lib/_chunks-cjs/behavior.core.cjs +40 -37
  3. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  4. package/lib/_chunks-cjs/parse-blocks.cjs +79 -0
  5. package/lib/_chunks-cjs/parse-blocks.cjs.map +1 -0
  6. package/lib/_chunks-cjs/plugin.event-listener.cjs +357 -140
  7. package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -1
  8. package/lib/_chunks-cjs/selector.get-selection-start-point.cjs +15 -0
  9. package/lib/_chunks-cjs/selector.get-selection-start-point.cjs.map +1 -0
  10. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +88 -88
  11. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -1
  12. package/lib/_chunks-es/behavior.core.js +40 -37
  13. package/lib/_chunks-es/behavior.core.js.map +1 -1
  14. package/lib/_chunks-es/parse-blocks.js +80 -0
  15. package/lib/_chunks-es/parse-blocks.js.map +1 -0
  16. package/lib/_chunks-es/plugin.event-listener.js +359 -141
  17. package/lib/_chunks-es/plugin.event-listener.js.map +1 -1
  18. package/lib/_chunks-es/selector.get-selection-start-point.js +16 -0
  19. package/lib/_chunks-es/selector.get-selection-start-point.js.map +1 -0
  20. package/lib/_chunks-es/selector.is-at-the-start-of-block.js +88 -88
  21. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
  22. package/lib/behaviors/index.d.cts +196 -124
  23. package/lib/behaviors/index.d.ts +196 -124
  24. package/lib/index.cjs +22 -21
  25. package/lib/index.cjs.map +1 -1
  26. package/lib/index.d.cts +505 -0
  27. package/lib/index.d.ts +505 -0
  28. package/lib/index.js +22 -21
  29. package/lib/index.js.map +1 -1
  30. package/lib/plugins/index.cjs +249 -1
  31. package/lib/plugins/index.cjs.map +1 -1
  32. package/lib/plugins/index.d.cts +246 -1
  33. package/lib/plugins/index.d.ts +246 -1
  34. package/lib/plugins/index.js +257 -3
  35. package/lib/plugins/index.js.map +1 -1
  36. package/lib/selectors/index.cjs +42 -3
  37. package/lib/selectors/index.cjs.map +1 -1
  38. package/lib/selectors/index.d.cts +39 -0
  39. package/lib/selectors/index.d.ts +39 -0
  40. package/lib/selectors/index.js +45 -4
  41. package/lib/selectors/index.js.map +1 -1
  42. package/lib/utils/index.cjs +70 -1
  43. package/lib/utils/index.cjs.map +1 -1
  44. package/lib/utils/index.d.cts +168 -2
  45. package/lib/utils/index.d.ts +168 -2
  46. package/lib/utils/index.js +71 -1
  47. package/lib/utils/index.js.map +1 -1
  48. package/package.json +4 -4
  49. package/src/behavior-actions/behavior.action.delete.ts +18 -0
  50. package/src/behavior-actions/behavior.action.insert-break.ts +96 -91
  51. package/src/behavior-actions/behavior.actions.ts +9 -0
  52. package/src/behaviors/_exports/index.ts +1 -0
  53. package/src/behaviors/behavior.core.deserialize.ts +52 -38
  54. package/src/behaviors/behavior.core.ts +4 -11
  55. package/src/behaviors/behavior.types.ts +4 -0
  56. package/src/editor/PortableTextEditor.tsx +308 -1
  57. package/src/editor/components/DefaultObject.tsx +21 -0
  58. package/src/editor/components/Element.tsx +5 -5
  59. package/src/editor/components/Leaf.tsx +1 -6
  60. package/src/internal-utils/__tests__/patchToOperations.test.ts +19 -21
  61. package/src/internal-utils/applyPatch.ts +11 -3
  62. package/src/plugins/index.ts +2 -0
  63. package/src/plugins/plugin.behavior.tsx +22 -0
  64. package/src/plugins/plugin.one-line.tsx +225 -0
  65. package/src/selectors/index.ts +7 -2
  66. package/src/selectors/selector.get-active-annotations.test.ts +122 -0
  67. package/src/selectors/selector.get-active-annotations.ts +30 -0
  68. package/src/selectors/selector.get-selection-end-point.ts +17 -0
  69. package/src/selectors/selector.get-selection-start-point.ts +17 -0
  70. package/src/selectors/selector.get-selection.ts +8 -0
  71. package/src/selectors/selector.get-value.ts +11 -0
  72. package/src/selectors/selector.is-overlapping-selection.ts +46 -0
  73. package/src/utils/index.ts +4 -0
  74. package/src/utils/util.is-span.ts +12 -0
  75. package/src/utils/util.is-text-block.ts +12 -0
  76. package/src/utils/util.merge-text-blocks.ts +36 -0
  77. package/src/utils/util.split-text-block.ts +55 -0
  78. package/src/editor/nodes/DefaultAnnotation.tsx +0 -20
  79. package/src/editor/nodes/DefaultObject.tsx +0 -18
@@ -1,14 +1,25 @@
1
- import { getActiveListItem, getActiveStyle, getFirstBlock, getFocusBlock, getFocusBlockObject, getFocusChild, getFocusListBlock, getFocusSpan, getFocusTextBlock, getLastBlock, getNextBlock, getPreviousBlock, getSelectedBlocks, getSelectedSpans, getSelectionEndBlock, getSelectionStartBlock, isActiveAnnotation, isActiveDecorator, isActiveListItem, isActiveStyle, isAtTheEndOfBlock, isAtTheStartOfBlock, isSelectionCollapsed, isSelectionExpanded } from "../_chunks-es/selector.is-at-the-start-of-block.js";
1
+ import { isPortableTextTextBlock, isKeySegment } from "@sanity/types";
2
+ import { getSelectedBlocks, getSelectedSpans } from "../_chunks-es/selector.is-at-the-start-of-block.js";
3
+ import { getActiveListItem, getActiveStyle, getFirstBlock, getFocusBlock, getFocusBlockObject, getFocusChild, getFocusListBlock, getFocusSpan, getFocusTextBlock, getLastBlock, getNextBlock, getPreviousBlock, getSelectionEndBlock, getSelectionStartBlock, isActiveAnnotation, isActiveDecorator, isActiveListItem, isActiveStyle, isAtTheEndOfBlock, isAtTheStartOfBlock, isSelectionCollapsed, isSelectionExpanded } from "../_chunks-es/selector.is-at-the-start-of-block.js";
2
4
  import { sliceBlocks } from "../_chunks-es/util.slice-blocks.js";
5
+ import { getSelectionStartPoint, getSelectionEndPoint } from "../_chunks-es/selector.get-selection-start-point.js";
3
6
  import { getBlockTextBefore, getSelectionText } from "../_chunks-es/selector.get-text-before.js";
4
- import { isKeySegment, isPortableTextTextBlock } from "@sanity/types";
5
7
  import { reverseSelection } from "../_chunks-es/util.reverse-selection.js";
6
- const getSelectedSlice = ({
8
+ const getActiveAnnotations = (snapshot) => {
9
+ if (!snapshot.context.selection)
10
+ return [];
11
+ const selectedBlocks = getSelectedBlocks(snapshot), selectedSpans = getSelectedSpans(snapshot);
12
+ return selectedSpans.length === 0 ? [] : selectedBlocks.flatMap((block) => isPortableTextTextBlock(block.node) ? block.node.markDefs ?? [] : []).filter((markDef) => selectedSpans.some((span) => span.node.marks?.includes(markDef._key)));
13
+ }, getSelectedSlice = ({
7
14
  context
8
15
  }) => sliceBlocks({
9
16
  blocks: context.value,
10
17
  selection: context.selection
11
- });
18
+ }), getSelection = ({
19
+ context
20
+ }) => context.selection, getValue = ({
21
+ context
22
+ }) => context.value;
12
23
  function isPointAfterSelection(point) {
13
24
  return (snapshot) => {
14
25
  if (!snapshot.context.selection)
@@ -79,7 +90,32 @@ function isPointBeforeSelection(point) {
79
90
  return before;
80
91
  };
81
92
  }
93
+ function isOverlappingSelection(selection) {
94
+ return ({
95
+ context
96
+ }) => {
97
+ if (!selection || !context.selection)
98
+ return !1;
99
+ const selectionStartPoint = getSelectionStartPoint({
100
+ context: {
101
+ ...context,
102
+ selection
103
+ }
104
+ }), selectionEndPoint = getSelectionEndPoint({
105
+ context: {
106
+ ...context,
107
+ selection
108
+ }
109
+ });
110
+ return !(!selectionStartPoint || !selectionEndPoint || !isPointAfterSelection(selectionStartPoint)({
111
+ context
112
+ }) || !isPointBeforeSelection(selectionEndPoint)({
113
+ context
114
+ }));
115
+ };
116
+ }
82
117
  export {
118
+ getActiveAnnotations,
83
119
  getActiveListItem,
84
120
  getActiveStyle,
85
121
  getBlockTextBefore,
@@ -96,15 +132,20 @@ export {
96
132
  getSelectedBlocks,
97
133
  getSelectedSlice,
98
134
  getSelectedSpans,
135
+ getSelection,
99
136
  getSelectionEndBlock,
137
+ getSelectionEndPoint,
100
138
  getSelectionStartBlock,
139
+ getSelectionStartPoint,
101
140
  getSelectionText,
141
+ getValue,
102
142
  isActiveAnnotation,
103
143
  isActiveDecorator,
104
144
  isActiveListItem,
105
145
  isActiveStyle,
106
146
  isAtTheEndOfBlock,
107
147
  isAtTheStartOfBlock,
148
+ isOverlappingSelection,
108
149
  isPointAfterSelection,
109
150
  isPointBeforeSelection,
110
151
  isSelectionCollapsed,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["getSelectedSlice","context","sliceBlocks","blocks","value","selection","isPointAfterSelection","point","snapshot","reverseSelection","pointBlockKey","isKeySegment","path","_key","undefined","pointChildKey","endBlockKey","focus","endChildKey","after","block","isPortableTextTextBlock","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-active-annotations.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selection.ts","../../src/selectors/selector.get-value.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts","../../src/selectors/selector.is-overlapping-selection.ts"],"sourcesContent":["import {isPortableTextTextBlock, type PortableTextObject} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return []\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectionMarkDefs.filter((markDef) =>\n selectedSpans.some((span) => span.node.marks?.includes(markDef._key)),\n )\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import type {EditorSelection, EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getSelection: EditorSelector<EditorSelection> = ({context}) => {\n return context.selection\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getValue: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return context.value\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n","import type {EditorSelection} from '../types/editor'\nimport type {EditorSelector} from './../editor/editor-selector'\nimport {getSelectionEndPoint} from './selector.get-selection-end-point'\nimport {getSelectionStartPoint} from './selector.get-selection-start-point'\nimport {isPointAfterSelection} from './selector.is-point-after-selection'\nimport {isPointBeforeSelection} from './selector.is-point-before-selection'\n\n/**\n * @public\n */\nexport function isOverlappingSelection(\n selection: EditorSelection,\n): EditorSelector<boolean> {\n return ({context}) => {\n if (!selection || !context.selection) {\n return false\n }\n\n const selectionStartPoint = getSelectionStartPoint({\n context: {\n ...context,\n selection,\n },\n })\n const selectionEndPoint = getSelectionEndPoint({\n context: {\n ...context,\n selection,\n },\n })\n\n if (!selectionStartPoint || !selectionEndPoint) {\n return false\n }\n\n if (!isPointAfterSelection(selectionStartPoint)({context})) {\n return false\n }\n\n if (!isPointBeforeSelection(selectionEndPoint)({context})) {\n return false\n }\n\n return true\n }\n}\n"],"names":["getActiveAnnotations","snapshot","context","selection","selectedBlocks","getSelectedBlocks","selectedSpans","getSelectedSpans","length","flatMap","block","isPortableTextTextBlock","node","markDefs","filter","markDef","some","span","marks","includes","_key","getSelectedSlice","sliceBlocks","blocks","value","getSelection","getValue","isPointAfterSelection","point","reverseSelection","pointBlockKey","isKeySegment","path","undefined","pointChildKey","endBlockKey","focus","endChildKey","after","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before","isOverlappingSelection","selectionStartPoint","getSelectionStartPoint","selectionEndPoint","getSelectionEndPoint"],"mappings":"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"}
@@ -1,6 +1,71 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var util_isEmptyTextBlock = require("../_chunks-cjs/util.is-empty-text-block.cjs"), util_isEqualSelectionPoints = require("../_chunks-cjs/util.is-equal-selection-points.cjs"), util_reverseSelection = require("../_chunks-cjs/util.reverse-selection.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs");
3
+ var util_isEmptyTextBlock = require("../_chunks-cjs/util.is-empty-text-block.cjs"), util_isEqualSelectionPoints = require("../_chunks-cjs/util.is-equal-selection-points.cjs"), parseBlocks = require("../_chunks-cjs/parse-blocks.cjs"), util_reverseSelection = require("../_chunks-cjs/util.reverse-selection.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs");
4
+ function isSpan(context, child) {
5
+ return child._type === context.schema.span.name;
6
+ }
7
+ function isTextBlock(context, block) {
8
+ return block._type === context.schema.block.name;
9
+ }
10
+ function mergeTextBlocks({
11
+ context,
12
+ targetBlock,
13
+ incomingBlock
14
+ }) {
15
+ const parsedIncomingBlock = parseBlocks.parseBlock({
16
+ context,
17
+ block: incomingBlock,
18
+ options: {
19
+ refreshKeys: !0
20
+ }
21
+ });
22
+ return !parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock) ? targetBlock : {
23
+ ...targetBlock,
24
+ children: [...targetBlock.children, ...parsedIncomingBlock.children],
25
+ markDefs: [...targetBlock.markDefs ?? [], ...parsedIncomingBlock.markDefs ?? []]
26
+ };
27
+ }
28
+ function splitTextBlock({
29
+ context,
30
+ block,
31
+ point
32
+ }) {
33
+ const firstChild = block.children.at(0), lastChild = block.children.at(block.children.length - 1);
34
+ if (!firstChild || !lastChild)
35
+ return;
36
+ const before = util_sliceBlocks.sliceBlocks({
37
+ blocks: [block],
38
+ selection: {
39
+ anchor: {
40
+ path: [{
41
+ _key: block._key
42
+ }, "children", {
43
+ _key: firstChild._key
44
+ }],
45
+ offset: 0
46
+ },
47
+ focus: point
48
+ }
49
+ }).at(0), after = util_sliceBlocks.sliceBlocks({
50
+ blocks: [block],
51
+ selection: {
52
+ anchor: point,
53
+ focus: {
54
+ path: [{
55
+ _key: block._key
56
+ }, "children", {
57
+ _key: lastChild._key
58
+ }],
59
+ offset: isSpan(context, lastChild) ? lastChild.text.length : 0
60
+ }
61
+ }
62
+ }).at(0);
63
+ if (!(!before || !after) && !(!isTextBlock(context, before) || !isTextBlock(context, after)))
64
+ return {
65
+ before,
66
+ after
67
+ };
68
+ }
4
69
  exports.blockOffsetToSpanSelectionPoint = util_isEmptyTextBlock.blockOffsetToSpanSelectionPoint;
5
70
  exports.getTextBlockText = util_isEmptyTextBlock.getTextBlockText;
6
71
  exports.isEmptyTextBlock = util_isEmptyTextBlock.isEmptyTextBlock;
@@ -11,4 +76,8 @@ exports.isEqualSelectionPoints = util_isEqualSelectionPoints.isEqualSelectionPoi
11
76
  exports.isKeyedSegment = util_isEqualSelectionPoints.isKeyedSegment;
12
77
  exports.reverseSelection = util_reverseSelection.reverseSelection;
13
78
  exports.sliceBlocks = util_sliceBlocks.sliceBlocks;
79
+ exports.isSpan = isSpan;
80
+ exports.isTextBlock = isTextBlock;
81
+ exports.mergeTextBlocks = mergeTextBlocks;
82
+ exports.splitTextBlock = splitTextBlock;
14
83
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/utils/util.is-span.ts","../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {PortableTextChild, PortableTextSpan} from '@sanity/types'\nimport type {EditorContext} from '../selectors'\n\n/**\n * @public\n */\nexport function isSpan(\n context: Pick<EditorContext, 'schema'>,\n child: PortableTextChild,\n): child is PortableTextSpan {\n return child._type === context.schema.span.name\n}\n","import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../selectors'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport type {EditorContext} from '../selectors'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {isTextBlock, sliceBlocks, type EditorSelectionPoint} from '.'\nimport type {EditorContext} from '../selectors'\nimport {isSpan} from './util.is-span'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isSpan","context","child","_type","schema","span","name","isTextBlock","block","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","children","markDefs","splitTextBlock","point","firstChild","at","lastChild","length","before","sliceBlocks","blocks","selection","anchor","path","_key","offset","focus","after","text"],"mappings":";;;AAMgBA,SAAAA,OACdC,SACAC,OAC2B;AAC3B,SAAOA,MAAMC,UAAUF,QAAQG,OAAOC,KAAKC;AAC7C;ACLgBC,SAAAA,YACdN,SACAO,OACgC;AAChC,SAAOA,MAAML,UAAUF,QAAQG,OAAOI,MAAMF;AAC9C;ACHO,SAASG,gBAAgB;AAAA,EAC9BR;AAAAA,EACAS;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,YAAAA,WAAW;AAAA,IACrCZ;AAAAA,IACAO,OAAOG;AAAAA,IACPG,SAAS;AAAA,MAACC,aAAa;AAAA,IAAA;AAAA,EAAI,CAC5B;AAED,SAAI,CAACH,uBAAuB,CAACL,YAAYN,SAASW,mBAAmB,IAC5DF,cAGF;AAAA,IACL,GAAGA;AAAAA,IACHM,UAAU,CAAC,GAAGN,YAAYM,UAAU,GAAGJ,oBAAoBI,QAAQ;AAAA,IACnEC,UAAU,CACR,GAAIP,YAAYO,YAAY,CAAA,GAC5B,GAAIL,oBAAoBK,YAAY,CAAG,CAAA;AAAA,EAE3C;AACF;AC3BO,SAASC,eAAe;AAAA,EAC7BjB;AAAAA,EACAO;AAAAA,EACAW;AAKF,GAA8E;AAC5E,QAAMC,aAAaZ,MAAMQ,SAASK,GAAG,CAAC,GAChCC,YAAYd,MAAMQ,SAASK,GAAGb,MAAMQ,SAASO,SAAS,CAAC;AAEzD,MAAA,CAACH,cAAc,CAACE;AAClB;AAGF,QAAME,SAASC,iBAAAA,YAAY;AAAA,IACzBC,QAAQ,CAAClB,KAAK;AAAA,IACdmB,WAAW;AAAA,MACTC,QAAQ;AAAA,QACNC,MAAM,CAAC;AAAA,UAACC,MAAMtB,MAAMsB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAC,OAAOb;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEE,GAAG,CAAC,GACDY,QAAQR,iBAAAA,YAAY;AAAA,IACxBC,QAAQ,CAAClB,KAAK;AAAA,IACdmB,WAAW;AAAA,MACTC,QAAQT;AAAAA,MACRa,OAAO;AAAA,QACLH,MAAM,CAAC;AAAA,UAACC,MAAMtB,MAAMsB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,UAAUQ;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQ/B,OAAOC,SAASqB,SAAS,IAAIA,UAAUY,KAAKX,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACS,UAIZ,EAAC1B,CAAAA,YAAYN,SAASuB,MAAM,KAAK,CAACjB,YAAYN,SAASgC,KAAK;AAIzD,WAAA;AAAA,MAACT;AAAAA,MAAQS;AAAAA,IAAK;AACvB;;;;;;;;;;;;;;;"}
@@ -1,5 +1,20 @@
1
- import {KeyedSegment, PortableTextBlock} from '@sanity/types'
2
- import type {Path, PathSegment, PortableTextTextBlock} from '@sanity/types'
1
+ import type {
2
+ ArraySchemaType,
3
+ BlockDecoratorDefinition,
4
+ BlockListDefinition,
5
+ BlockStyleDefinition,
6
+ ObjectSchemaType,
7
+ Path,
8
+ PathSegment,
9
+ PortableTextChild,
10
+ PortableTextTextBlock,
11
+ } from '@sanity/types'
12
+ import {
13
+ KeyedSegment,
14
+ PortableTextBlock,
15
+ PortableTextObject,
16
+ PortableTextSpan,
17
+ } from '@sanity/types'
3
18
 
4
19
  /**
5
20
  * @beta
@@ -25,6 +40,72 @@ export declare function blockOffsetToSpanSelectionPoint({
25
40
  }
26
41
  | undefined
27
42
 
43
+ declare type Converter<TMIMEType extends MIMEType = MIMEType> = {
44
+ mimeType: TMIMEType
45
+ serialize: Serializer<TMIMEType>
46
+ deserialize: Deserializer<TMIMEType>
47
+ }
48
+
49
+ declare type ConverterEvent<TMIMEType extends MIMEType = MIMEType> =
50
+ | {
51
+ type: 'serialize'
52
+ originEvent: 'copy' | 'cut' | 'unknown'
53
+ }
54
+ | {
55
+ type: 'serialization.failure'
56
+ mimeType: TMIMEType
57
+ reason: string
58
+ }
59
+ | {
60
+ type: 'serialization.success'
61
+ data: string
62
+ mimeType: TMIMEType
63
+ originEvent: 'copy' | 'cut' | 'unknown'
64
+ }
65
+ | {
66
+ type: 'deserialize'
67
+ data: string
68
+ }
69
+ | {
70
+ type: 'deserialization.failure'
71
+ mimeType: TMIMEType
72
+ reason: string
73
+ }
74
+ | {
75
+ type: 'deserialization.success'
76
+ data: Array<PortableTextBlock>
77
+ mimeType: TMIMEType
78
+ }
79
+
80
+ declare type Deserializer<TMIMEType extends MIMEType> = ({
81
+ context,
82
+ event,
83
+ }: {
84
+ context: EditorContext
85
+ event: PickFromUnion<ConverterEvent<TMIMEType>, 'type', 'deserialize'>
86
+ }) => PickFromUnion<
87
+ ConverterEvent<TMIMEType>,
88
+ 'type',
89
+ 'deserialization.success' | 'deserialization.failure'
90
+ >
91
+
92
+ /**
93
+ * @public
94
+ */
95
+ declare type EditorContext = {
96
+ activeDecorators: Array<string>
97
+ converters: Array<Converter>
98
+ keyGenerator: () => string
99
+ schema: EditorSchema
100
+ selection: EditorSelection
101
+ value: Array<PortableTextBlock>
102
+ }
103
+
104
+ /**
105
+ * @public
106
+ */
107
+ declare type EditorSchema = PortableTextMemberSchemaTypes
108
+
28
109
  /** @public */
29
110
  export declare type EditorSelection = {
30
111
  anchor: EditorSelectionPoint
@@ -85,6 +166,61 @@ export declare function isKeyedSegment(
85
166
  segment: PathSegment,
86
167
  ): segment is KeyedSegment
87
168
 
169
+ /**
170
+ * @public
171
+ */
172
+ export declare function isSpan(
173
+ context: Pick<EditorContext, 'schema'>,
174
+ child: PortableTextChild,
175
+ ): child is PortableTextSpan
176
+
177
+ /**
178
+ * @public
179
+ */
180
+ export declare function isTextBlock(
181
+ context: Pick<EditorContext, 'schema'>,
182
+ block: PortableTextBlock,
183
+ ): block is PortableTextTextBlock
184
+
185
+ /**
186
+ * @beta
187
+ */
188
+ export declare function mergeTextBlocks({
189
+ context,
190
+ targetBlock,
191
+ incomingBlock,
192
+ }: {
193
+ context: Pick<EditorContext, 'keyGenerator' | 'schema'>
194
+ targetBlock: PortableTextTextBlock
195
+ incomingBlock: PortableTextTextBlock
196
+ }): PortableTextTextBlock<PortableTextSpan | PortableTextObject>
197
+
198
+ declare type MIMEType = `${string}/${string}`
199
+
200
+ /**
201
+ * @internal
202
+ */
203
+ declare type PickFromUnion<
204
+ TUnion,
205
+ TTagKey extends keyof TUnion,
206
+ TPickedTags extends TUnion[TTagKey],
207
+ > = TUnion extends Record<TTagKey, TPickedTags> ? TUnion : never
208
+
209
+ /** @internal */
210
+ declare type PortableTextMemberSchemaTypes = {
211
+ annotations: (ObjectSchemaType & {
212
+ i18nTitleKey?: string
213
+ })[]
214
+ block: ObjectSchemaType
215
+ blockObjects: ObjectSchemaType[]
216
+ decorators: BlockDecoratorDefinition[]
217
+ inlineObjects: ObjectSchemaType[]
218
+ portableText: ArraySchemaType<PortableTextBlock>
219
+ span: ObjectSchemaType
220
+ styles: BlockStyleDefinition[]
221
+ lists: BlockListDefinition[]
222
+ }
223
+
88
224
  /**
89
225
  * @public
90
226
  */
@@ -92,6 +228,18 @@ export declare function reverseSelection(
92
228
  selection: NonNullable<EditorSelection>,
93
229
  ): NonNullable<EditorSelection>
94
230
 
231
+ declare type Serializer<TMIMEType extends MIMEType> = ({
232
+ context,
233
+ event,
234
+ }: {
235
+ context: EditorContext
236
+ event: PickFromUnion<ConverterEvent<TMIMEType>, 'type', 'serialize'>
237
+ }) => PickFromUnion<
238
+ ConverterEvent<TMIMEType>,
239
+ 'type',
240
+ 'serialization.success' | 'serialization.failure'
241
+ >
242
+
95
243
  /**
96
244
  * @public
97
245
  */
@@ -114,4 +262,22 @@ export declare function spanSelectionPointToBlockOffset({
114
262
  selectionPoint: EditorSelectionPoint
115
263
  }): BlockOffset | undefined
116
264
 
265
+ /**
266
+ * @beta
267
+ */
268
+ export declare function splitTextBlock({
269
+ context,
270
+ block,
271
+ point,
272
+ }: {
273
+ context: Pick<EditorContext, 'schema'>
274
+ block: PortableTextTextBlock
275
+ point: EditorSelectionPoint
276
+ }):
277
+ | {
278
+ before: PortableTextTextBlock
279
+ after: PortableTextTextBlock
280
+ }
281
+ | undefined
282
+
117
283
  export {}
@@ -1,5 +1,20 @@
1
- import {KeyedSegment, PortableTextBlock} from '@sanity/types'
2
- import type {Path, PathSegment, PortableTextTextBlock} from '@sanity/types'
1
+ import type {
2
+ ArraySchemaType,
3
+ BlockDecoratorDefinition,
4
+ BlockListDefinition,
5
+ BlockStyleDefinition,
6
+ ObjectSchemaType,
7
+ Path,
8
+ PathSegment,
9
+ PortableTextChild,
10
+ PortableTextTextBlock,
11
+ } from '@sanity/types'
12
+ import {
13
+ KeyedSegment,
14
+ PortableTextBlock,
15
+ PortableTextObject,
16
+ PortableTextSpan,
17
+ } from '@sanity/types'
3
18
 
4
19
  /**
5
20
  * @beta
@@ -25,6 +40,72 @@ export declare function blockOffsetToSpanSelectionPoint({
25
40
  }
26
41
  | undefined
27
42
 
43
+ declare type Converter<TMIMEType extends MIMEType = MIMEType> = {
44
+ mimeType: TMIMEType
45
+ serialize: Serializer<TMIMEType>
46
+ deserialize: Deserializer<TMIMEType>
47
+ }
48
+
49
+ declare type ConverterEvent<TMIMEType extends MIMEType = MIMEType> =
50
+ | {
51
+ type: 'serialize'
52
+ originEvent: 'copy' | 'cut' | 'unknown'
53
+ }
54
+ | {
55
+ type: 'serialization.failure'
56
+ mimeType: TMIMEType
57
+ reason: string
58
+ }
59
+ | {
60
+ type: 'serialization.success'
61
+ data: string
62
+ mimeType: TMIMEType
63
+ originEvent: 'copy' | 'cut' | 'unknown'
64
+ }
65
+ | {
66
+ type: 'deserialize'
67
+ data: string
68
+ }
69
+ | {
70
+ type: 'deserialization.failure'
71
+ mimeType: TMIMEType
72
+ reason: string
73
+ }
74
+ | {
75
+ type: 'deserialization.success'
76
+ data: Array<PortableTextBlock>
77
+ mimeType: TMIMEType
78
+ }
79
+
80
+ declare type Deserializer<TMIMEType extends MIMEType> = ({
81
+ context,
82
+ event,
83
+ }: {
84
+ context: EditorContext
85
+ event: PickFromUnion<ConverterEvent<TMIMEType>, 'type', 'deserialize'>
86
+ }) => PickFromUnion<
87
+ ConverterEvent<TMIMEType>,
88
+ 'type',
89
+ 'deserialization.success' | 'deserialization.failure'
90
+ >
91
+
92
+ /**
93
+ * @public
94
+ */
95
+ declare type EditorContext = {
96
+ activeDecorators: Array<string>
97
+ converters: Array<Converter>
98
+ keyGenerator: () => string
99
+ schema: EditorSchema
100
+ selection: EditorSelection
101
+ value: Array<PortableTextBlock>
102
+ }
103
+
104
+ /**
105
+ * @public
106
+ */
107
+ declare type EditorSchema = PortableTextMemberSchemaTypes
108
+
28
109
  /** @public */
29
110
  export declare type EditorSelection = {
30
111
  anchor: EditorSelectionPoint
@@ -85,6 +166,61 @@ export declare function isKeyedSegment(
85
166
  segment: PathSegment,
86
167
  ): segment is KeyedSegment
87
168
 
169
+ /**
170
+ * @public
171
+ */
172
+ export declare function isSpan(
173
+ context: Pick<EditorContext, 'schema'>,
174
+ child: PortableTextChild,
175
+ ): child is PortableTextSpan
176
+
177
+ /**
178
+ * @public
179
+ */
180
+ export declare function isTextBlock(
181
+ context: Pick<EditorContext, 'schema'>,
182
+ block: PortableTextBlock,
183
+ ): block is PortableTextTextBlock
184
+
185
+ /**
186
+ * @beta
187
+ */
188
+ export declare function mergeTextBlocks({
189
+ context,
190
+ targetBlock,
191
+ incomingBlock,
192
+ }: {
193
+ context: Pick<EditorContext, 'keyGenerator' | 'schema'>
194
+ targetBlock: PortableTextTextBlock
195
+ incomingBlock: PortableTextTextBlock
196
+ }): PortableTextTextBlock<PortableTextSpan | PortableTextObject>
197
+
198
+ declare type MIMEType = `${string}/${string}`
199
+
200
+ /**
201
+ * @internal
202
+ */
203
+ declare type PickFromUnion<
204
+ TUnion,
205
+ TTagKey extends keyof TUnion,
206
+ TPickedTags extends TUnion[TTagKey],
207
+ > = TUnion extends Record<TTagKey, TPickedTags> ? TUnion : never
208
+
209
+ /** @internal */
210
+ declare type PortableTextMemberSchemaTypes = {
211
+ annotations: (ObjectSchemaType & {
212
+ i18nTitleKey?: string
213
+ })[]
214
+ block: ObjectSchemaType
215
+ blockObjects: ObjectSchemaType[]
216
+ decorators: BlockDecoratorDefinition[]
217
+ inlineObjects: ObjectSchemaType[]
218
+ portableText: ArraySchemaType<PortableTextBlock>
219
+ span: ObjectSchemaType
220
+ styles: BlockStyleDefinition[]
221
+ lists: BlockListDefinition[]
222
+ }
223
+
88
224
  /**
89
225
  * @public
90
226
  */
@@ -92,6 +228,18 @@ export declare function reverseSelection(
92
228
  selection: NonNullable<EditorSelection>,
93
229
  ): NonNullable<EditorSelection>
94
230
 
231
+ declare type Serializer<TMIMEType extends MIMEType> = ({
232
+ context,
233
+ event,
234
+ }: {
235
+ context: EditorContext
236
+ event: PickFromUnion<ConverterEvent<TMIMEType>, 'type', 'serialize'>
237
+ }) => PickFromUnion<
238
+ ConverterEvent<TMIMEType>,
239
+ 'type',
240
+ 'serialization.success' | 'serialization.failure'
241
+ >
242
+
95
243
  /**
96
244
  * @public
97
245
  */
@@ -114,4 +262,22 @@ export declare function spanSelectionPointToBlockOffset({
114
262
  selectionPoint: EditorSelectionPoint
115
263
  }): BlockOffset | undefined
116
264
 
265
+ /**
266
+ * @beta
267
+ */
268
+ export declare function splitTextBlock({
269
+ context,
270
+ block,
271
+ point,
272
+ }: {
273
+ context: Pick<EditorContext, 'schema'>
274
+ block: PortableTextTextBlock
275
+ point: EditorSelectionPoint
276
+ }):
277
+ | {
278
+ before: PortableTextTextBlock
279
+ after: PortableTextTextBlock
280
+ }
281
+ | undefined
282
+
117
283
  export {}