@portabletext/editor 1.39.1 → 1.40.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.
Files changed (99) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +12 -4
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/editor-provider.cjs +131 -109
  4. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  5. package/lib/_chunks-cjs/{parse-blocks.cjs → util.selection-point-to-block-offset.cjs} +74 -4
  6. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -0
  7. package/lib/_chunks-cjs/util.slice-blocks.cjs +2 -2
  8. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  9. package/lib/_chunks-cjs/util.split-text-block.cjs +68 -0
  10. package/lib/_chunks-cjs/util.split-text-block.cjs.map +1 -0
  11. package/lib/_chunks-es/behavior.core.js +12 -4
  12. package/lib/_chunks-es/behavior.core.js.map +1 -1
  13. package/lib/_chunks-es/editor-provider.js +125 -103
  14. package/lib/_chunks-es/editor-provider.js.map +1 -1
  15. package/lib/_chunks-es/{parse-blocks.js → util.selection-point-to-block-offset.js} +76 -5
  16. package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -0
  17. package/lib/_chunks-es/util.slice-blocks.js +2 -2
  18. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  19. package/lib/_chunks-es/util.split-text-block.js +70 -0
  20. package/lib/_chunks-es/util.split-text-block.js.map +1 -0
  21. package/lib/behaviors/index.d.cts +383 -111
  22. package/lib/behaviors/index.d.ts +383 -111
  23. package/lib/index.cjs +198 -195
  24. package/lib/index.cjs.map +1 -1
  25. package/lib/index.d.cts +345 -90
  26. package/lib/index.d.ts +345 -90
  27. package/lib/index.js +205 -202
  28. package/lib/index.js.map +1 -1
  29. package/lib/plugins/index.cjs +11 -11
  30. package/lib/plugins/index.cjs.map +1 -1
  31. package/lib/plugins/index.d.cts +335 -93
  32. package/lib/plugins/index.d.ts +335 -93
  33. package/lib/plugins/index.js +2 -2
  34. package/lib/selectors/index.d.cts +333 -81
  35. package/lib/selectors/index.d.ts +333 -81
  36. package/lib/utils/index.cjs +15 -87
  37. package/lib/utils/index.cjs.map +1 -1
  38. package/lib/utils/index.d.cts +386 -84
  39. package/lib/utils/index.d.ts +386 -84
  40. package/lib/utils/index.js +13 -86
  41. package/lib/utils/index.js.map +1 -1
  42. package/package.json +6 -6
  43. package/src/behavior-actions/behavior.action.decorator.add.ts +13 -2
  44. package/src/behaviors/behavior.core.block-objects.ts +32 -2
  45. package/src/behaviors/behavior.default.ts +38 -14
  46. package/src/behaviors/behavior.types.ts +5 -4
  47. package/src/converters/converter.portable-text.ts +9 -0
  48. package/src/converters/converter.text-plain.test.ts +5 -5
  49. package/src/converters/converter.text-plain.ts +12 -19
  50. package/src/editor/Editable.tsx +122 -68
  51. package/src/editor/PortableTextEditor.tsx +8 -8
  52. package/src/editor/__tests__/self-solving.test.tsx +1 -1
  53. package/src/editor/components/Element.tsx +2 -9
  54. package/src/editor/create-editor.ts +13 -5
  55. package/src/editor/editor-machine.ts +6 -2
  56. package/src/editor/editor-provider.tsx +11 -7
  57. package/src/editor/editor-selector.ts +4 -3
  58. package/src/editor/editor-snapshot.ts +2 -2
  59. package/src/editor/plugins/create-with-event-listeners.ts +2 -5
  60. package/src/editor/plugins/createWithPortableTextMarkModel.ts +1 -2
  61. package/src/internal-utils/block-keys.ts +9 -0
  62. package/src/internal-utils/collapse-selection.ts +36 -0
  63. package/src/internal-utils/compound-client-rect.ts +28 -0
  64. package/src/internal-utils/drag-selection.test.ts +507 -0
  65. package/src/internal-utils/drag-selection.ts +66 -0
  66. package/src/internal-utils/editor-selection.test.ts +40 -0
  67. package/src/internal-utils/editor-selection.ts +60 -0
  68. package/src/internal-utils/event-position.ts +55 -80
  69. package/src/internal-utils/inline-object-selection.ts +115 -0
  70. package/src/internal-utils/selection-block-keys.ts +20 -0
  71. package/src/internal-utils/selection-elements.ts +61 -0
  72. package/src/internal-utils/selection-focus-text.ts +38 -0
  73. package/src/internal-utils/selection-text.test.ts +23 -0
  74. package/src/internal-utils/selection-text.ts +90 -0
  75. package/src/internal-utils/split-string.ts +12 -0
  76. package/src/internal-utils/string-overlap.test.ts +14 -0
  77. package/src/internal-utils/string-overlap.ts +28 -0
  78. package/src/internal-utils/string-utils.ts +7 -0
  79. package/src/internal-utils/terse-pt.test.ts +60 -0
  80. package/src/internal-utils/terse-pt.ts +36 -0
  81. package/src/internal-utils/text-block-key.test.ts +30 -0
  82. package/src/internal-utils/text-block-key.ts +30 -0
  83. package/src/internal-utils/text-marks.test.ts +33 -0
  84. package/src/internal-utils/text-marks.ts +26 -0
  85. package/src/internal-utils/text-selection.test.ts +175 -0
  86. package/src/internal-utils/text-selection.ts +122 -0
  87. package/src/internal-utils/value-annotations.ts +31 -0
  88. package/src/internal-utils/values.ts +16 -5
  89. package/src/utils/index.ts +5 -0
  90. package/src/utils/util.block-offset-to-block-selection-point.ts +28 -0
  91. package/src/utils/util.block-offset-to-selection-point.ts +33 -0
  92. package/src/utils/util.block-offsets-to-selection.ts +3 -3
  93. package/src/utils/util.is-equal-selections.ts +20 -0
  94. package/src/utils/util.is-selection-collapsed.ts +15 -0
  95. package/src/utils/util.reverse-selection.ts +9 -5
  96. package/src/utils/util.selection-point-to-block-offset.ts +31 -0
  97. package/lib/_chunks-cjs/parse-blocks.cjs.map +0 -1
  98. package/lib/_chunks-es/parse-blocks.js.map +0 -1
  99. package/src/editor/components/use-draggable.ts +0 -123
@@ -1,15 +1,46 @@
1
1
  "use strict";
2
- var util_sliceBlocks = require("./util.slice-blocks.cjs");
2
+ var util_sliceBlocks = require("./util.slice-blocks.cjs"), types = require("@sanity/types");
3
+ function blockOffsetToBlockSelectionPoint({
4
+ value,
5
+ blockOffset
6
+ }) {
7
+ let selectionPoint;
8
+ for (const block of value)
9
+ if (block._key === blockOffset.path[0]._key) {
10
+ selectionPoint = {
11
+ path: [{
12
+ _key: block._key
13
+ }],
14
+ offset: blockOffset.offset
15
+ };
16
+ break;
17
+ }
18
+ return selectionPoint;
19
+ }
20
+ function blockOffsetToSelectionPoint({
21
+ value,
22
+ blockOffset,
23
+ direction
24
+ }) {
25
+ return util_sliceBlocks.blockOffsetToSpanSelectionPoint({
26
+ value,
27
+ blockOffset,
28
+ direction
29
+ }) || blockOffsetToBlockSelectionPoint({
30
+ value,
31
+ blockOffset
32
+ });
33
+ }
3
34
  function blockOffsetsToSelection({
4
35
  value,
5
36
  offsets,
6
37
  backward
7
38
  }) {
8
- const anchor = util_sliceBlocks.blockOffsetToSpanSelectionPoint({
39
+ const anchor = blockOffsetToSelectionPoint({
9
40
  value,
10
41
  blockOffset: offsets.anchor,
11
42
  direction: backward ? "backward" : "forward"
12
- }), focus = util_sliceBlocks.blockOffsetToSpanSelectionPoint({
43
+ }), focus = blockOffsetToSelectionPoint({
13
44
  value,
14
45
  blockOffset: offsets.focus,
15
46
  direction: backward ? "forward" : "backward"
@@ -20,6 +51,27 @@ function blockOffsetsToSelection({
20
51
  backward
21
52
  };
22
53
  }
54
+ function childSelectionPointToBlockOffset({
55
+ value,
56
+ selectionPoint
57
+ }) {
58
+ let offset = 0;
59
+ const blockKey = util_sliceBlocks.isKeyedSegment(selectionPoint.path[0]) ? selectionPoint.path[0]._key : void 0, childKey = util_sliceBlocks.isKeyedSegment(selectionPoint.path[2]) ? selectionPoint.path[2]._key : void 0;
60
+ if (!(!blockKey || !childKey)) {
61
+ for (const block of value)
62
+ if (block._key === blockKey && types.isPortableTextTextBlock(block))
63
+ for (const child of block.children) {
64
+ if (child._key === childKey)
65
+ return {
66
+ path: [{
67
+ _key: block._key
68
+ }],
69
+ offset: offset + selectionPoint.offset
70
+ };
71
+ types.isPortableTextSpan(child) && (offset += child.text.length);
72
+ }
73
+ }
74
+ }
23
75
  function isTypedObject(object) {
24
76
  return isRecord(object) && typeof object._type == "string";
25
77
  }
@@ -165,8 +217,26 @@ function parseInlineObject({
165
217
  _key: options.refreshKeys ? context.keyGenerator() : typeof inlineObject._key == "string" ? inlineObject._key : context.keyGenerator()
166
218
  };
167
219
  }
220
+ function selectionPointToBlockOffset({
221
+ value,
222
+ selectionPoint
223
+ }) {
224
+ return selectionPoint.path.length === 1 && util_sliceBlocks.isKeyedSegment(selectionPoint.path[0]) ? {
225
+ path: [{
226
+ _key: selectionPoint.path[0]._key
227
+ }],
228
+ offset: selectionPoint.offset
229
+ } : childSelectionPointToBlockOffset({
230
+ value,
231
+ selectionPoint
232
+ });
233
+ }
234
+ exports.blockOffsetToBlockSelectionPoint = blockOffsetToBlockSelectionPoint;
235
+ exports.blockOffsetToSelectionPoint = blockOffsetToSelectionPoint;
168
236
  exports.blockOffsetsToSelection = blockOffsetsToSelection;
237
+ exports.childSelectionPointToBlockOffset = childSelectionPointToBlockOffset;
169
238
  exports.isTextBlock = isTextBlock;
170
239
  exports.parseBlock = parseBlock;
171
240
  exports.parseBlocks = parseBlocks;
172
- //# sourceMappingURL=parse-blocks.cjs.map
241
+ exports.selectionPointToBlockOffset = selectionPointToBlockOffset;
242
+ //# sourceMappingURL=util.selection-point-to-block-offset.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.selection-point-to-block-offset.cjs","sources":["../../src/utils/util.block-offset-to-block-selection-point.ts","../../src/utils/util.block-offset-to-selection-point.ts","../../src/utils/util.block-offsets-to-selection.ts","../../src/utils/util.child-selection-point-to-block-offset.ts","../../src/internal-utils/asserters.ts","../../src/internal-utils/parse-blocks.ts","../../src/utils/util.selection-point-to-block-offset.ts"],"sourcesContent":["import type {PortableTextBlock} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function blockOffsetToBlockSelectionPoint({\n value,\n blockOffset,\n}: {\n value: Array<PortableTextBlock>\n blockOffset: BlockOffset\n}): EditorSelectionPoint | undefined {\n let selectionPoint: EditorSelectionPoint | undefined\n\n for (const block of value) {\n if (block._key === blockOffset.path[0]._key) {\n selectionPoint = {\n path: [{_key: block._key}],\n offset: blockOffset.offset,\n }\n break\n }\n }\n\n return selectionPoint\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {blockOffsetToSpanSelectionPoint} from './util.block-offset'\nimport {blockOffsetToBlockSelectionPoint} from './util.block-offset-to-block-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetToSelectionPoint({\n value,\n blockOffset,\n direction,\n}: {\n value: Array<PortableTextBlock>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}): EditorSelectionPoint | undefined {\n const spanSelectionPoint = blockOffsetToSpanSelectionPoint({\n value,\n blockOffset,\n direction,\n })\n\n if (!spanSelectionPoint) {\n return blockOffsetToBlockSelectionPoint({\n value,\n blockOffset,\n })\n }\n\n return spanSelectionPoint\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelection} from '..'\nimport type {BlockOffset} from '../types/block-offset'\nimport {blockOffsetToSelectionPoint} from './util.block-offset-to-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetsToSelection({\n value,\n offsets,\n backward,\n}: {\n value: Array<PortableTextBlock>\n offsets: {anchor: BlockOffset; focus: BlockOffset}\n backward?: boolean\n}): EditorSelection {\n const anchor = blockOffsetToSelectionPoint({\n value,\n blockOffset: offsets.anchor,\n direction: backward ? 'backward' : 'forward',\n })\n const focus = blockOffsetToSelectionPoint({\n value,\n blockOffset: offsets.focus,\n direction: backward ? 'forward' : 'backward',\n })\n\n if (!anchor || !focus) {\n return null\n }\n\n return {\n anchor,\n focus,\n backward,\n }\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function childSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = isKeyedSegment(selectionPoint.path[0])\n ? selectionPoint.path[0]._key\n : undefined\n const childKey = isKeyedSegment(selectionPoint.path[2])\n ? selectionPoint.path[2]._key\n : undefined\n\n if (!blockKey || !childKey) {\n return undefined\n }\n\n for (const block of value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (child._key === childKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n if (isPortableTextSpan(child)) {\n offset += child.text.length\n }\n }\n }\n}\n","import type {TypedObject} from '@sanity/types'\n\nexport function isTypedObject(object: unknown): object is TypedObject {\n return isRecord(object) && typeof object._type === 'string'\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && (typeof value === 'object' || typeof value === 'function')\n}\n","import type {\n PortableTextBlock,\n PortableTextObject,\n PortableTextSpan,\n PortableTextTextBlock,\n} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isTypedObject} from './asserters'\n\nexport function parseBlocks({\n context,\n blocks,\n options,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n blocks: unknown\n options: {\n refreshKeys: boolean\n }\n}): Array<PortableTextBlock> {\n if (!Array.isArray(blocks)) {\n return []\n }\n\n return blocks.flatMap((block) => {\n const parsedBlock = parseBlock({context, block, options})\n\n return parsedBlock ? [parsedBlock] : []\n })\n}\n\nexport function parseBlock({\n context,\n block,\n options,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n block: unknown\n options: {\n refreshKeys: boolean\n }\n}): PortableTextBlock | undefined {\n return (\n parseTextBlock({block, context, options}) ??\n parseBlockObject({blockObject: block, context, options})\n )\n}\n\nfunction parseBlockObject({\n blockObject,\n context,\n options,\n}: {\n blockObject: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean}\n}): PortableTextObject | undefined {\n if (!isTypedObject(blockObject)) {\n return undefined\n }\n\n if (\n blockObject._type === context.schema.block.name ||\n blockObject._type === 'block' ||\n !context.schema.blockObjects.some(({name}) => name === blockObject._type)\n ) {\n return undefined\n }\n\n return {\n ...blockObject,\n _key: options.refreshKeys\n ? context.keyGenerator()\n : typeof blockObject._key === 'string'\n ? blockObject._key\n : context.keyGenerator(),\n }\n}\n\nexport function isTextBlock(\n schema: EditorSchema,\n block: unknown,\n): block is PortableTextTextBlock {\n return (\n parseTextBlock({\n block,\n context: {schema, keyGenerator: () => ''},\n options: {refreshKeys: false},\n }) !== undefined\n )\n}\n\nfunction parseTextBlock({\n block,\n context,\n options,\n}: {\n block: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean}\n}): PortableTextTextBlock | undefined {\n if (!isTypedObject(block)) {\n return undefined\n }\n\n if (block._type !== context.schema.block.name) {\n return undefined\n }\n\n const _key = options.refreshKeys\n ? context.keyGenerator()\n : typeof block._key === 'string'\n ? block._key\n : context.keyGenerator()\n\n const unparsedMarkDefs: Array<unknown> = Array.isArray(block.markDefs)\n ? block.markDefs\n : []\n const markDefKeyMap = new Map<string, string>()\n const markDefs = unparsedMarkDefs.flatMap((markDef) => {\n if (!isTypedObject(markDef)) {\n return []\n }\n\n if (typeof markDef._key !== 'string') {\n return []\n }\n\n if (\n context.schema.annotations.some(\n (annotation) => annotation.name === markDef._type,\n )\n ) {\n const _key = options.refreshKeys ? context.keyGenerator() : markDef._key\n markDefKeyMap.set(markDef._key, _key)\n\n return [\n {\n ...markDef,\n _key,\n },\n ]\n }\n\n return []\n })\n\n const unparsedChildren: Array<unknown> = Array.isArray(block.children)\n ? block.children\n : []\n\n const children = unparsedChildren\n .map(\n (child) =>\n parseSpan({span: child, context, markDefKeyMap, options}) ??\n parseInlineObject({inlineObject: child, context, options}),\n )\n .filter((child) => child !== undefined)\n\n const parsedBlock: PortableTextTextBlock = {\n // Spread the entire block to allow custom properties on it\n ...block,\n _key,\n children:\n children.length > 0\n ? children\n : [\n {\n _key: context.keyGenerator(),\n _type: context.schema.span.name,\n text: '',\n marks: [],\n },\n ],\n markDefs,\n }\n\n /**\n * Reset text block .style if it's somehow set to an invalid type\n */\n if (\n typeof parsedBlock.style !== 'string' ||\n !context.schema.styles.find((style) => style.value === block.style)\n ) {\n const defaultStyle = context.schema.styles.at(0)?.value\n\n if (defaultStyle !== undefined) {\n parsedBlock.style = defaultStyle\n } else {\n delete parsedBlock.style\n }\n }\n\n /**\n * Reset text block .listItem if it's somehow set to an invalid type\n */\n if (\n typeof parsedBlock.listItem !== 'string' ||\n !context.schema.lists.find((list) => list.value === block.listItem)\n ) {\n delete parsedBlock.listItem\n }\n\n /**\n * Reset text block .level if it's somehow set to an invalid type\n */\n if (typeof parsedBlock.level !== 'number') {\n delete parsedBlock.level\n }\n\n return parsedBlock\n}\n\nexport function parseSpan({\n span,\n context,\n markDefKeyMap,\n options,\n}: {\n span: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n markDefKeyMap: Map<string, string>\n options: {refreshKeys: boolean}\n}): PortableTextSpan | undefined {\n if (!isTypedObject(span)) {\n return undefined\n }\n\n // In reality, the span schema name is always 'span', but we only the check here anyway\n if (span._type !== context.schema.span.name || span._type !== 'span') {\n return undefined\n }\n\n const unparsedMarks: Array<unknown> = Array.isArray(span.marks)\n ? span.marks\n : []\n const marks = unparsedMarks.flatMap((mark) => {\n if (typeof mark !== 'string') {\n return []\n }\n\n const markDefKey = markDefKeyMap.get(mark)\n\n if (markDefKey !== undefined) {\n return [markDefKey]\n }\n\n if (\n context.schema.decorators.some((decorator) => decorator.value === mark)\n ) {\n return [mark]\n }\n\n return []\n })\n\n return {\n // Spread the entire span to allow custom properties on it\n ...span,\n _type: 'span',\n _key: options.refreshKeys\n ? context.keyGenerator()\n : typeof span._key === 'string'\n ? span._key\n : context.keyGenerator(),\n text: typeof span.text === 'string' ? span.text : '',\n marks,\n }\n}\n\nfunction parseInlineObject({\n inlineObject,\n context,\n options,\n}: {\n inlineObject: unknown\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n options: {refreshKeys: boolean}\n}): PortableTextObject | undefined {\n if (!isTypedObject(inlineObject)) {\n return undefined\n }\n\n if (\n inlineObject._type === context.schema.span.name ||\n inlineObject._type === 'span' ||\n // Respect the schema definition and don't parse inline objects that are not defined\n !context.schema.inlineObjects.some(({name}) => name === inlineObject._type)\n ) {\n return undefined\n }\n\n return {\n // Spread the entire inline object to allow custom properties on it\n ...inlineObject,\n _key: options.refreshKeys\n ? context.keyGenerator()\n : typeof inlineObject._key === 'string'\n ? inlineObject._key\n : context.keyGenerator(),\n }\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function selectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n if (\n selectionPoint.path.length === 1 &&\n isKeyedSegment(selectionPoint.path[0])\n ) {\n return {\n path: [{_key: selectionPoint.path[0]._key}],\n offset: selectionPoint.offset,\n }\n }\n\n return childSelectionPointToBlockOffset({\n value,\n selectionPoint,\n })\n}\n"],"names":["blockOffsetToBlockSelectionPoint","value","blockOffset","selectionPoint","block","_key","path","offset","blockOffsetToSelectionPoint","direction","blockOffsetToSpanSelectionPoint","blockOffsetsToSelection","offsets","backward","anchor","focus","childSelectionPointToBlockOffset","blockKey","isKeyedSegment","undefined","childKey","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","isTypedObject","object","isRecord","_type","parseBlocks","context","blocks","options","Array","isArray","flatMap","parsedBlock","parseBlock","parseTextBlock","parseBlockObject","blockObject","schema","name","blockObjects","some","refreshKeys","keyGenerator","isTextBlock","unparsedMarkDefs","markDefs","markDefKeyMap","Map","markDef","annotations","annotation","set","map","parseSpan","span","parseInlineObject","inlineObject","filter","marks","style","styles","find","defaultStyle","at","listItem","lists","list","level","mark","markDefKey","get","decorators","decorator","inlineObjects","selectionPointToBlockOffset"],"mappings":"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"}
@@ -126,7 +126,7 @@ function isSpan(context, child) {
126
126
  return child._type === context.schema.span.name;
127
127
  }
128
128
  function reverseSelection(selection) {
129
- return selection.backward ? {
129
+ return selection && (selection.backward ? {
130
130
  anchor: selection.focus,
131
131
  focus: selection.anchor,
132
132
  backward: !1
@@ -134,7 +134,7 @@ function reverseSelection(selection) {
134
134
  anchor: selection.focus,
135
135
  focus: selection.anchor,
136
136
  backward: !0
137
- };
137
+ });
138
138
  }
139
139
  function sliceBlocks({
140
140
  blocks,
@@ -1 +1 @@
1
- {"version":3,"file":"util.slice-blocks.cjs","sources":["../../src/utils/util.is-keyed-segment.ts","../../src/utils/util.block-offset.ts","../../src/utils/util.get-block-end-point.ts","../../src/utils/util.get-block-start-point.ts","../../src/utils/util.get-text-block-text.ts","../../src/utils/util.is-empty-text-block.ts","../../src/utils/util.is-equal-selection-points.ts","../../src/utils/util.is-span.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.slice-blocks.ts"],"sourcesContent":["import type {KeyedSegment, PathSegment} from '@sanity/types'\n\n/**\n * @public\n */\nexport function isKeyedSegment(segment: PathSegment): segment is KeyedSegment {\n return typeof segment === 'object' && segment !== null && '_key' in segment\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function blockOffsetToSpanSelectionPoint({\n value,\n blockOffset,\n direction,\n}: {\n value: Array<PortableTextBlock>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}) {\n let offsetLeft = blockOffset.offset\n let selectionPoint:\n | {path: [KeyedSegment, 'children', KeyedSegment]; offset: number}\n | undefined\n let skippedInlineObject = false\n\n for (const block of value) {\n if (block._key !== blockOffset.path[0]._key) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (direction === 'forward') {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n break\n }\n\n offsetLeft -= child.text.length\n\n continue\n }\n\n if (!isPortableTextSpan(child)) {\n skippedInlineObject = true\n continue\n }\n\n if (offsetLeft === 0 && selectionPoint && !skippedInlineObject) {\n if (skippedInlineObject) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: 0,\n }\n }\n break\n }\n\n if (offsetLeft > child.text.length) {\n offsetLeft -= child.text.length\n continue\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n\n offsetLeft -= child.text.length\n\n if (offsetLeft !== 0) {\n break\n }\n }\n }\n }\n\n return selectionPoint\n}\n\n/**\n * @public\n */\nexport function spanSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = isKeyedSegment(selectionPoint.path[0])\n ? selectionPoint.path[0]._key\n : undefined\n const spanKey = isKeyedSegment(selectionPoint.path[2])\n ? selectionPoint.path[2]._key\n : undefined\n\n if (!blockKey || !spanKey) {\n return undefined\n }\n\n for (const block of value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (child._key === spanKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n offset += child.text.length\n }\n }\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockEndPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n const lastChild = node.children[node.children.length - 1]\n\n if (lastChild) {\n return {\n path: [...path, 'children', {_key: lastChild._key}],\n offset: isPortableTextSpan(lastChild) ? lastChild.text.length : 0,\n }\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n","import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockStartPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n return {\n path: [...path, 'children', {_key: node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\n\n/**\n * @public\n */\nexport function getTextBlockText(block: PortableTextTextBlock) {\n return block.children.map((child) => child.text ?? '').join('')\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport {getTextBlockText} from './util.get-text-block-text'\n\n/**\n * @public\n */\nexport function isEmptyTextBlock(block: PortableTextBlock) {\n if (!isPortableTextTextBlock(block)) {\n return false\n }\n\n const onlyText = block.children.every(isPortableTextSpan)\n const blockText = getTextBlockText(block)\n\n return onlyText && blockText === ''\n}\n","import type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function isEqualSelectionPoints(\n a: EditorSelectionPoint,\n b: EditorSelectionPoint,\n) {\n return (\n a.offset === b.offset && JSON.stringify(a.path) === JSON.stringify(b.path)\n )\n}\n","import type {PortableTextChild, PortableTextSpan} from '@sanity/types'\nimport type {EditorContext} from '..'\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 {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection(\n selection: NonNullable<EditorSelection>,\n): NonNullable<EditorSelection> {\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n }\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n }\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelection} from '..'\n\n/**\n * @public\n */\nexport function sliceBlocks({\n blocks,\n selection,\n}: {\n blocks: Array<PortableTextBlock>\n selection: EditorSelection\n}): Array<PortableTextBlock> {\n const slice: Array<PortableTextBlock> = []\n\n if (!selection) {\n return slice\n }\n\n let startBlock: PortableTextBlock | undefined\n const middleBlocks: PortableTextBlock[] = []\n let endBlock: PortableTextBlock | undefined\n\n const startPoint = selection.backward ? selection.focus : selection.anchor\n const endPoint = selection.backward ? selection.anchor : selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n const startChildKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endChildKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return slice\n }\n\n for (const block of blocks) {\n if (!isPortableTextTextBlock(block)) {\n if (block._key === startBlockKey && block._key === endBlockKey) {\n startBlock = block\n break\n }\n }\n\n if (block._key === startBlockKey) {\n if (!isPortableTextTextBlock(block)) {\n startBlock = block\n continue\n }\n\n if (startChildKey) {\n for (const child of block.children) {\n if (child._key === startChildKey) {\n if (isPortableTextSpan(child)) {\n const text =\n child._key === endChildKey\n ? child.text.slice(startPoint.offset, endPoint.offset)\n : child.text.slice(startPoint.offset)\n\n startBlock = {\n ...block,\n children: [\n {\n ...child,\n text,\n },\n ],\n }\n } else {\n startBlock = {\n ...block,\n children: [child],\n }\n }\n\n if (startChildKey === endChildKey) {\n break\n }\n continue\n }\n\n if (startBlock && isPortableTextTextBlock(startBlock)) {\n if (\n endChildKey &&\n child._key === endChildKey &&\n isPortableTextSpan(child)\n ) {\n startBlock.children.push({\n ...child,\n text: child.text.slice(0, endPoint.offset),\n })\n } else {\n startBlock.children.push(child)\n }\n\n if (\n block._key === endBlockKey &&\n endChildKey &&\n child._key === endChildKey\n ) {\n break\n }\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n startBlock = block\n\n if (startBlockKey === endBlockKey) {\n break\n }\n }\n\n if (block._key === endBlockKey) {\n if (!isPortableTextTextBlock(block)) {\n endBlock = block\n break\n }\n\n if (endChildKey) {\n endBlock = {\n ...block,\n children: [],\n }\n\n for (const child of block.children) {\n if (endBlock && isPortableTextTextBlock(endBlock)) {\n if (child._key === endChildKey && isPortableTextSpan(child)) {\n endBlock.children.push({\n ...child,\n text: child.text.slice(0, endPoint.offset),\n })\n\n break\n }\n\n endBlock.children.push(child)\n\n if (endChildKey && child._key === endChildKey) {\n break\n }\n }\n }\n\n break\n }\n\n endBlock = block\n\n break\n }\n\n if (startBlock) {\n middleBlocks.push(block)\n }\n }\n\n return [\n ...(startBlock ? [startBlock] : []),\n ...middleBlocks,\n ...(endBlock ? [endBlock] : []),\n ]\n}\n"],"names":["isKeyedSegment","segment","blockOffsetToSpanSelectionPoint","value","blockOffset","direction","offsetLeft","offset","selectionPoint","skippedInlineObject","block","_key","path","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","spanSelectionPointToBlockOffset","blockKey","undefined","spanKey","getBlockEndPoint","node","lastChild","getBlockStartPoint","getTextBlockText","map","join","isEmptyTextBlock","onlyText","every","blockText","isEqualSelectionPoints","a","b","JSON","stringify","isSpan","context","_type","schema","span","name","reverseSelection","selection","backward","anchor","focus","sliceBlocks","blocks","slice","startBlock","middleBlocks","endBlock","startPoint","endPoint","startBlockKey","isKeySegment","endBlockKey","startChildKey","endChildKey","push"],"mappings":"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"}
1
+ {"version":3,"file":"util.slice-blocks.cjs","sources":["../../src/utils/util.is-keyed-segment.ts","../../src/utils/util.block-offset.ts","../../src/utils/util.get-block-end-point.ts","../../src/utils/util.get-block-start-point.ts","../../src/utils/util.get-text-block-text.ts","../../src/utils/util.is-empty-text-block.ts","../../src/utils/util.is-equal-selection-points.ts","../../src/utils/util.is-span.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.slice-blocks.ts"],"sourcesContent":["import type {KeyedSegment, PathSegment} from '@sanity/types'\n\n/**\n * @public\n */\nexport function isKeyedSegment(segment: PathSegment): segment is KeyedSegment {\n return typeof segment === 'object' && segment !== null && '_key' in segment\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function blockOffsetToSpanSelectionPoint({\n value,\n blockOffset,\n direction,\n}: {\n value: Array<PortableTextBlock>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}) {\n let offsetLeft = blockOffset.offset\n let selectionPoint:\n | {path: [KeyedSegment, 'children', KeyedSegment]; offset: number}\n | undefined\n let skippedInlineObject = false\n\n for (const block of value) {\n if (block._key !== blockOffset.path[0]._key) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (direction === 'forward') {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n break\n }\n\n offsetLeft -= child.text.length\n\n continue\n }\n\n if (!isPortableTextSpan(child)) {\n skippedInlineObject = true\n continue\n }\n\n if (offsetLeft === 0 && selectionPoint && !skippedInlineObject) {\n if (skippedInlineObject) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: 0,\n }\n }\n break\n }\n\n if (offsetLeft > child.text.length) {\n offsetLeft -= child.text.length\n continue\n }\n\n if (offsetLeft <= child.text.length) {\n selectionPoint = {\n path: [...blockOffset.path, 'children', {_key: child._key}],\n offset: offsetLeft,\n }\n\n offsetLeft -= child.text.length\n\n if (offsetLeft !== 0) {\n break\n }\n }\n }\n }\n\n return selectionPoint\n}\n\n/**\n * @public\n */\nexport function spanSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = isKeyedSegment(selectionPoint.path[0])\n ? selectionPoint.path[0]._key\n : undefined\n const spanKey = isKeyedSegment(selectionPoint.path[2])\n ? selectionPoint.path[2]._key\n : undefined\n\n if (!blockKey || !spanKey) {\n return undefined\n }\n\n for (const block of value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (child._key === spanKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n offset += child.text.length\n }\n }\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockEndPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n const lastChild = node.children[node.children.length - 1]\n\n if (lastChild) {\n return {\n path: [...path, 'children', {_key: lastChild._key}],\n offset: isPortableTextSpan(lastChild) ? lastChild.text.length : 0,\n }\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n","import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockStartPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n return {\n path: [...path, 'children', {_key: node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\n\n/**\n * @public\n */\nexport function getTextBlockText(block: PortableTextTextBlock) {\n return block.children.map((child) => child.text ?? '').join('')\n}\n","import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport {getTextBlockText} from './util.get-text-block-text'\n\n/**\n * @public\n */\nexport function isEmptyTextBlock(block: PortableTextBlock) {\n if (!isPortableTextTextBlock(block)) {\n return false\n }\n\n const onlyText = block.children.every(isPortableTextSpan)\n const blockText = getTextBlockText(block)\n\n return onlyText && blockText === ''\n}\n","import type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function isEqualSelectionPoints(\n a: EditorSelectionPoint,\n b: EditorSelectionPoint,\n) {\n return (\n a.offset === b.offset && JSON.stringify(a.path) === JSON.stringify(b.path)\n )\n}\n","import type {PortableTextChild, PortableTextSpan} from '@sanity/types'\nimport type {EditorContext} from '..'\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 {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n>(selection: TEditorSelection): TEditorSelection {\n if (!selection) {\n return selection\n }\n\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n } as TEditorSelection\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n } as TEditorSelection\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelection} from '..'\n\n/**\n * @public\n */\nexport function sliceBlocks({\n blocks,\n selection,\n}: {\n blocks: Array<PortableTextBlock>\n selection: EditorSelection\n}): Array<PortableTextBlock> {\n const slice: Array<PortableTextBlock> = []\n\n if (!selection) {\n return slice\n }\n\n let startBlock: PortableTextBlock | undefined\n const middleBlocks: PortableTextBlock[] = []\n let endBlock: PortableTextBlock | undefined\n\n const startPoint = selection.backward ? selection.focus : selection.anchor\n const endPoint = selection.backward ? selection.anchor : selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n const startChildKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endChildKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return slice\n }\n\n for (const block of blocks) {\n if (!isPortableTextTextBlock(block)) {\n if (block._key === startBlockKey && block._key === endBlockKey) {\n startBlock = block\n break\n }\n }\n\n if (block._key === startBlockKey) {\n if (!isPortableTextTextBlock(block)) {\n startBlock = block\n continue\n }\n\n if (startChildKey) {\n for (const child of block.children) {\n if (child._key === startChildKey) {\n if (isPortableTextSpan(child)) {\n const text =\n child._key === endChildKey\n ? child.text.slice(startPoint.offset, endPoint.offset)\n : child.text.slice(startPoint.offset)\n\n startBlock = {\n ...block,\n children: [\n {\n ...child,\n text,\n },\n ],\n }\n } else {\n startBlock = {\n ...block,\n children: [child],\n }\n }\n\n if (startChildKey === endChildKey) {\n break\n }\n continue\n }\n\n if (startBlock && isPortableTextTextBlock(startBlock)) {\n if (\n endChildKey &&\n child._key === endChildKey &&\n isPortableTextSpan(child)\n ) {\n startBlock.children.push({\n ...child,\n text: child.text.slice(0, endPoint.offset),\n })\n } else {\n startBlock.children.push(child)\n }\n\n if (\n block._key === endBlockKey &&\n endChildKey &&\n child._key === endChildKey\n ) {\n break\n }\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n startBlock = block\n\n if (startBlockKey === endBlockKey) {\n break\n }\n }\n\n if (block._key === endBlockKey) {\n if (!isPortableTextTextBlock(block)) {\n endBlock = block\n break\n }\n\n if (endChildKey) {\n endBlock = {\n ...block,\n children: [],\n }\n\n for (const child of block.children) {\n if (endBlock && isPortableTextTextBlock(endBlock)) {\n if (child._key === endChildKey && isPortableTextSpan(child)) {\n endBlock.children.push({\n ...child,\n text: child.text.slice(0, endPoint.offset),\n })\n\n break\n }\n\n endBlock.children.push(child)\n\n if (endChildKey && child._key === endChildKey) {\n break\n }\n }\n }\n\n break\n }\n\n endBlock = block\n\n break\n }\n\n if (startBlock) {\n middleBlocks.push(block)\n }\n }\n\n return [\n ...(startBlock ? [startBlock] : []),\n ...middleBlocks,\n ...(endBlock ? [endBlock] : []),\n ]\n}\n"],"names":["isKeyedSegment","segment","blockOffsetToSpanSelectionPoint","value","blockOffset","direction","offsetLeft","offset","selectionPoint","skippedInlineObject","block","_key","path","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","spanSelectionPointToBlockOffset","blockKey","undefined","spanKey","getBlockEndPoint","node","lastChild","getBlockStartPoint","getTextBlockText","map","join","isEmptyTextBlock","onlyText","every","blockText","isEqualSelectionPoints","a","b","JSON","stringify","isSpan","context","_type","schema","span","name","reverseSelection","selection","backward","anchor","focus","sliceBlocks","blocks","slice","startBlock","middleBlocks","endBlock","startPoint","endPoint","startBlockKey","isKeySegment","endBlockKey","startChildKey","endChildKey","push"],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var util_selectionPointToBlockOffset = require("./util.selection-point-to-block-offset.cjs"), util_sliceBlocks = require("./util.slice-blocks.cjs");
3
+ function isTextBlock(context, block) {
4
+ return block._type === context.schema.block.name;
5
+ }
6
+ function mergeTextBlocks({
7
+ context,
8
+ targetBlock,
9
+ incomingBlock
10
+ }) {
11
+ const parsedIncomingBlock = util_selectionPointToBlockOffset.parseBlock({
12
+ context,
13
+ block: incomingBlock,
14
+ options: {
15
+ refreshKeys: !0
16
+ }
17
+ });
18
+ return !parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock) ? targetBlock : {
19
+ ...targetBlock,
20
+ children: [...targetBlock.children, ...parsedIncomingBlock.children],
21
+ markDefs: [...targetBlock.markDefs ?? [], ...parsedIncomingBlock.markDefs ?? []]
22
+ };
23
+ }
24
+ function splitTextBlock({
25
+ context,
26
+ block,
27
+ point
28
+ }) {
29
+ const firstChild = block.children.at(0), lastChild = block.children.at(block.children.length - 1);
30
+ if (!firstChild || !lastChild)
31
+ return;
32
+ const before = util_sliceBlocks.sliceBlocks({
33
+ blocks: [block],
34
+ selection: {
35
+ anchor: {
36
+ path: [{
37
+ _key: block._key
38
+ }, "children", {
39
+ _key: firstChild._key
40
+ }],
41
+ offset: 0
42
+ },
43
+ focus: point
44
+ }
45
+ }).at(0), after = util_sliceBlocks.sliceBlocks({
46
+ blocks: [block],
47
+ selection: {
48
+ anchor: point,
49
+ focus: {
50
+ path: [{
51
+ _key: block._key
52
+ }, "children", {
53
+ _key: lastChild._key
54
+ }],
55
+ offset: util_sliceBlocks.isSpan(context, lastChild) ? lastChild.text.length : 0
56
+ }
57
+ }
58
+ }).at(0);
59
+ if (!(!before || !after) && !(!isTextBlock(context, before) || !isTextBlock(context, after)))
60
+ return {
61
+ before,
62
+ after
63
+ };
64
+ }
65
+ exports.isTextBlock = isTextBlock;
66
+ exports.mergeTextBlocks = mergeTextBlocks;
67
+ exports.splitTextBlock = splitTextBlock;
68
+ //# sourceMappingURL=util.split-text-block.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.split-text-block.cjs","sources":["../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\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 type {EditorContext} from '..'\nimport {parseBlock} from '../internal-utils/parse-blocks'\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 type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\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":["isTextBlock","context","block","_type","schema","name","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","isSpan","text"],"mappings":";;AAMgBA,SAAAA,YACdC,SACAC,OACgC;AAChC,SAAOA,MAAMC,UAAUF,QAAQG,OAAOF,MAAMG;AAC9C;ACHO,SAASC,gBAAgB;AAAA,EAC9BL;AAAAA,EACAM;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,iCAAAA,WAAW;AAAA,IACrCT;AAAAA,IACAC,OAAOM;AAAAA,IACPG,SAAS;AAAA,MAACC,aAAa;AAAA,IAAA;AAAA,EAAI,CAC5B;AAED,SAAI,CAACH,uBAAuB,CAACT,YAAYC,SAASQ,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;ACzBO,SAASC,eAAe;AAAA,EAC7Bd;AAAAA,EACAC;AAAAA,EACAc;AAKF,GAA8E;AAC5E,QAAMC,aAAaf,MAAMW,SAASK,GAAG,CAAC,GAChCC,YAAYjB,MAAMW,SAASK,GAAGhB,MAAMW,SAASO,SAAS,CAAC;AAEzD,MAAA,CAACH,cAAc,CAACE;AAClB;AAGF,QAAME,SAASC,iBAAAA,YAAY;AAAA,IACzBC,QAAQ,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQ;AAAA,QACNC,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;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,CAACrB,KAAK;AAAA,IACdsB,WAAW;AAAA,MACTC,QAAQT;AAAAA,MACRa,OAAO;AAAA,QACLH,MAAM,CAAC;AAAA,UAACC,MAAMzB,MAAMyB;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,UAAUQ;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQG,iBAAO9B,OAAAA,SAASkB,SAAS,IAAIA,UAAUa,KAAKZ,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACS,UAIZ,EAAC9B,CAAAA,YAAYC,SAASoB,MAAM,KAAK,CAACrB,YAAYC,SAAS6B,KAAK;AAIzD,WAAA;AAAA,MAACT;AAAAA,MAAQS;AAAAA,IAAK;AACvB;;;;"}
@@ -176,8 +176,10 @@ const addAnnotationOnCollapsedSelection = {
176
176
  snapshot,
177
177
  event
178
178
  }) => {
179
- const isArrowDown = isHotkey("ArrowDown", event.originEvent), focusBlockObject = getFocusBlockObject(snapshot), nextBlock = getNextBlock(snapshot);
180
- return isArrowDown && focusBlockObject && !nextBlock;
179
+ if (!isHotkey("ArrowDown", event.originEvent) || !isSelectionCollapsed(snapshot))
180
+ return !1;
181
+ const focusBlockObject = getFocusBlockObject(snapshot), nextBlock = getNextBlock(snapshot);
182
+ return focusBlockObject && !nextBlock;
181
183
  },
182
184
  actions: [() => [raise({
183
185
  type: "insert.text block",
@@ -189,8 +191,10 @@ const addAnnotationOnCollapsedSelection = {
189
191
  snapshot,
190
192
  event
191
193
  }) => {
192
- const isArrowUp = isHotkey("ArrowUp", event.originEvent), focusBlockObject = getFocusBlockObject(snapshot), previousBlock = getPreviousBlock(snapshot);
193
- return isArrowUp && focusBlockObject && !previousBlock;
194
+ if (!isHotkey("ArrowUp", event.originEvent) || !isSelectionCollapsed(snapshot))
195
+ return !1;
196
+ const focusBlockObject = getFocusBlockObject(snapshot), previousBlock = getPreviousBlock(snapshot);
197
+ return focusBlockObject && !previousBlock;
194
198
  },
195
199
  actions: [() => [raise({
196
200
  type: "insert.text block",
@@ -214,6 +218,8 @@ const addAnnotationOnCollapsedSelection = {
214
218
  snapshot,
215
219
  event
216
220
  }) => {
221
+ if (!isSelectionCollapsed(snapshot))
222
+ return !1;
217
223
  const focusBlockObject = getFocusBlockObject(snapshot), previousBlock = getPreviousBlock(snapshot);
218
224
  return event.position.isEditor && event.position.block === "start" && focusBlockObject && !previousBlock;
219
225
  },
@@ -227,6 +233,8 @@ const addAnnotationOnCollapsedSelection = {
227
233
  snapshot,
228
234
  event
229
235
  }) => {
236
+ if (!isSelectionCollapsed(snapshot))
237
+ return !1;
230
238
  const focusBlockObject = getFocusBlockObject(snapshot), nextBlock = getNextBlock(snapshot);
231
239
  return event.position.isEditor && event.position.block === "end" && focusBlockObject && !nextBlock;
232
240
  },