@portabletext/editor 3.3.3 → 3.3.5

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 (309) hide show
  1. package/lib/_chunks-dts/index.d.ts +21 -1667
  2. package/lib/index.js +511 -9010
  3. package/lib/index.js.map +1 -1
  4. package/package.json +14 -15
  5. package/src/behaviors/_exports/index.ts +0 -1
  6. package/src/behaviors/behavior.abstract.annotation.ts +0 -77
  7. package/src/behaviors/behavior.abstract.decorator.ts +0 -39
  8. package/src/behaviors/behavior.abstract.delete.ts +0 -273
  9. package/src/behaviors/behavior.abstract.deserialize.ts +0 -232
  10. package/src/behaviors/behavior.abstract.insert.ts +0 -525
  11. package/src/behaviors/behavior.abstract.keyboard.ts +0 -189
  12. package/src/behaviors/behavior.abstract.list-item.ts +0 -70
  13. package/src/behaviors/behavior.abstract.move.ts +0 -79
  14. package/src/behaviors/behavior.abstract.select.ts +0 -118
  15. package/src/behaviors/behavior.abstract.serialize.ts +0 -96
  16. package/src/behaviors/behavior.abstract.split.ts +0 -170
  17. package/src/behaviors/behavior.abstract.style.ts +0 -55
  18. package/src/behaviors/behavior.abstract.ts +0 -139
  19. package/src/behaviors/behavior.config.ts +0 -7
  20. package/src/behaviors/behavior.core.annotations.ts +0 -62
  21. package/src/behaviors/behavior.core.block-element.ts +0 -116
  22. package/src/behaviors/behavior.core.block-objects.ts +0 -285
  23. package/src/behaviors/behavior.core.decorators.ts +0 -44
  24. package/src/behaviors/behavior.core.dnd.ts +0 -356
  25. package/src/behaviors/behavior.core.insert-break.ts +0 -266
  26. package/src/behaviors/behavior.core.insert.ts +0 -52
  27. package/src/behaviors/behavior.core.lists.ts +0 -691
  28. package/src/behaviors/behavior.core.ts +0 -44
  29. package/src/behaviors/behavior.perform-event.ts +0 -354
  30. package/src/behaviors/behavior.types.action.ts +0 -102
  31. package/src/behaviors/behavior.types.behavior.ts +0 -83
  32. package/src/behaviors/behavior.types.event.ts +0 -667
  33. package/src/behaviors/behavior.types.guard.ts +0 -11
  34. package/src/behaviors/index.ts +0 -17
  35. package/src/converters/converter.json.ts +0 -53
  36. package/src/converters/converter.portable-text.deserialize.test.ts +0 -680
  37. package/src/converters/converter.portable-text.ts +0 -75
  38. package/src/converters/converter.text-html.deserialize.test.ts +0 -406
  39. package/src/converters/converter.text-html.serialize.test.ts +0 -246
  40. package/src/converters/converter.text-html.ts +0 -87
  41. package/src/converters/converter.text-markdown.ts +0 -67
  42. package/src/converters/converter.text-plain.test.ts +0 -245
  43. package/src/converters/converter.text-plain.ts +0 -126
  44. package/src/converters/converter.types.ts +0 -72
  45. package/src/converters/converters.core.ts +0 -18
  46. package/src/editor/Editable.tsx +0 -1012
  47. package/src/editor/PortableTextEditor.tsx +0 -791
  48. package/src/editor/components/drop-indicator.tsx +0 -17
  49. package/src/editor/components/render-block-object.tsx +0 -121
  50. package/src/editor/components/render-default-object.tsx +0 -21
  51. package/src/editor/components/render-element.tsx +0 -88
  52. package/src/editor/components/render-inline-object.tsx +0 -129
  53. package/src/editor/components/render-leaf.tsx +0 -64
  54. package/src/editor/components/render-span.tsx +0 -303
  55. package/src/editor/components/render-text-block.tsx +0 -265
  56. package/src/editor/components/render-text.tsx +0 -18
  57. package/src/editor/components/use-core-block-element-behaviors.ts +0 -39
  58. package/src/editor/create-editor.ts +0 -323
  59. package/src/editor/create-slate-editor.tsx +0 -64
  60. package/src/editor/editor-actor-context.ts +0 -4
  61. package/src/editor/editor-context.tsx +0 -7
  62. package/src/editor/editor-dom.ts +0 -220
  63. package/src/editor/editor-machine.ts +0 -751
  64. package/src/editor/editor-provider.tsx +0 -111
  65. package/src/editor/editor-schema.ts +0 -6
  66. package/src/editor/editor-selector.ts +0 -89
  67. package/src/editor/editor-snapshot.ts +0 -68
  68. package/src/editor/event-to-change.tsx +0 -49
  69. package/src/editor/hooks/usePortableTextEditor.ts +0 -25
  70. package/src/editor/hooks/usePortableTextEditorSelection.tsx +0 -28
  71. package/src/editor/mutation-machine.ts +0 -322
  72. package/src/editor/plugins/create-with-event-listeners.ts +0 -271
  73. package/src/editor/plugins/createWithEditableAPI.ts +0 -529
  74. package/src/editor/plugins/createWithHotKeys.ts +0 -68
  75. package/src/editor/plugins/createWithObjectKeys.ts +0 -289
  76. package/src/editor/plugins/createWithPatches.ts +0 -272
  77. package/src/editor/plugins/createWithPortableTextMarkModel.ts +0 -559
  78. package/src/editor/plugins/createWithSchemaTypes.ts +0 -121
  79. package/src/editor/plugins/slate-plugin.update-selection.ts +0 -51
  80. package/src/editor/plugins/slate-plugin.update-value.ts +0 -46
  81. package/src/editor/plugins/with-plugins.ts +0 -69
  82. package/src/editor/range-decorations-machine.ts +0 -421
  83. package/src/editor/relay-actor-context.ts +0 -4
  84. package/src/editor/relay-machine.ts +0 -152
  85. package/src/editor/sync-machine.ts +0 -961
  86. package/src/editor/use-editor.ts +0 -27
  87. package/src/editor/validate-selection-machine.test.ts +0 -47
  88. package/src/editor/validate-selection-machine.ts +0 -149
  89. package/src/editor/weakMaps.ts +0 -15
  90. package/src/editor/with-normalizing-node.ts +0 -14
  91. package/src/editor/with-performing-behavior-operation.ts +0 -21
  92. package/src/editor/withChanges.ts +0 -13
  93. package/src/editor/without-normalizing-conditional.ts +0 -13
  94. package/src/editor/withoutPatching.ts +0 -14
  95. package/src/editor.ts +0 -59
  96. package/src/history/behavior.operation.history.redo.ts +0 -67
  97. package/src/history/behavior.operation.history.undo.ts +0 -71
  98. package/src/history/event.history.undo.test.tsx +0 -672
  99. package/src/history/history.preserving-keys.test.tsx +0 -112
  100. package/src/history/remote-patches.ts +0 -20
  101. package/src/history/slate-plugin.history.ts +0 -142
  102. package/src/history/slate-plugin.redoing.ts +0 -21
  103. package/src/history/slate-plugin.undoing.ts +0 -21
  104. package/src/history/slate-plugin.without-history.ts +0 -23
  105. package/src/history/transform-operation.ts +0 -245
  106. package/src/history/undo-redo-collaboration.test.tsx +0 -541
  107. package/src/history/undo-redo.feature +0 -125
  108. package/src/history/undo-redo.test.tsx +0 -195
  109. package/src/history/undo-step.ts +0 -148
  110. package/src/index.ts +0 -107
  111. package/src/internal-utils/__tests__/ranges.test.ts +0 -23
  112. package/src/internal-utils/__tests__/values.test.ts +0 -110
  113. package/src/internal-utils/apply-operation-to-portable-text.test.ts +0 -1861
  114. package/src/internal-utils/apply-operation-to-portable-text.ts +0 -615
  115. package/src/internal-utils/applyPatch.ts +0 -644
  116. package/src/internal-utils/block-keys.ts +0 -9
  117. package/src/internal-utils/build-index-maps.test.ts +0 -464
  118. package/src/internal-utils/build-index-maps.ts +0 -131
  119. package/src/internal-utils/collapse-selection.ts +0 -36
  120. package/src/internal-utils/compound-client-rect.ts +0 -28
  121. package/src/internal-utils/create-placeholder-block.ts +0 -21
  122. package/src/internal-utils/create-test-snapshot.ts +0 -28
  123. package/src/internal-utils/debug.ts +0 -12
  124. package/src/internal-utils/editor-selection.test.ts +0 -44
  125. package/src/internal-utils/editor-selection.ts +0 -56
  126. package/src/internal-utils/event-position.ts +0 -318
  127. package/src/internal-utils/global-scope.ts +0 -27
  128. package/src/internal-utils/globally-scoped-context.ts +0 -39
  129. package/src/internal-utils/is-hotkey.test.ts +0 -114
  130. package/src/internal-utils/is-hotkey.ts +0 -209
  131. package/src/internal-utils/mime-type.ts +0 -1
  132. package/src/internal-utils/move-range-by-operation.ts +0 -19
  133. package/src/internal-utils/operation-to-patches.test.ts +0 -522
  134. package/src/internal-utils/operation-to-patches.ts +0 -571
  135. package/src/internal-utils/portable-text-node.ts +0 -209
  136. package/src/internal-utils/schema.ts +0 -8
  137. package/src/internal-utils/selection-block-keys.ts +0 -20
  138. package/src/internal-utils/selection-focus-text.ts +0 -40
  139. package/src/internal-utils/selection-text.test.ts +0 -32
  140. package/src/internal-utils/selection-text.ts +0 -21
  141. package/src/internal-utils/selection.ts +0 -77
  142. package/src/internal-utils/sibling-utils.ts +0 -55
  143. package/src/internal-utils/slate-utils.test.tsx +0 -121
  144. package/src/internal-utils/slate-utils.ts +0 -417
  145. package/src/internal-utils/split-string.ts +0 -12
  146. package/src/internal-utils/stop-actor.ts +0 -43
  147. package/src/internal-utils/string-overlap.test.ts +0 -14
  148. package/src/internal-utils/string-overlap.ts +0 -28
  149. package/src/internal-utils/string-utils.ts +0 -7
  150. package/src/internal-utils/text-block-key.test.ts +0 -41
  151. package/src/internal-utils/text-block-key.ts +0 -26
  152. package/src/internal-utils/text-marks.test.ts +0 -41
  153. package/src/internal-utils/text-marks.ts +0 -22
  154. package/src/internal-utils/text-selection.test.ts +0 -211
  155. package/src/internal-utils/text-selection.ts +0 -121
  156. package/src/internal-utils/to-slate-range.test.ts +0 -278
  157. package/src/internal-utils/to-slate-range.ts +0 -171
  158. package/src/internal-utils/validateValue.ts +0 -443
  159. package/src/internal-utils/value-annotations.ts +0 -33
  160. package/src/internal-utils/values.test.ts +0 -282
  161. package/src/internal-utils/values.ts +0 -266
  162. package/src/keyboard-shortcuts/default-keyboard-shortcuts.ts +0 -146
  163. package/src/operations/behavior.operation.annotation.add.ts +0 -99
  164. package/src/operations/behavior.operation.annotation.remove.ts +0 -150
  165. package/src/operations/behavior.operation.block.set.ts +0 -104
  166. package/src/operations/behavior.operation.block.unset.ts +0 -54
  167. package/src/operations/behavior.operation.child.set.ts +0 -107
  168. package/src/operations/behavior.operation.child.unset.ts +0 -116
  169. package/src/operations/behavior.operation.decorator.add.ts +0 -131
  170. package/src/operations/behavior.operation.delete.ts +0 -294
  171. package/src/operations/behavior.operation.insert.block.ts +0 -495
  172. package/src/operations/behavior.operation.insert.child.ts +0 -129
  173. package/src/operations/behavior.operation.insert.text.ts +0 -8
  174. package/src/operations/behavior.operation.move.backward.ts +0 -12
  175. package/src/operations/behavior.operation.move.block.ts +0 -44
  176. package/src/operations/behavior.operation.move.forward.ts +0 -11
  177. package/src/operations/behavior.operation.select.ts +0 -27
  178. package/src/operations/behavior.operations.ts +0 -221
  179. package/src/plugins/_exports/index.ts +0 -1
  180. package/src/plugins/index.ts +0 -3
  181. package/src/plugins/plugin.behavior.tsx +0 -24
  182. package/src/plugins/plugin.editor-ref.tsx +0 -17
  183. package/src/plugins/plugin.event-listener.tsx +0 -68
  184. package/src/plugins/plugin.internal.auto-close-brackets.test.tsx +0 -71
  185. package/src/plugins/plugin.internal.auto-close-brackets.ts +0 -62
  186. package/src/plugins/plugin.internal.change-ref.tsx +0 -19
  187. package/src/plugins/plugin.internal.portable-text-editor-ref.tsx +0 -16
  188. package/src/plugins/plugin.internal.slate-editor-ref.tsx +0 -15
  189. package/src/priority/priority.core.ts +0 -3
  190. package/src/priority/priority.sort.test.ts +0 -319
  191. package/src/priority/priority.sort.ts +0 -123
  192. package/src/priority/priority.types.ts +0 -24
  193. package/src/selectors/_exports/index.ts +0 -1
  194. package/src/selectors/drag-selection.test.ts +0 -578
  195. package/src/selectors/drag-selection.ts +0 -118
  196. package/src/selectors/index.ts +0 -54
  197. package/src/selectors/selector.get-active-annotation-marks.ts +0 -12
  198. package/src/selectors/selector.get-active-annotations.ts +0 -36
  199. package/src/selectors/selector.get-active-decorators.ts +0 -29
  200. package/src/selectors/selector.get-active-list-item.ts +0 -38
  201. package/src/selectors/selector.get-active-style.ts +0 -38
  202. package/src/selectors/selector.get-anchor-block.ts +0 -22
  203. package/src/selectors/selector.get-anchor-child.ts +0 -36
  204. package/src/selectors/selector.get-anchor-span.ts +0 -17
  205. package/src/selectors/selector.get-anchor-text-block.ts +0 -18
  206. package/src/selectors/selector.get-block-offsets.ts +0 -34
  207. package/src/selectors/selector.get-caret-word-selection.test.ts +0 -284
  208. package/src/selectors/selector.get-caret-word-selection.ts +0 -134
  209. package/src/selectors/selector.get-first-block.ts +0 -14
  210. package/src/selectors/selector.get-focus-block-object.ts +0 -18
  211. package/src/selectors/selector.get-focus-block.ts +0 -23
  212. package/src/selectors/selector.get-focus-child.ts +0 -36
  213. package/src/selectors/selector.get-focus-inline-object.ts +0 -17
  214. package/src/selectors/selector.get-focus-list-block.ts +0 -18
  215. package/src/selectors/selector.get-focus-span.ts +0 -18
  216. package/src/selectors/selector.get-focus-text-block.ts +0 -18
  217. package/src/selectors/selector.get-last-block.ts +0 -16
  218. package/src/selectors/selector.get-mark-state.test.ts +0 -325
  219. package/src/selectors/selector.get-mark-state.ts +0 -263
  220. package/src/selectors/selector.get-next-block.ts +0 -29
  221. package/src/selectors/selector.get-next-inline-object.ts +0 -53
  222. package/src/selectors/selector.get-next-inline-objects.ts +0 -50
  223. package/src/selectors/selector.get-next-span.ts +0 -56
  224. package/src/selectors/selector.get-previous-block.ts +0 -29
  225. package/src/selectors/selector.get-previous-inline-object.ts +0 -50
  226. package/src/selectors/selector.get-previous-inline-objects.ts +0 -47
  227. package/src/selectors/selector.get-previous-span.ts +0 -53
  228. package/src/selectors/selector.get-selected-blocks.ts +0 -61
  229. package/src/selectors/selector.get-selected-spans.test.ts +0 -347
  230. package/src/selectors/selector.get-selected-spans.ts +0 -155
  231. package/src/selectors/selector.get-selected-text-blocks.ts +0 -73
  232. package/src/selectors/selector.get-selected-value.test.ts +0 -834
  233. package/src/selectors/selector.get-selected-value.ts +0 -66
  234. package/src/selectors/selector.get-selection-end-block.ts +0 -33
  235. package/src/selectors/selector.get-selection-end-child.ts +0 -33
  236. package/src/selectors/selector.get-selection-end-point.ts +0 -17
  237. package/src/selectors/selector.get-selection-start-block.ts +0 -33
  238. package/src/selectors/selector.get-selection-start-child.ts +0 -33
  239. package/src/selectors/selector.get-selection-start-point.ts +0 -17
  240. package/src/selectors/selector.get-selection-text.test.ts +0 -421
  241. package/src/selectors/selector.get-selection-text.ts +0 -27
  242. package/src/selectors/selector.get-selection.ts +0 -9
  243. package/src/selectors/selector.get-text-after.ts +0 -46
  244. package/src/selectors/selector.get-text-before.ts +0 -46
  245. package/src/selectors/selector.get-value.ts +0 -11
  246. package/src/selectors/selector.is-active-annotation.test.ts +0 -320
  247. package/src/selectors/selector.is-active-annotation.ts +0 -52
  248. package/src/selectors/selector.is-active-decorator.test.ts +0 -136
  249. package/src/selectors/selector.is-active-decorator.ts +0 -24
  250. package/src/selectors/selector.is-active-list-item.ts +0 -13
  251. package/src/selectors/selector.is-active-style.ts +0 -13
  252. package/src/selectors/selector.is-at-the-end-of-block.ts +0 -30
  253. package/src/selectors/selector.is-at-the-start-of-block.ts +0 -30
  254. package/src/selectors/selector.is-overlapping-selection.test.ts +0 -304
  255. package/src/selectors/selector.is-overlapping-selection.ts +0 -181
  256. package/src/selectors/selector.is-point-after-selection.ts +0 -97
  257. package/src/selectors/selector.is-point-before-selection.ts +0 -97
  258. package/src/selectors/selector.is-selecting-entire-blocks.ts +0 -43
  259. package/src/selectors/selector.is-selection-collapsed.ts +0 -17
  260. package/src/selectors/selector.is-selection-expanded.test.ts +0 -63
  261. package/src/selectors/selector.is-selection-expanded.ts +0 -9
  262. package/src/test/_exports/index.ts +0 -1
  263. package/src/test/gherkin-parameter-types.ts +0 -112
  264. package/src/test/index.ts +0 -1
  265. package/src/test/vitest/_exports/index.ts +0 -1
  266. package/src/test/vitest/index.ts +0 -3
  267. package/src/test/vitest/step-context.ts +0 -13
  268. package/src/test/vitest/step-definitions.tsx +0 -960
  269. package/src/test/vitest/test-editor.tsx +0 -198
  270. package/src/type-utils.ts +0 -29
  271. package/src/types/block-offset.ts +0 -9
  272. package/src/types/block-with-optional-key.ts +0 -25
  273. package/src/types/editor.ts +0 -509
  274. package/src/types/options.ts +0 -13
  275. package/src/types/paths.ts +0 -35
  276. package/src/types/slate-editor.ts +0 -50
  277. package/src/types/slate.ts +0 -27
  278. package/src/utils/_exports/index.ts +0 -1
  279. package/src/utils/asserters.ts +0 -9
  280. package/src/utils/index.ts +0 -24
  281. package/src/utils/key-generator.ts +0 -33
  282. package/src/utils/parse-blocks.test.ts +0 -836
  283. package/src/utils/parse-blocks.ts +0 -504
  284. package/src/utils/util.at-the-beginning-of-block.ts +0 -32
  285. package/src/utils/util.block-offset-to-block-selection-point.ts +0 -28
  286. package/src/utils/util.block-offset-to-selection-point.ts +0 -33
  287. package/src/utils/util.block-offset.test.ts +0 -375
  288. package/src/utils/util.block-offset.ts +0 -136
  289. package/src/utils/util.block-offsets-to-selection.ts +0 -38
  290. package/src/utils/util.child-selection-point-to-block-offset.ts +0 -51
  291. package/src/utils/util.get-block-end-point.ts +0 -35
  292. package/src/utils/util.get-block-start-point.ts +0 -31
  293. package/src/utils/util.get-selection-end-point.ts +0 -20
  294. package/src/utils/util.get-selection-start-point.ts +0 -20
  295. package/src/utils/util.get-text-block-text.ts +0 -8
  296. package/src/utils/util.is-empty-text-block.ts +0 -21
  297. package/src/utils/util.is-equal-selection-points.ts +0 -13
  298. package/src/utils/util.is-equal-selections.ts +0 -20
  299. package/src/utils/util.is-keyed-segment.ts +0 -8
  300. package/src/utils/util.is-selection-collapsed.ts +0 -16
  301. package/src/utils/util.is-selection-expanded.ts +0 -13
  302. package/src/utils/util.merge-text-blocks.ts +0 -40
  303. package/src/utils/util.reverse-selection.ts +0 -26
  304. package/src/utils/util.selection-point-to-block-offset.ts +0 -30
  305. package/src/utils/util.selection-point.ts +0 -22
  306. package/src/utils/util.slice-blocks.ts +0 -221
  307. package/src/utils/util.slice-text-block.test.ts +0 -190
  308. package/src/utils/util.slice-text-block.ts +0 -89
  309. 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
- }