@portabletext/editor 3.3.3 → 3.3.4

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 (306) hide show
  1. package/package.json +11 -12
  2. package/src/behaviors/_exports/index.ts +0 -1
  3. package/src/behaviors/behavior.abstract.annotation.ts +0 -77
  4. package/src/behaviors/behavior.abstract.decorator.ts +0 -39
  5. package/src/behaviors/behavior.abstract.delete.ts +0 -273
  6. package/src/behaviors/behavior.abstract.deserialize.ts +0 -232
  7. package/src/behaviors/behavior.abstract.insert.ts +0 -525
  8. package/src/behaviors/behavior.abstract.keyboard.ts +0 -189
  9. package/src/behaviors/behavior.abstract.list-item.ts +0 -70
  10. package/src/behaviors/behavior.abstract.move.ts +0 -79
  11. package/src/behaviors/behavior.abstract.select.ts +0 -118
  12. package/src/behaviors/behavior.abstract.serialize.ts +0 -96
  13. package/src/behaviors/behavior.abstract.split.ts +0 -170
  14. package/src/behaviors/behavior.abstract.style.ts +0 -55
  15. package/src/behaviors/behavior.abstract.ts +0 -139
  16. package/src/behaviors/behavior.config.ts +0 -7
  17. package/src/behaviors/behavior.core.annotations.ts +0 -62
  18. package/src/behaviors/behavior.core.block-element.ts +0 -116
  19. package/src/behaviors/behavior.core.block-objects.ts +0 -285
  20. package/src/behaviors/behavior.core.decorators.ts +0 -44
  21. package/src/behaviors/behavior.core.dnd.ts +0 -356
  22. package/src/behaviors/behavior.core.insert-break.ts +0 -266
  23. package/src/behaviors/behavior.core.insert.ts +0 -52
  24. package/src/behaviors/behavior.core.lists.ts +0 -691
  25. package/src/behaviors/behavior.core.ts +0 -44
  26. package/src/behaviors/behavior.perform-event.ts +0 -354
  27. package/src/behaviors/behavior.types.action.ts +0 -102
  28. package/src/behaviors/behavior.types.behavior.ts +0 -83
  29. package/src/behaviors/behavior.types.event.ts +0 -667
  30. package/src/behaviors/behavior.types.guard.ts +0 -11
  31. package/src/behaviors/index.ts +0 -17
  32. package/src/converters/converter.json.ts +0 -53
  33. package/src/converters/converter.portable-text.deserialize.test.ts +0 -680
  34. package/src/converters/converter.portable-text.ts +0 -75
  35. package/src/converters/converter.text-html.deserialize.test.ts +0 -406
  36. package/src/converters/converter.text-html.serialize.test.ts +0 -246
  37. package/src/converters/converter.text-html.ts +0 -87
  38. package/src/converters/converter.text-markdown.ts +0 -67
  39. package/src/converters/converter.text-plain.test.ts +0 -245
  40. package/src/converters/converter.text-plain.ts +0 -126
  41. package/src/converters/converter.types.ts +0 -72
  42. package/src/converters/converters.core.ts +0 -18
  43. package/src/editor/Editable.tsx +0 -1012
  44. package/src/editor/PortableTextEditor.tsx +0 -791
  45. package/src/editor/components/drop-indicator.tsx +0 -17
  46. package/src/editor/components/render-block-object.tsx +0 -121
  47. package/src/editor/components/render-default-object.tsx +0 -21
  48. package/src/editor/components/render-element.tsx +0 -88
  49. package/src/editor/components/render-inline-object.tsx +0 -129
  50. package/src/editor/components/render-leaf.tsx +0 -64
  51. package/src/editor/components/render-span.tsx +0 -303
  52. package/src/editor/components/render-text-block.tsx +0 -265
  53. package/src/editor/components/render-text.tsx +0 -18
  54. package/src/editor/components/use-core-block-element-behaviors.ts +0 -39
  55. package/src/editor/create-editor.ts +0 -323
  56. package/src/editor/create-slate-editor.tsx +0 -64
  57. package/src/editor/editor-actor-context.ts +0 -4
  58. package/src/editor/editor-context.tsx +0 -7
  59. package/src/editor/editor-dom.ts +0 -220
  60. package/src/editor/editor-machine.ts +0 -751
  61. package/src/editor/editor-provider.tsx +0 -111
  62. package/src/editor/editor-schema.ts +0 -6
  63. package/src/editor/editor-selector.ts +0 -89
  64. package/src/editor/editor-snapshot.ts +0 -68
  65. package/src/editor/event-to-change.tsx +0 -49
  66. package/src/editor/hooks/usePortableTextEditor.ts +0 -25
  67. package/src/editor/hooks/usePortableTextEditorSelection.tsx +0 -28
  68. package/src/editor/mutation-machine.ts +0 -322
  69. package/src/editor/plugins/create-with-event-listeners.ts +0 -271
  70. package/src/editor/plugins/createWithEditableAPI.ts +0 -529
  71. package/src/editor/plugins/createWithHotKeys.ts +0 -68
  72. package/src/editor/plugins/createWithObjectKeys.ts +0 -289
  73. package/src/editor/plugins/createWithPatches.ts +0 -272
  74. package/src/editor/plugins/createWithPortableTextMarkModel.ts +0 -559
  75. package/src/editor/plugins/createWithSchemaTypes.ts +0 -121
  76. package/src/editor/plugins/slate-plugin.update-selection.ts +0 -51
  77. package/src/editor/plugins/slate-plugin.update-value.ts +0 -46
  78. package/src/editor/plugins/with-plugins.ts +0 -69
  79. package/src/editor/range-decorations-machine.ts +0 -421
  80. package/src/editor/relay-actor-context.ts +0 -4
  81. package/src/editor/relay-machine.ts +0 -152
  82. package/src/editor/sync-machine.ts +0 -961
  83. package/src/editor/use-editor.ts +0 -27
  84. package/src/editor/validate-selection-machine.test.ts +0 -47
  85. package/src/editor/validate-selection-machine.ts +0 -149
  86. package/src/editor/weakMaps.ts +0 -15
  87. package/src/editor/with-normalizing-node.ts +0 -14
  88. package/src/editor/with-performing-behavior-operation.ts +0 -21
  89. package/src/editor/withChanges.ts +0 -13
  90. package/src/editor/without-normalizing-conditional.ts +0 -13
  91. package/src/editor/withoutPatching.ts +0 -14
  92. package/src/editor.ts +0 -59
  93. package/src/history/behavior.operation.history.redo.ts +0 -67
  94. package/src/history/behavior.operation.history.undo.ts +0 -71
  95. package/src/history/event.history.undo.test.tsx +0 -672
  96. package/src/history/history.preserving-keys.test.tsx +0 -112
  97. package/src/history/remote-patches.ts +0 -20
  98. package/src/history/slate-plugin.history.ts +0 -142
  99. package/src/history/slate-plugin.redoing.ts +0 -21
  100. package/src/history/slate-plugin.undoing.ts +0 -21
  101. package/src/history/slate-plugin.without-history.ts +0 -23
  102. package/src/history/transform-operation.ts +0 -245
  103. package/src/history/undo-redo-collaboration.test.tsx +0 -541
  104. package/src/history/undo-redo.feature +0 -125
  105. package/src/history/undo-redo.test.tsx +0 -195
  106. package/src/history/undo-step.ts +0 -148
  107. package/src/index.ts +0 -107
  108. package/src/internal-utils/__tests__/ranges.test.ts +0 -23
  109. package/src/internal-utils/__tests__/values.test.ts +0 -110
  110. package/src/internal-utils/apply-operation-to-portable-text.test.ts +0 -1861
  111. package/src/internal-utils/apply-operation-to-portable-text.ts +0 -615
  112. package/src/internal-utils/applyPatch.ts +0 -644
  113. package/src/internal-utils/block-keys.ts +0 -9
  114. package/src/internal-utils/build-index-maps.test.ts +0 -464
  115. package/src/internal-utils/build-index-maps.ts +0 -131
  116. package/src/internal-utils/collapse-selection.ts +0 -36
  117. package/src/internal-utils/compound-client-rect.ts +0 -28
  118. package/src/internal-utils/create-placeholder-block.ts +0 -21
  119. package/src/internal-utils/create-test-snapshot.ts +0 -28
  120. package/src/internal-utils/debug.ts +0 -12
  121. package/src/internal-utils/editor-selection.test.ts +0 -44
  122. package/src/internal-utils/editor-selection.ts +0 -56
  123. package/src/internal-utils/event-position.ts +0 -318
  124. package/src/internal-utils/global-scope.ts +0 -27
  125. package/src/internal-utils/globally-scoped-context.ts +0 -39
  126. package/src/internal-utils/is-hotkey.test.ts +0 -114
  127. package/src/internal-utils/is-hotkey.ts +0 -209
  128. package/src/internal-utils/mime-type.ts +0 -1
  129. package/src/internal-utils/move-range-by-operation.ts +0 -19
  130. package/src/internal-utils/operation-to-patches.test.ts +0 -522
  131. package/src/internal-utils/operation-to-patches.ts +0 -571
  132. package/src/internal-utils/portable-text-node.ts +0 -209
  133. package/src/internal-utils/schema.ts +0 -8
  134. package/src/internal-utils/selection-block-keys.ts +0 -20
  135. package/src/internal-utils/selection-focus-text.ts +0 -40
  136. package/src/internal-utils/selection-text.test.ts +0 -32
  137. package/src/internal-utils/selection-text.ts +0 -21
  138. package/src/internal-utils/selection.ts +0 -77
  139. package/src/internal-utils/sibling-utils.ts +0 -55
  140. package/src/internal-utils/slate-utils.test.tsx +0 -121
  141. package/src/internal-utils/slate-utils.ts +0 -417
  142. package/src/internal-utils/split-string.ts +0 -12
  143. package/src/internal-utils/stop-actor.ts +0 -43
  144. package/src/internal-utils/string-overlap.test.ts +0 -14
  145. package/src/internal-utils/string-overlap.ts +0 -28
  146. package/src/internal-utils/string-utils.ts +0 -7
  147. package/src/internal-utils/text-block-key.test.ts +0 -41
  148. package/src/internal-utils/text-block-key.ts +0 -26
  149. package/src/internal-utils/text-marks.test.ts +0 -41
  150. package/src/internal-utils/text-marks.ts +0 -22
  151. package/src/internal-utils/text-selection.test.ts +0 -211
  152. package/src/internal-utils/text-selection.ts +0 -121
  153. package/src/internal-utils/to-slate-range.test.ts +0 -278
  154. package/src/internal-utils/to-slate-range.ts +0 -171
  155. package/src/internal-utils/validateValue.ts +0 -443
  156. package/src/internal-utils/value-annotations.ts +0 -33
  157. package/src/internal-utils/values.test.ts +0 -282
  158. package/src/internal-utils/values.ts +0 -266
  159. package/src/keyboard-shortcuts/default-keyboard-shortcuts.ts +0 -146
  160. package/src/operations/behavior.operation.annotation.add.ts +0 -99
  161. package/src/operations/behavior.operation.annotation.remove.ts +0 -150
  162. package/src/operations/behavior.operation.block.set.ts +0 -104
  163. package/src/operations/behavior.operation.block.unset.ts +0 -54
  164. package/src/operations/behavior.operation.child.set.ts +0 -107
  165. package/src/operations/behavior.operation.child.unset.ts +0 -116
  166. package/src/operations/behavior.operation.decorator.add.ts +0 -131
  167. package/src/operations/behavior.operation.delete.ts +0 -294
  168. package/src/operations/behavior.operation.insert.block.ts +0 -495
  169. package/src/operations/behavior.operation.insert.child.ts +0 -129
  170. package/src/operations/behavior.operation.insert.text.ts +0 -8
  171. package/src/operations/behavior.operation.move.backward.ts +0 -12
  172. package/src/operations/behavior.operation.move.block.ts +0 -44
  173. package/src/operations/behavior.operation.move.forward.ts +0 -11
  174. package/src/operations/behavior.operation.select.ts +0 -27
  175. package/src/operations/behavior.operations.ts +0 -221
  176. package/src/plugins/_exports/index.ts +0 -1
  177. package/src/plugins/index.ts +0 -3
  178. package/src/plugins/plugin.behavior.tsx +0 -24
  179. package/src/plugins/plugin.editor-ref.tsx +0 -17
  180. package/src/plugins/plugin.event-listener.tsx +0 -68
  181. package/src/plugins/plugin.internal.auto-close-brackets.test.tsx +0 -71
  182. package/src/plugins/plugin.internal.auto-close-brackets.ts +0 -62
  183. package/src/plugins/plugin.internal.change-ref.tsx +0 -19
  184. package/src/plugins/plugin.internal.portable-text-editor-ref.tsx +0 -16
  185. package/src/plugins/plugin.internal.slate-editor-ref.tsx +0 -15
  186. package/src/priority/priority.core.ts +0 -3
  187. package/src/priority/priority.sort.test.ts +0 -319
  188. package/src/priority/priority.sort.ts +0 -123
  189. package/src/priority/priority.types.ts +0 -24
  190. package/src/selectors/_exports/index.ts +0 -1
  191. package/src/selectors/drag-selection.test.ts +0 -578
  192. package/src/selectors/drag-selection.ts +0 -118
  193. package/src/selectors/index.ts +0 -54
  194. package/src/selectors/selector.get-active-annotation-marks.ts +0 -12
  195. package/src/selectors/selector.get-active-annotations.ts +0 -36
  196. package/src/selectors/selector.get-active-decorators.ts +0 -29
  197. package/src/selectors/selector.get-active-list-item.ts +0 -38
  198. package/src/selectors/selector.get-active-style.ts +0 -38
  199. package/src/selectors/selector.get-anchor-block.ts +0 -22
  200. package/src/selectors/selector.get-anchor-child.ts +0 -36
  201. package/src/selectors/selector.get-anchor-span.ts +0 -17
  202. package/src/selectors/selector.get-anchor-text-block.ts +0 -18
  203. package/src/selectors/selector.get-block-offsets.ts +0 -34
  204. package/src/selectors/selector.get-caret-word-selection.test.ts +0 -284
  205. package/src/selectors/selector.get-caret-word-selection.ts +0 -134
  206. package/src/selectors/selector.get-first-block.ts +0 -14
  207. package/src/selectors/selector.get-focus-block-object.ts +0 -18
  208. package/src/selectors/selector.get-focus-block.ts +0 -23
  209. package/src/selectors/selector.get-focus-child.ts +0 -36
  210. package/src/selectors/selector.get-focus-inline-object.ts +0 -17
  211. package/src/selectors/selector.get-focus-list-block.ts +0 -18
  212. package/src/selectors/selector.get-focus-span.ts +0 -18
  213. package/src/selectors/selector.get-focus-text-block.ts +0 -18
  214. package/src/selectors/selector.get-last-block.ts +0 -16
  215. package/src/selectors/selector.get-mark-state.test.ts +0 -325
  216. package/src/selectors/selector.get-mark-state.ts +0 -263
  217. package/src/selectors/selector.get-next-block.ts +0 -29
  218. package/src/selectors/selector.get-next-inline-object.ts +0 -53
  219. package/src/selectors/selector.get-next-inline-objects.ts +0 -50
  220. package/src/selectors/selector.get-next-span.ts +0 -56
  221. package/src/selectors/selector.get-previous-block.ts +0 -29
  222. package/src/selectors/selector.get-previous-inline-object.ts +0 -50
  223. package/src/selectors/selector.get-previous-inline-objects.ts +0 -47
  224. package/src/selectors/selector.get-previous-span.ts +0 -53
  225. package/src/selectors/selector.get-selected-blocks.ts +0 -61
  226. package/src/selectors/selector.get-selected-spans.test.ts +0 -347
  227. package/src/selectors/selector.get-selected-spans.ts +0 -155
  228. package/src/selectors/selector.get-selected-text-blocks.ts +0 -73
  229. package/src/selectors/selector.get-selected-value.test.ts +0 -834
  230. package/src/selectors/selector.get-selected-value.ts +0 -66
  231. package/src/selectors/selector.get-selection-end-block.ts +0 -33
  232. package/src/selectors/selector.get-selection-end-child.ts +0 -33
  233. package/src/selectors/selector.get-selection-end-point.ts +0 -17
  234. package/src/selectors/selector.get-selection-start-block.ts +0 -33
  235. package/src/selectors/selector.get-selection-start-child.ts +0 -33
  236. package/src/selectors/selector.get-selection-start-point.ts +0 -17
  237. package/src/selectors/selector.get-selection-text.test.ts +0 -421
  238. package/src/selectors/selector.get-selection-text.ts +0 -27
  239. package/src/selectors/selector.get-selection.ts +0 -9
  240. package/src/selectors/selector.get-text-after.ts +0 -46
  241. package/src/selectors/selector.get-text-before.ts +0 -46
  242. package/src/selectors/selector.get-value.ts +0 -11
  243. package/src/selectors/selector.is-active-annotation.test.ts +0 -320
  244. package/src/selectors/selector.is-active-annotation.ts +0 -52
  245. package/src/selectors/selector.is-active-decorator.test.ts +0 -136
  246. package/src/selectors/selector.is-active-decorator.ts +0 -24
  247. package/src/selectors/selector.is-active-list-item.ts +0 -13
  248. package/src/selectors/selector.is-active-style.ts +0 -13
  249. package/src/selectors/selector.is-at-the-end-of-block.ts +0 -30
  250. package/src/selectors/selector.is-at-the-start-of-block.ts +0 -30
  251. package/src/selectors/selector.is-overlapping-selection.test.ts +0 -304
  252. package/src/selectors/selector.is-overlapping-selection.ts +0 -181
  253. package/src/selectors/selector.is-point-after-selection.ts +0 -97
  254. package/src/selectors/selector.is-point-before-selection.ts +0 -97
  255. package/src/selectors/selector.is-selecting-entire-blocks.ts +0 -43
  256. package/src/selectors/selector.is-selection-collapsed.ts +0 -17
  257. package/src/selectors/selector.is-selection-expanded.test.ts +0 -63
  258. package/src/selectors/selector.is-selection-expanded.ts +0 -9
  259. package/src/test/_exports/index.ts +0 -1
  260. package/src/test/gherkin-parameter-types.ts +0 -112
  261. package/src/test/index.ts +0 -1
  262. package/src/test/vitest/_exports/index.ts +0 -1
  263. package/src/test/vitest/index.ts +0 -3
  264. package/src/test/vitest/step-context.ts +0 -13
  265. package/src/test/vitest/step-definitions.tsx +0 -960
  266. package/src/test/vitest/test-editor.tsx +0 -198
  267. package/src/type-utils.ts +0 -29
  268. package/src/types/block-offset.ts +0 -9
  269. package/src/types/block-with-optional-key.ts +0 -25
  270. package/src/types/editor.ts +0 -509
  271. package/src/types/options.ts +0 -13
  272. package/src/types/paths.ts +0 -35
  273. package/src/types/slate-editor.ts +0 -50
  274. package/src/types/slate.ts +0 -27
  275. package/src/utils/_exports/index.ts +0 -1
  276. package/src/utils/asserters.ts +0 -9
  277. package/src/utils/index.ts +0 -24
  278. package/src/utils/key-generator.ts +0 -33
  279. package/src/utils/parse-blocks.test.ts +0 -836
  280. package/src/utils/parse-blocks.ts +0 -504
  281. package/src/utils/util.at-the-beginning-of-block.ts +0 -32
  282. package/src/utils/util.block-offset-to-block-selection-point.ts +0 -28
  283. package/src/utils/util.block-offset-to-selection-point.ts +0 -33
  284. package/src/utils/util.block-offset.test.ts +0 -375
  285. package/src/utils/util.block-offset.ts +0 -136
  286. package/src/utils/util.block-offsets-to-selection.ts +0 -38
  287. package/src/utils/util.child-selection-point-to-block-offset.ts +0 -51
  288. package/src/utils/util.get-block-end-point.ts +0 -35
  289. package/src/utils/util.get-block-start-point.ts +0 -31
  290. package/src/utils/util.get-selection-end-point.ts +0 -20
  291. package/src/utils/util.get-selection-start-point.ts +0 -20
  292. package/src/utils/util.get-text-block-text.ts +0 -8
  293. package/src/utils/util.is-empty-text-block.ts +0 -21
  294. package/src/utils/util.is-equal-selection-points.ts +0 -13
  295. package/src/utils/util.is-equal-selections.ts +0 -20
  296. package/src/utils/util.is-keyed-segment.ts +0 -8
  297. package/src/utils/util.is-selection-collapsed.ts +0 -16
  298. package/src/utils/util.is-selection-expanded.ts +0 -13
  299. package/src/utils/util.merge-text-blocks.ts +0 -40
  300. package/src/utils/util.reverse-selection.ts +0 -26
  301. package/src/utils/util.selection-point-to-block-offset.ts +0 -30
  302. package/src/utils/util.selection-point.ts +0 -22
  303. package/src/utils/util.slice-blocks.ts +0 -221
  304. package/src/utils/util.slice-text-block.test.ts +0 -190
  305. package/src/utils/util.slice-text-block.ts +0 -89
  306. package/src/utils/util.split-text-block.ts +0 -54
@@ -1,171 +0,0 @@
1
- import {isSpan, isTextBlock} from '@portabletext/schema'
2
- import type {PortableTextObject, PortableTextSpan} from '@sanity/types'
3
- import type {Path, Range} from 'slate'
4
- import type {EditorContext, EditorSnapshot} from '../editor/editor-snapshot'
5
- import type {EditorSelectionPoint} from '../types/editor'
6
- import {blockOffsetToSpanSelectionPoint} from '../utils/util.block-offset'
7
- import {isEqualSelectionPoints} from '../utils/util.is-equal-selection-points'
8
- import {
9
- getBlockKeyFromSelectionPoint,
10
- getChildKeyFromSelectionPoint,
11
- } from '../utils/util.selection-point'
12
-
13
- export function toSlateRange(
14
- snapshot: {
15
- context: Pick<EditorContext, 'schema' | 'value' | 'selection'>
16
- } & Pick<EditorSnapshot, 'blockIndexMap'>,
17
- ): Range | null {
18
- if (!snapshot.context.selection) {
19
- return null
20
- }
21
-
22
- if (
23
- isEqualSelectionPoints(
24
- snapshot.context.selection.anchor,
25
- snapshot.context.selection.focus,
26
- )
27
- ) {
28
- const anchorPoint = toSlateSelectionPoint(
29
- snapshot,
30
- snapshot.context.selection.anchor,
31
- snapshot.context.selection.backward ? 'backward' : 'forward',
32
- )
33
-
34
- if (!anchorPoint) {
35
- return null
36
- }
37
-
38
- return {
39
- anchor: anchorPoint,
40
- focus: anchorPoint,
41
- }
42
- }
43
-
44
- const anchorPoint = toSlateSelectionPoint(
45
- snapshot,
46
- snapshot.context.selection.anchor,
47
- snapshot.context.selection.backward ? 'forward' : 'backward',
48
- )
49
- const focusPoint = toSlateSelectionPoint(
50
- snapshot,
51
- snapshot.context.selection.focus,
52
- snapshot.context.selection.backward ? 'backward' : 'forward',
53
- )
54
-
55
- if (!anchorPoint || !focusPoint) {
56
- return null
57
- }
58
-
59
- return {
60
- anchor: anchorPoint,
61
- focus: focusPoint,
62
- }
63
- }
64
-
65
- function toSlateSelectionPoint(
66
- snapshot: {
67
- context: Pick<EditorContext, 'schema' | 'value'>
68
- } & Pick<EditorSnapshot, 'blockIndexMap'>,
69
- selectionPoint: EditorSelectionPoint,
70
- direction: 'forward' | 'backward',
71
- ):
72
- | {
73
- path: Path
74
- offset: number
75
- }
76
- | undefined {
77
- const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)
78
-
79
- if (!blockKey) {
80
- return undefined
81
- }
82
-
83
- const blockIndex = snapshot.blockIndexMap.get(blockKey)
84
-
85
- if (blockIndex === undefined) {
86
- return undefined
87
- }
88
-
89
- const block = snapshot.context.value.at(blockIndex)
90
-
91
- if (!block) {
92
- return undefined
93
- }
94
-
95
- if (!isTextBlock(snapshot.context, block)) {
96
- return {
97
- path: [blockIndex, 0],
98
- offset: 0,
99
- }
100
- }
101
-
102
- let childKey = getChildKeyFromSelectionPoint({
103
- path: selectionPoint.path,
104
- offset: 0,
105
- })
106
-
107
- // If the block is a text block, but there is no child key in the selection
108
- // point path, then we can try to find a span selection point by the offset.
109
- const spanSelectionPoint = !childKey
110
- ? blockOffsetToSpanSelectionPoint({
111
- context: {
112
- schema: snapshot.context.schema,
113
- value: [block],
114
- },
115
- blockOffset: {
116
- path: [{_key: blockKey}],
117
- offset: selectionPoint.offset,
118
- },
119
- direction,
120
- })
121
- : undefined
122
-
123
- childKey = spanSelectionPoint
124
- ? getChildKeyFromSelectionPoint(spanSelectionPoint)
125
- : childKey
126
-
127
- // If we still don't have a child key, then we have to resort to selecting
128
- // the first child of the block (which by Slate convention is a span).
129
- if (!childKey) {
130
- return {
131
- path: [blockIndex, 0],
132
- offset: 0,
133
- }
134
- }
135
-
136
- let offset = spanSelectionPoint?.offset ?? selectionPoint.offset
137
- let childPath: Array<number> = []
138
- let childIndex = -1
139
- let pathChild: PortableTextSpan | PortableTextObject | undefined
140
-
141
- for (const child of block.children) {
142
- childIndex++
143
- if (child._key === childKey) {
144
- pathChild = child
145
- if (isSpan(snapshot.context, child)) {
146
- childPath = [childIndex]
147
- } else {
148
- childPath = [childIndex, 0]
149
- offset = 0
150
- }
151
- break
152
- }
153
- }
154
-
155
- // If we for some unforeseen reason didn't manage to produce a child path,
156
- // then we have to resort to selecting the first child of the block (which
157
- // by Slate convention is a span).
158
- if (childPath.length === 0) {
159
- return {
160
- path: [blockIndex, 0],
161
- offset: 0,
162
- }
163
- }
164
-
165
- return {
166
- path: [blockIndex].concat(childPath),
167
- offset: isSpan(snapshot.context, pathChild)
168
- ? Math.min(pathChild.text.length, offset)
169
- : offset,
170
- }
171
- }
@@ -1,443 +0,0 @@
1
- import {insert, set, setIfMissing, unset} from '@portabletext/patches'
2
- import {isSpan, isTextBlock} from '@portabletext/schema'
3
- import type {
4
- PortableTextBlock,
5
- PortableTextSpan,
6
- PortableTextTextBlock,
7
- } from '@sanity/types'
8
- import {flatten, isPlainObject, uniq} from 'lodash'
9
- import type {EditorSchema} from '../editor/editor-schema'
10
- import type {InvalidValueResolution} from '../types/editor'
11
-
12
- export interface Validation {
13
- valid: boolean
14
- resolution: InvalidValueResolution | null
15
- value: PortableTextBlock[] | undefined
16
- }
17
-
18
- export function validateValue(
19
- value: PortableTextBlock[] | undefined,
20
- types: EditorSchema,
21
- keyGenerator: () => string,
22
- ): Validation {
23
- let resolution: InvalidValueResolution | null = null
24
- let valid = true
25
- const validChildTypes = [
26
- types.span.name,
27
- ...types.inlineObjects.map((t) => t.name),
28
- ]
29
- const validBlockTypes = [
30
- types.block.name,
31
- ...types.blockObjects.map((t) => t.name),
32
- ]
33
-
34
- // Undefined is allowed
35
- if (value === undefined) {
36
- return {valid: true, resolution: null, value}
37
- }
38
- // Only lengthy arrays are allowed in the editor.
39
- if (!Array.isArray(value) || value.length === 0) {
40
- return {
41
- valid: false,
42
- resolution: {
43
- patches: [unset([])],
44
- description:
45
- 'Editor value must be an array of Portable Text blocks, or undefined.',
46
- action: 'Unset the value',
47
- item: value,
48
-
49
- i18n: {
50
- description:
51
- 'inputs.portable-text.invalid-value.not-an-array.description',
52
- action: 'inputs.portable-text.invalid-value.not-an-array.action',
53
- },
54
- },
55
- value,
56
- }
57
- }
58
- if (
59
- value.some((blk: PortableTextBlock, index: number): boolean => {
60
- // Is the block an object?
61
- if (!isPlainObject(blk)) {
62
- resolution = {
63
- patches: [unset([index])],
64
- description: `Block must be an object, got ${String(blk)}`,
65
- action: `Unset invalid item`,
66
- item: blk,
67
-
68
- i18n: {
69
- description:
70
- 'inputs.portable-text.invalid-value.not-an-object.description',
71
- action: 'inputs.portable-text.invalid-value.not-an-object.action',
72
- values: {index},
73
- },
74
- }
75
- return true
76
- }
77
- // Test that every block has a _key prop
78
- if (!blk._key || typeof blk._key !== 'string') {
79
- resolution = {
80
- patches: [set({...blk, _key: keyGenerator()}, [index])],
81
- description: `Block at index ${index} is missing required _key.`,
82
- action: 'Set the block with a random _key value',
83
- item: blk,
84
-
85
- i18n: {
86
- description:
87
- 'inputs.portable-text.invalid-value.missing-key.description',
88
- action: 'inputs.portable-text.invalid-value.missing-key.action',
89
- values: {index},
90
- },
91
- }
92
- return true
93
- }
94
- // Test that every block has valid _type
95
- if (!blk._type || !validBlockTypes.includes(blk._type)) {
96
- // Special case where block type is set to default 'block', but the block type is named something else according to the schema.
97
- if (blk._type === 'block') {
98
- const currentBlockTypeName = types.block.name
99
- resolution = {
100
- patches: [
101
- set({...blk, _type: currentBlockTypeName}, [{_key: blk._key}]),
102
- ],
103
- description: `Block with _key '${blk._key}' has invalid type name '${blk._type}'. According to the schema, the block type name is '${currentBlockTypeName}'`,
104
- action: `Use type '${currentBlockTypeName}'`,
105
- item: blk,
106
-
107
- i18n: {
108
- description:
109
- 'inputs.portable-text.invalid-value.incorrect-block-type.description',
110
- action:
111
- 'inputs.portable-text.invalid-value.incorrect-block-type.action',
112
- values: {key: blk._key, expectedTypeName: currentBlockTypeName},
113
- },
114
- }
115
- return true
116
- }
117
-
118
- // If the block has no `_type`, but aside from that is a valid Portable Text block
119
- if (
120
- !blk._type &&
121
- isTextBlock({schema: types}, {...blk, _type: types.block.name})
122
- ) {
123
- resolution = {
124
- patches: [
125
- set({...blk, _type: types.block.name}, [{_key: blk._key}]),
126
- ],
127
- description: `Block with _key '${blk._key}' is missing a type name. According to the schema, the block type name is '${types.block.name}'`,
128
- action: `Use type '${types.block.name}'`,
129
- item: blk,
130
-
131
- i18n: {
132
- description:
133
- 'inputs.portable-text.invalid-value.missing-block-type.description',
134
- action:
135
- 'inputs.portable-text.invalid-value.missing-block-type.action',
136
- values: {key: blk._key, expectedTypeName: types.block.name},
137
- },
138
- }
139
- return true
140
- }
141
-
142
- if (!blk._type) {
143
- resolution = {
144
- patches: [unset([{_key: blk._key}])],
145
- description: `Block with _key '${blk._key}' is missing an _type property`,
146
- action: 'Remove the block',
147
- item: blk,
148
-
149
- i18n: {
150
- description:
151
- 'inputs.portable-text.invalid-value.missing-type.description',
152
- action: 'inputs.portable-text.invalid-value.missing-type.action',
153
- values: {key: blk._key},
154
- },
155
- }
156
- return true
157
- }
158
-
159
- resolution = {
160
- patches: [unset([{_key: blk._key}])],
161
- description: `Block with _key '${blk._key}' has invalid _type '${blk._type}'`,
162
- action: 'Remove the block',
163
- item: blk,
164
-
165
- i18n: {
166
- description:
167
- 'inputs.portable-text.invalid-value.disallowed-type.description',
168
- action: 'inputs.portable-text.invalid-value.disallowed-type.action',
169
- values: {key: blk._key, typeName: blk._type},
170
- },
171
- }
172
- return true
173
- }
174
-
175
- // Test regular text blocks
176
- if (blk._type === types.block.name) {
177
- const textBlock = blk as PortableTextTextBlock
178
- // Test that it has a valid children property (array)
179
- if (textBlock.children && !Array.isArray(textBlock.children)) {
180
- resolution = {
181
- patches: [set({children: []}, [{_key: textBlock._key}])],
182
- description: `Text block with _key '${textBlock._key}' has a invalid required property 'children'.`,
183
- action: 'Reset the children property',
184
- item: textBlock,
185
-
186
- i18n: {
187
- description:
188
- 'inputs.portable-text.invalid-value.missing-or-invalid-children.description',
189
- action:
190
- 'inputs.portable-text.invalid-value.missing-or-invalid-children.action',
191
- values: {key: textBlock._key},
192
- },
193
- }
194
- return true
195
- }
196
- // Test that children is set and lengthy
197
- if (
198
- textBlock.children === undefined ||
199
- (Array.isArray(textBlock.children) && textBlock.children.length === 0)
200
- ) {
201
- const newSpan = {
202
- _type: types.span.name,
203
- _key: keyGenerator(),
204
- text: '',
205
- marks: [],
206
- }
207
- resolution = {
208
- autoResolve: true,
209
- patches: [
210
- setIfMissing([], [{_key: blk._key}, 'children']),
211
- insert([newSpan], 'after', [{_key: blk._key}, 'children', 0]),
212
- ],
213
- description: `Children for text block with _key '${blk._key}' is empty.`,
214
- action: 'Insert an empty text',
215
- item: blk,
216
-
217
- i18n: {
218
- description:
219
- 'inputs.portable-text.invalid-value.empty-children.description',
220
- action:
221
- 'inputs.portable-text.invalid-value.empty-children.action',
222
- values: {key: blk._key},
223
- },
224
- }
225
- return true
226
- }
227
-
228
- const allUsedMarks = uniq(
229
- flatten(
230
- textBlock.children
231
- .filter((child) => isSpan({schema: types}, child))
232
- .map((cld) => cld.marks || []),
233
- ),
234
- )
235
-
236
- // Test that all markDefs are in use (remove orphaned markDefs)
237
- if (Array.isArray(blk.markDefs) && blk.markDefs.length > 0) {
238
- const unusedMarkDefs: string[] = uniq(
239
- blk.markDefs
240
- .map((def) => def._key)
241
- .filter((key) => !allUsedMarks.includes(key)),
242
- )
243
- if (unusedMarkDefs.length > 0) {
244
- resolution = {
245
- autoResolve: true,
246
- patches: unusedMarkDefs.map((markDefKey) =>
247
- unset([{_key: blk._key}, 'markDefs', {_key: markDefKey}]),
248
- ),
249
- description: `Block contains orphaned data (unused mark definitions): ${unusedMarkDefs.join(
250
- ', ',
251
- )}.`,
252
- action: 'Remove unused mark definition item',
253
- item: blk,
254
- i18n: {
255
- description:
256
- 'inputs.portable-text.invalid-value.orphaned-mark-defs.description',
257
- action:
258
- 'inputs.portable-text.invalid-value.orphaned-mark-defs.action',
259
- values: {
260
- key: blk._key,
261
- unusedMarkDefs: unusedMarkDefs.map((m) => m.toString()),
262
- },
263
- },
264
- }
265
- return true
266
- }
267
- }
268
-
269
- // Test that every annotation mark used has a definition
270
- const annotationMarks = allUsedMarks.filter(
271
- (mark) => !types.decorators.map((dec) => dec.name).includes(mark),
272
- )
273
- const orphanedMarks = annotationMarks.filter(
274
- (mark) =>
275
- textBlock.markDefs === undefined ||
276
- !textBlock.markDefs.find((def) => def._key === mark),
277
- )
278
- if (orphanedMarks.length > 0) {
279
- const spanChildren = textBlock.children.filter(
280
- (cld) =>
281
- cld._type === types.span.name &&
282
- Array.isArray(cld.marks) &&
283
- cld.marks.some((mark) => orphanedMarks.includes(mark)),
284
- ) as PortableTextSpan[]
285
- if (spanChildren) {
286
- const orphaned = orphanedMarks.join(', ')
287
- resolution = {
288
- autoResolve: true,
289
- patches: spanChildren.map((child) => {
290
- return set(
291
- (child.marks || []).filter(
292
- (cMrk) => !orphanedMarks.includes(cMrk),
293
- ),
294
- [{_key: blk._key}, 'children', {_key: child._key}, 'marks'],
295
- )
296
- }),
297
- description: `Block with _key '${blk._key}' contains marks (${orphaned}) not supported by the current content model.`,
298
- action: 'Remove invalid marks',
299
- item: blk,
300
-
301
- i18n: {
302
- description:
303
- 'inputs.portable-text.invalid-value.orphaned-marks.description',
304
- action:
305
- 'inputs.portable-text.invalid-value.orphaned-marks.action',
306
- values: {
307
- key: blk._key,
308
- orphanedMarks: orphanedMarks.map((m) => m.toString()),
309
- },
310
- },
311
- }
312
- return true
313
- }
314
- }
315
-
316
- // Test every child
317
- if (
318
- textBlock.children.some((child, cIndex: number) => {
319
- if (!isPlainObject(child)) {
320
- resolution = {
321
- patches: [unset([{_key: blk._key}, 'children', cIndex])],
322
- description: `Child at index '${cIndex}' in block with key '${blk._key}' is not an object.`,
323
- action: 'Remove the item',
324
- item: blk,
325
-
326
- i18n: {
327
- description:
328
- 'inputs.portable-text.invalid-value.non-object-child.description',
329
- action:
330
- 'inputs.portable-text.invalid-value.non-object-child.action',
331
- values: {key: blk._key, index: cIndex},
332
- },
333
- }
334
- return true
335
- }
336
-
337
- if (!child._key || typeof child._key !== 'string') {
338
- const newChild = {...child, _key: keyGenerator()}
339
- resolution = {
340
- autoResolve: true,
341
- patches: [
342
- set(newChild, [{_key: blk._key}, 'children', cIndex]),
343
- ],
344
- description: `Child at index ${cIndex} is missing required _key in block with _key ${blk._key}.`,
345
- action: 'Set a new random _key on the object',
346
- item: blk,
347
-
348
- i18n: {
349
- description:
350
- 'inputs.portable-text.invalid-value.missing-child-key.description',
351
- action:
352
- 'inputs.portable-text.invalid-value.missing-child-key.action',
353
- values: {key: blk._key, index: cIndex},
354
- },
355
- }
356
- return true
357
- }
358
-
359
- // Verify that children have valid types
360
- if (!child._type) {
361
- resolution = {
362
- patches: [
363
- unset([{_key: blk._key}, 'children', {_key: child._key}]),
364
- ],
365
- description: `Child with _key '${child._key}' in block with key '${blk._key}' is missing '_type' property.`,
366
- action: 'Remove the object',
367
- item: blk,
368
-
369
- i18n: {
370
- description:
371
- 'inputs.portable-text.invalid-value.missing-child-type.description',
372
- action:
373
- 'inputs.portable-text.invalid-value.missing-child-type.action',
374
- values: {key: blk._key, childKey: child._key},
375
- },
376
- }
377
- return true
378
- }
379
-
380
- if (!validChildTypes.includes(child._type)) {
381
- resolution = {
382
- patches: [
383
- unset([{_key: blk._key}, 'children', {_key: child._key}]),
384
- ],
385
- description: `Child with _key '${child._key}' in block with key '${blk._key}' has invalid '_type' property (${child._type}).`,
386
- action: 'Remove the object',
387
- item: blk,
388
-
389
- i18n: {
390
- description:
391
- 'inputs.portable-text.invalid-value.disallowed-child-type.description',
392
- action:
393
- 'inputs.portable-text.invalid-value.disallowed-child-type.action',
394
- values: {
395
- key: blk._key,
396
- childKey: child._key,
397
- childType: child._type,
398
- },
399
- },
400
- }
401
- return true
402
- }
403
-
404
- // Verify that spans have .text property that is a string
405
- if (
406
- child._type === types.span.name &&
407
- typeof child.text !== 'string'
408
- ) {
409
- resolution = {
410
- patches: [
411
- set({...child, text: ''}, [
412
- {_key: blk._key},
413
- 'children',
414
- {_key: child._key},
415
- ]),
416
- ],
417
- description: `Child with _key '${child._key}' in block with key '${blk._key}' has missing or invalid text property!`,
418
- action: `Write an empty text property to the object`,
419
- item: blk,
420
-
421
- i18n: {
422
- description:
423
- 'inputs.portable-text.invalid-value.invalid-span-text.description',
424
- action:
425
- 'inputs.portable-text.invalid-value.invalid-span-text.action',
426
- values: {key: blk._key, childKey: child._key},
427
- },
428
- }
429
- return true
430
- }
431
- return false
432
- })
433
- ) {
434
- valid = false
435
- }
436
- }
437
- return false
438
- })
439
- ) {
440
- valid = false
441
- }
442
- return {valid, resolution, value}
443
- }
@@ -1,33 +0,0 @@
1
- import {isSpan, isTextBlock} from '@portabletext/schema'
2
- import type {PortableTextBlock} from '@sanity/types'
3
- import type {EditorSchema} from '../editor/editor-schema'
4
-
5
- export function getValueAnnotations(
6
- schema: EditorSchema,
7
- value: Array<PortableTextBlock> | undefined,
8
- ): Array<string> {
9
- if (!value) {
10
- return []
11
- }
12
-
13
- const annotations: Array<string> = []
14
-
15
- for (const block of value) {
16
- if (isTextBlock({schema}, block)) {
17
- for (const child of block.children) {
18
- if (isSpan({schema}, child) && child.marks) {
19
- for (const mark of child.marks) {
20
- if (
21
- block.markDefs?.some((markDef) => markDef._key === mark) &&
22
- !annotations.includes(mark)
23
- ) {
24
- annotations.push(mark)
25
- }
26
- }
27
- }
28
- }
29
- }
30
- }
31
-
32
- return annotations
33
- }