@blocknote/core 0.16.0 → 0.17.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 (248) hide show
  1. package/dist/blocknote.js +3292 -2755
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +6 -6
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/webpack-stats.json +1 -1
  6. package/package.json +5 -2
  7. package/src/api/blockManipulation/commands/insertBlocks/__snapshots__/insertBlocks.test.ts.snap +3087 -0
  8. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.ts +132 -0
  9. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +71 -0
  10. package/src/api/blockManipulation/commands/mergeBlocks/__snapshots__/mergeBlocks.test.ts.snap +2276 -0
  11. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +131 -0
  12. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +103 -0
  13. package/src/api/blockManipulation/commands/moveBlock/__snapshots__/moveBlock.test.ts.snap +3767 -0
  14. package/src/api/blockManipulation/commands/moveBlock/moveBlock.test.ts +192 -0
  15. package/src/api/blockManipulation/commands/moveBlock/moveBlock.ts +178 -0
  16. package/src/api/blockManipulation/commands/removeBlocks/__snapshots__/removeBlocks.test.ts.snap +1136 -0
  17. package/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.ts +34 -0
  18. package/src/api/blockManipulation/commands/removeBlocks/removeBlocks.ts +100 -0
  19. package/src/api/blockManipulation/commands/replaceBlocks/__snapshots__/replaceBlocks.test.ts.snap +4931 -0
  20. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.ts +222 -0
  21. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +70 -0
  22. package/src/api/blockManipulation/commands/splitBlock/__snapshots__/splitBlock.test.ts.snap +2924 -0
  23. package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +136 -0
  24. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +48 -0
  25. package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +8376 -0
  26. package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +300 -0
  27. package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +199 -0
  28. package/src/api/blockManipulation/insertContentAt.ts +96 -0
  29. package/src/api/blockManipulation/selections/textCursorPosition/__snapshots__/textCursorPosition.test.ts.snap +316 -0
  30. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.ts +53 -0
  31. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts +130 -0
  32. package/src/api/blockManipulation/setupTestEnv.ts +179 -0
  33. package/src/api/clipboard/__snapshots__/tableAllCells.html +1 -1
  34. package/src/api/clipboard/clipboard.test.ts +5 -6
  35. package/src/api/clipboard/fromClipboard/fileDropExtension.ts +8 -4
  36. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +11 -6
  37. package/src/api/clipboard/fromClipboard/pasteExtension.ts +8 -4
  38. package/src/api/clipboard/toClipboard/copyExtension.ts +113 -61
  39. package/src/api/exporters/html/__snapshots__/complex/misc/external.html +1 -1
  40. package/src/api/exporters/html/__snapshots__/lists/basic/external.html +1 -1
  41. package/src/api/exporters/html/__snapshots__/lists/nested/external.html +1 -1
  42. package/src/api/exporters/html/externalHTMLExporter.ts +42 -94
  43. package/src/api/exporters/html/htmlConversion.test.ts +19 -13
  44. package/src/api/exporters/html/internalHTMLSerializer.ts +21 -72
  45. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +263 -0
  46. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +158 -0
  47. package/src/api/exporters/markdown/markdownExporter.test.ts +10 -10
  48. package/src/api/exporters/markdown/markdownExporter.ts +11 -7
  49. package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +2 -2
  50. package/src/api/getBlockInfoFromPos.ts +172 -90
  51. package/src/api/nodeConversions/blockToNode.ts +257 -0
  52. package/src/api/nodeConversions/fragmentToBlocks.ts +60 -0
  53. package/src/api/nodeConversions/nodeConversions.test.ts +9 -8
  54. package/src/api/nodeConversions/{nodeConversions.ts → nodeToBlock.ts} +20 -262
  55. package/src/api/parsers/html/parseHTML.test.ts +2 -2
  56. package/src/api/parsers/html/parseHTML.ts +8 -4
  57. package/src/api/parsers/html/util/nestedLists.test.ts +2 -2
  58. package/src/api/parsers/markdown/parseMarkdown.test.ts +2 -2
  59. package/src/api/parsers/markdown/parseMarkdown.ts +8 -4
  60. package/src/api/testUtil/cases/customBlocks.ts +11 -11
  61. package/src/api/testUtil/cases/customInlineContent.ts +6 -6
  62. package/src/api/testUtil/cases/customStyles.ts +6 -6
  63. package/src/api/testUtil/cases/defaultSchema.ts +4 -4
  64. package/src/api/testUtil/index.ts +6 -6
  65. package/src/api/testUtil/partialBlockTestUtil.ts +5 -5
  66. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +5 -5
  67. package/src/blocks/FileBlockContent/FileBlockContent.ts +4 -4
  68. package/src/blocks/FileBlockContent/fileBlockHelpers.ts +2 -2
  69. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +61 -39
  70. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +5 -5
  71. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +30 -18
  72. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +67 -33
  73. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +23 -19
  74. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +22 -24
  75. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +31 -19
  76. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +16 -11
  77. package/src/blocks/TableBlockContent/TableBlockContent.ts +4 -4
  78. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +5 -5
  79. package/src/blocks/defaultBlockHelpers.ts +4 -4
  80. package/src/blocks/defaultBlockTypeGuards.ts +5 -5
  81. package/src/blocks/defaultBlocks.ts +13 -13
  82. package/src/blocks/defaultProps.ts +1 -1
  83. package/src/editor/BlockNoteEditor.test.ts +14 -7
  84. package/src/editor/BlockNoteEditor.ts +82 -149
  85. package/src/editor/BlockNoteExtensions.ts +15 -11
  86. package/src/editor/BlockNoteSchema.ts +7 -7
  87. package/src/editor/BlockNoteTipTapEditor.ts +5 -3
  88. package/src/editor/cursorPositionTypes.ts +7 -2
  89. package/src/editor/selectionTypes.ts +6 -2
  90. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +1 -1
  91. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +1 -1
  92. package/src/extensions/FilePanel/FilePanelPlugin.ts +4 -4
  93. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +8 -4
  94. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +334 -0
  95. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +9 -4
  96. package/src/extensions/{NonEditableBlocks/NonEditableBlockPlugin.ts → NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts} +2 -2
  97. package/src/extensions/Placeholder/PlaceholderPlugin.ts +1 -1
  98. package/src/extensions/SideMenu/SideMenuPlugin.ts +72 -401
  99. package/src/extensions/SideMenu/dragging.ts +251 -0
  100. package/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +1 -1
  101. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +8 -4
  102. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +8 -4
  103. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +19 -15
  104. package/src/extensions/TableHandles/TableHandlesPlugin.ts +11 -7
  105. package/src/extensions/TextColor/TextColorExtension.ts +1 -1
  106. package/src/extensions/TextColor/TextColorMark.ts +1 -1
  107. package/src/i18n/dictionary.ts +1 -1
  108. package/src/i18n/locales/ar.ts +1 -1
  109. package/src/i18n/locales/fr.ts +1 -1
  110. package/src/i18n/locales/hr.ts +308 -0
  111. package/src/i18n/locales/index.ts +15 -14
  112. package/src/i18n/locales/is.ts +1 -1
  113. package/src/i18n/locales/ja.ts +1 -1
  114. package/src/i18n/locales/ko.ts +1 -1
  115. package/src/i18n/locales/nl.ts +1 -1
  116. package/src/i18n/locales/pl.ts +1 -1
  117. package/src/i18n/locales/pt.ts +1 -1
  118. package/src/i18n/locales/ru.ts +1 -1
  119. package/src/i18n/locales/vi.ts +1 -1
  120. package/src/i18n/locales/zh.ts +1 -1
  121. package/src/index.ts +45 -44
  122. package/src/pm-nodes/BlockContainer.ts +3 -647
  123. package/src/pm-nodes/BlockGroup.ts +2 -2
  124. package/src/pm-nodes/index.ts +3 -3
  125. package/src/schema/blocks/createSpec.ts +8 -7
  126. package/src/schema/blocks/internal.ts +9 -9
  127. package/src/schema/blocks/types.ts +4 -4
  128. package/src/schema/index.ts +10 -10
  129. package/src/schema/inlineContent/createSpec.ts +9 -10
  130. package/src/schema/inlineContent/internal.ts +3 -3
  131. package/src/schema/inlineContent/types.ts +2 -2
  132. package/src/schema/styles/createSpec.ts +4 -3
  133. package/src/schema/styles/internal.ts +1 -1
  134. package/types/src/api/blockManipulation/commands/insertBlocks/insertBlocks.d.ts +4 -0
  135. package/types/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.d.ts +7 -0
  136. package/types/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.d.ts +1 -0
  137. package/types/src/api/blockManipulation/commands/moveBlock/moveBlock.d.ts +5 -0
  138. package/types/src/api/blockManipulation/commands/moveBlock/moveBlock.test.d.ts +1 -0
  139. package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.d.ts +7 -0
  140. package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.d.ts +1 -0
  141. package/types/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.d.ts +7 -0
  142. package/types/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.d.ts +1 -0
  143. package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +5 -0
  144. package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.test.d.ts +1 -0
  145. package/types/src/api/blockManipulation/commands/updateBlock/updateBlock.d.ts +11 -0
  146. package/types/src/api/blockManipulation/commands/updateBlock/updateBlock.test.d.ts +1 -0
  147. package/types/src/api/blockManipulation/insertContentAt.d.ts +6 -0
  148. package/types/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.d.ts +5 -0
  149. package/types/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.d.ts +1 -0
  150. package/types/src/api/blockManipulation/setupTestEnv.d.ts +492 -0
  151. package/types/src/api/clipboard/fromClipboard/fileDropExtension.d.ts +3 -3
  152. package/types/src/api/clipboard/fromClipboard/handleFileInsertion.d.ts +1 -1
  153. package/types/src/api/clipboard/fromClipboard/pasteExtension.d.ts +2 -2
  154. package/types/src/api/clipboard/toClipboard/copyExtension.d.ts +5 -5
  155. package/types/src/api/exporters/html/externalHTMLExporter.d.ts +7 -9
  156. package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +6 -10
  157. package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +10 -0
  158. package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +11 -0
  159. package/types/src/api/exporters/markdown/markdownExporter.d.ts +3 -3
  160. package/types/src/api/getBlockInfoFromPos.d.ts +63 -20
  161. package/types/src/api/nodeConversions/blockToNode.d.ts +15 -0
  162. package/types/src/api/nodeConversions/fragmentToBlocks.d.ts +7 -0
  163. package/types/src/api/nodeConversions/nodeToBlock.d.ts +16 -0
  164. package/types/src/api/parsers/html/parseHTML.d.ts +2 -2
  165. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -2
  166. package/types/src/api/testUtil/cases/customBlocks.d.ts +39 -39
  167. package/types/src/api/testUtil/cases/customInlineContent.d.ts +35 -35
  168. package/types/src/api/testUtil/cases/customStyles.d.ts +35 -35
  169. package/types/src/api/testUtil/cases/defaultSchema.d.ts +2 -2
  170. package/types/src/api/testUtil/index.d.ts +6 -6
  171. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +4 -4
  172. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +4 -4
  173. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +4 -4
  174. package/types/src/blocks/FileBlockContent/fileBlockHelpers.d.ts +2 -2
  175. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +2 -2
  176. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +4 -4
  177. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +2 -2
  178. package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +2 -2
  179. package/types/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.d.ts +2 -2
  180. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +2 -2
  181. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +2 -2
  182. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +2 -2
  183. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +4 -4
  184. package/types/src/blocks/defaultBlockHelpers.d.ts +3 -3
  185. package/types/src/blocks/defaultBlockTypeGuards.d.ts +4 -4
  186. package/types/src/blocks/defaultBlocks.d.ts +38 -38
  187. package/types/src/blocks/defaultProps.d.ts +1 -1
  188. package/types/src/editor/BlockNoteEditor.d.ts +28 -16
  189. package/types/src/editor/BlockNoteExtensions.d.ts +3 -3
  190. package/types/src/editor/BlockNoteSchema.d.ts +4 -4
  191. package/types/src/editor/BlockNoteTipTapEditor.d.ts +2 -2
  192. package/types/src/editor/cursorPositionTypes.d.ts +3 -2
  193. package/types/src/editor/selectionTypes.d.ts +2 -2
  194. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +1 -1
  195. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
  196. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +4 -4
  197. package/types/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.d.ts +5 -0
  198. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +4 -4
  199. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +2 -0
  200. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +1 -1
  201. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +12 -28
  202. package/types/src/extensions/SideMenu/dragging.d.ts +17 -0
  203. package/types/src/extensions/SuggestionMenu/DefaultSuggestionItem.d.ts +1 -1
  204. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +4 -4
  205. package/types/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.d.ts +3 -3
  206. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +4 -4
  207. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +4 -4
  208. package/types/src/extensions/TextColor/TextColorMark.d.ts +1 -1
  209. package/types/src/i18n/dictionary.d.ts +1 -1
  210. package/types/src/i18n/locales/ar.d.ts +1 -1
  211. package/types/src/i18n/locales/fr.d.ts +1 -1
  212. package/types/src/i18n/locales/hr.d.ts +239 -0
  213. package/types/src/i18n/locales/index.d.ts +15 -14
  214. package/types/src/i18n/locales/is.d.ts +1 -1
  215. package/types/src/i18n/locales/ja.d.ts +1 -1
  216. package/types/src/i18n/locales/ko.d.ts +1 -1
  217. package/types/src/i18n/locales/nl.d.ts +1 -1
  218. package/types/src/i18n/locales/pl.d.ts +1 -1
  219. package/types/src/i18n/locales/pt.d.ts +1 -1
  220. package/types/src/i18n/locales/ru.d.ts +1 -1
  221. package/types/src/i18n/locales/vi.d.ts +1 -1
  222. package/types/src/i18n/locales/zh.d.ts +1 -1
  223. package/types/src/index.d.ts +45 -44
  224. package/types/src/pm-nodes/BlockContainer.d.ts +2 -16
  225. package/types/src/pm-nodes/BlockGroup.d.ts +1 -1
  226. package/types/src/pm-nodes/index.d.ts +3 -3
  227. package/types/src/schema/blocks/createSpec.d.ts +5 -5
  228. package/types/src/schema/blocks/internal.d.ts +5 -5
  229. package/types/src/schema/blocks/types.d.ts +4 -4
  230. package/types/src/schema/index.d.ts +10 -10
  231. package/types/src/schema/inlineContent/createSpec.d.ts +3 -3
  232. package/types/src/schema/inlineContent/internal.d.ts +2 -2
  233. package/types/src/schema/inlineContent/types.d.ts +2 -2
  234. package/types/src/schema/styles/createSpec.d.ts +1 -1
  235. package/types/src/schema/styles/internal.d.ts +1 -1
  236. package/src/api/blockManipulation/__snapshots__/blockManipulation.test.ts.snap +0 -714
  237. package/src/api/blockManipulation/blockManipulation.test.ts +0 -292
  238. package/src/api/blockManipulation/blockManipulation.ts +0 -350
  239. package/src/api/exporters/html/util/sharedHTMLConversion.ts +0 -130
  240. package/src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts +0 -218
  241. package/src/api/getCurrentBlockContentType.ts +0 -14
  242. package/types/src/api/blockManipulation/blockManipulation.d.ts +0 -14
  243. package/types/src/api/exporters/html/util/sharedHTMLConversion.d.ts +0 -9
  244. package/types/src/api/exporters/html/util/simplifyBlocksRehypePlugin.d.ts +0 -16
  245. package/types/src/api/getCurrentBlockContentType.d.ts +0 -2
  246. package/types/src/api/nodeConversions/nodeConversions.d.ts +0 -24
  247. package/types/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.d.ts +0 -2
  248. /package/types/src/api/blockManipulation/{blockManipulation.test.d.ts → commands/insertBlocks/insertBlocks.test.d.ts} +0 -0
@@ -0,0 +1,192 @@
1
+ import { NodeSelection, TextSelection } from "prosemirror-state";
2
+ import { CellSelection } from "prosemirror-tables";
3
+ import { describe, expect, it } from "vitest";
4
+
5
+ import { getBlockInfoFromSelection } from "../../../getBlockInfoFromPos.js";
6
+ import { setupTestEnv } from "../../setupTestEnv.js";
7
+ import {
8
+ moveBlockDown,
9
+ moveBlockUp,
10
+ moveSelectedBlockAndSelection,
11
+ } from "./moveBlock.js";
12
+
13
+ const getEditor = setupTestEnv();
14
+
15
+ function makeSelectionSpanContent(selectionType: "text" | "node" | "cell") {
16
+ const { blockContent } = getBlockInfoFromSelection(
17
+ getEditor()._tiptapEditor.state
18
+ );
19
+
20
+ if (selectionType === "cell") {
21
+ getEditor()._tiptapEditor.view.dispatch(
22
+ getEditor()._tiptapEditor.state.tr.setSelection(
23
+ CellSelection.create(
24
+ getEditor()._tiptapEditor.state.doc,
25
+ getEditor()
26
+ ._tiptapEditor.state.doc.resolve(blockContent.beforePos + 3)
27
+ .before(),
28
+ getEditor()
29
+ ._tiptapEditor.state.doc.resolve(blockContent.afterPos - 3)
30
+ .before()
31
+ )
32
+ )
33
+ );
34
+ } else if (selectionType === "node") {
35
+ const resolvedContentStartPos = getEditor()._tiptapEditor.state.doc.resolve(
36
+ blockContent.beforePos
37
+ );
38
+
39
+ getEditor()._tiptapEditor.view.dispatch(
40
+ getEditor()._tiptapEditor.state.tr.setSelection(
41
+ NodeSelection.create(
42
+ getEditor()._tiptapEditor.state.doc,
43
+ getEditor()
44
+ ._tiptapEditor.state.doc.resolve(
45
+ resolvedContentStartPos.after(resolvedContentStartPos.depth + 1)
46
+ )
47
+ .start()
48
+ )
49
+ )
50
+ );
51
+ } else {
52
+ const resolvedContentStartPos = getEditor()._tiptapEditor.state.doc.resolve(
53
+ blockContent.beforePos
54
+ );
55
+ const resolvedContentEndPos = getEditor()._tiptapEditor.state.doc.resolve(
56
+ blockContent.afterPos
57
+ );
58
+
59
+ getEditor()._tiptapEditor.view.dispatch(
60
+ getEditor()._tiptapEditor.state.tr.setSelection(
61
+ TextSelection.create(
62
+ getEditor()._tiptapEditor.state.doc,
63
+ getEditor()
64
+ ._tiptapEditor.state.doc.resolve(
65
+ resolvedContentStartPos.after(resolvedContentStartPos.depth + 1)
66
+ )
67
+ .start(),
68
+ getEditor()
69
+ ._tiptapEditor.state.doc.resolve(
70
+ resolvedContentEndPos.before(resolvedContentEndPos.depth + 1)
71
+ )
72
+ .end()
73
+ )
74
+ )
75
+ );
76
+ }
77
+ }
78
+
79
+ describe("Test moveSelectedBlockAndSelection", () => {
80
+ it("Text selection", () => {
81
+ getEditor().setTextCursorPosition("paragraph-1");
82
+ makeSelectionSpanContent("text");
83
+
84
+ moveSelectedBlockAndSelection(getEditor(), "paragraph-0", "before");
85
+
86
+ const selection = getEditor()._tiptapEditor.state.selection;
87
+ getEditor().setTextCursorPosition("paragraph-1");
88
+ makeSelectionSpanContent("text");
89
+
90
+ expect(
91
+ selection.eq(getEditor()._tiptapEditor.state.selection)
92
+ ).toBeTruthy();
93
+ });
94
+
95
+ it("Node selection", () => {
96
+ getEditor().setTextCursorPosition("image-0");
97
+ makeSelectionSpanContent("node");
98
+
99
+ moveSelectedBlockAndSelection(getEditor(), "paragraph-0", "before");
100
+
101
+ const selection = getEditor()._tiptapEditor.state.selection;
102
+ getEditor().setTextCursorPosition("image-0");
103
+ makeSelectionSpanContent("node");
104
+
105
+ expect(
106
+ selection.eq(getEditor()._tiptapEditor.state.selection)
107
+ ).toBeTruthy();
108
+ });
109
+
110
+ it("Cell selection", () => {
111
+ getEditor().setTextCursorPosition("table-0");
112
+ makeSelectionSpanContent("cell");
113
+
114
+ moveSelectedBlockAndSelection(getEditor(), "paragraph-0", "before");
115
+
116
+ const selection = getEditor()._tiptapEditor.state.selection;
117
+ getEditor().setTextCursorPosition("table-0");
118
+ makeSelectionSpanContent("cell");
119
+
120
+ expect(
121
+ selection.eq(getEditor()._tiptapEditor.state.selection)
122
+ ).toBeTruthy();
123
+ });
124
+ });
125
+
126
+ describe("Test moveBlockUp", () => {
127
+ it("Basic", () => {
128
+ getEditor().setTextCursorPosition("paragraph-1");
129
+
130
+ moveBlockUp(getEditor());
131
+
132
+ expect(getEditor().document).toMatchSnapshot();
133
+ });
134
+
135
+ it("Into children", () => {
136
+ getEditor().setTextCursorPosition("paragraph-2");
137
+
138
+ moveBlockUp(getEditor());
139
+
140
+ expect(getEditor().document).toMatchSnapshot();
141
+ });
142
+
143
+ it("Out of children", () => {
144
+ getEditor().setTextCursorPosition("nested-paragraph-1");
145
+
146
+ moveBlockUp(getEditor());
147
+
148
+ expect(getEditor().document).toMatchSnapshot();
149
+ });
150
+
151
+ it("First block", () => {
152
+ getEditor().setTextCursorPosition("paragraph-0");
153
+
154
+ moveBlockUp(getEditor());
155
+
156
+ expect(getEditor().document).toMatchSnapshot();
157
+ });
158
+ });
159
+
160
+ describe("Test moveBlockDown", () => {
161
+ it("Basic", () => {
162
+ getEditor().setTextCursorPosition("paragraph-0");
163
+
164
+ moveBlockDown(getEditor());
165
+
166
+ expect(getEditor().document).toMatchSnapshot();
167
+ });
168
+
169
+ it("Into children", () => {
170
+ getEditor().setTextCursorPosition("paragraph-1");
171
+
172
+ moveBlockDown(getEditor());
173
+
174
+ expect(getEditor().document).toMatchSnapshot();
175
+ });
176
+
177
+ it("Out of children", () => {
178
+ getEditor().setTextCursorPosition("nested-paragraph-1");
179
+
180
+ moveBlockDown(getEditor());
181
+
182
+ expect(getEditor().document).toMatchSnapshot();
183
+ });
184
+
185
+ it("Last block", () => {
186
+ getEditor().setTextCursorPosition("trailing-paragraph");
187
+
188
+ moveBlockDown(getEditor());
189
+
190
+ expect(getEditor().document).toMatchSnapshot();
191
+ });
192
+ });
@@ -0,0 +1,178 @@
1
+ import { NodeSelection, Selection, TextSelection } from "prosemirror-state";
2
+ import { CellSelection } from "prosemirror-tables";
3
+
4
+ import type { BlockNoteEditor } from "../../../../editor/BlockNoteEditor";
5
+ import { BlockIdentifier } from "../../../../schema/index.js";
6
+ import { getBlockInfoFromSelection } from "../../../getBlockInfoFromPos.js";
7
+ import { getNodeById } from "../../../nodeUtil.js";
8
+
9
+ type BlockSelectionData = (
10
+ | {
11
+ type: "text";
12
+ anchor: number;
13
+ head: number;
14
+ }
15
+ | {
16
+ type: "node";
17
+ from: number;
18
+ }
19
+ | {
20
+ type: "cell";
21
+ anchorCell: number;
22
+ headCell: number;
23
+ }
24
+ ) & {
25
+ blockId: string;
26
+ blockPos: number;
27
+ };
28
+
29
+ // `getBlockSelectionData` and `updateBlockSelectionFromData` are used to save
30
+ // and restore the selection within a block, when the block is moved.
31
+ function getBlockSelectionData(
32
+ editor: BlockNoteEditor<any, any, any>
33
+ ): BlockSelectionData {
34
+ const { blockContainer } = getBlockInfoFromSelection(
35
+ editor._tiptapEditor.state
36
+ );
37
+
38
+ const selectionData = {
39
+ blockId: blockContainer.node.attrs.id,
40
+ blockPos: blockContainer.beforePos,
41
+ };
42
+
43
+ if (editor._tiptapEditor.state.selection instanceof CellSelection) {
44
+ return {
45
+ ...selectionData,
46
+ type: "cell" as const,
47
+ anchorCell: (editor._tiptapEditor.state.selection as CellSelection)
48
+ .$anchorCell.pos,
49
+ headCell: (editor._tiptapEditor.state.selection as CellSelection)
50
+ .$headCell.pos,
51
+ };
52
+ } else if (editor._tiptapEditor.state.selection instanceof NodeSelection) {
53
+ return {
54
+ ...selectionData,
55
+ type: "node" as const,
56
+ from: editor._tiptapEditor.state.selection.from,
57
+ };
58
+ } else {
59
+ return {
60
+ ...selectionData,
61
+ type: "text" as const,
62
+ anchor: editor._tiptapEditor.state.selection.anchor,
63
+ head: editor._tiptapEditor.state.selection.head,
64
+ };
65
+ }
66
+ }
67
+
68
+ function updateBlockSelectionFromData(
69
+ editor: BlockNoteEditor<any, any, any>,
70
+ data: BlockSelectionData
71
+ ) {
72
+ const blockPos = getNodeById(
73
+ data.blockId,
74
+ editor._tiptapEditor.state.doc
75
+ ).posBeforeNode;
76
+
77
+ let selection: Selection;
78
+ if (data.type === "cell") {
79
+ selection = CellSelection.create(
80
+ editor._tiptapEditor.state.doc,
81
+ data.anchorCell + (blockPos - data.blockPos),
82
+ data.headCell + (blockPos - data.blockPos)
83
+ );
84
+ } else if (data.type === "node") {
85
+ selection = NodeSelection.create(
86
+ editor._tiptapEditor.state.doc,
87
+ data.from + (blockPos - data.blockPos)
88
+ );
89
+ } else {
90
+ selection = TextSelection.create(
91
+ editor._tiptapEditor.state.doc,
92
+ data.anchor + (blockPos - data.blockPos),
93
+ data.head + (blockPos - data.blockPos)
94
+ );
95
+ }
96
+
97
+ editor._tiptapEditor.view.dispatch(
98
+ editor._tiptapEditor.state.tr.setSelection(selection)
99
+ );
100
+ }
101
+
102
+ export function moveSelectedBlockAndSelection(
103
+ editor: BlockNoteEditor<any, any, any>,
104
+ referenceBlock: BlockIdentifier,
105
+ placement: "before" | "after"
106
+ ) {
107
+ const { block } = editor.getTextCursorPosition();
108
+ const selectionData = getBlockSelectionData(editor);
109
+
110
+ editor.removeBlocks([block]);
111
+ editor.insertBlocks([block], referenceBlock, placement);
112
+
113
+ updateBlockSelectionFromData(editor, selectionData);
114
+ }
115
+
116
+ export function moveBlockUp(editor: BlockNoteEditor<any, any, any>) {
117
+ // This function currently only supports moving a single block.
118
+ const editorSelection = editor.getSelection();
119
+ if (editorSelection && editorSelection.blocks.length > 1) {
120
+ return;
121
+ }
122
+
123
+ const { prevBlock, parentBlock } = editor.getTextCursorPosition();
124
+
125
+ let referenceBlockId: string | undefined;
126
+ let placement: "before" | "after" | undefined;
127
+
128
+ if (!prevBlock) {
129
+ if (parentBlock) {
130
+ referenceBlockId = parentBlock.id;
131
+ placement = "before";
132
+ }
133
+ } else if (prevBlock.children.length > 0) {
134
+ referenceBlockId = prevBlock.children[prevBlock.children.length - 1].id;
135
+ placement = "after";
136
+ } else {
137
+ referenceBlockId = prevBlock.id;
138
+ placement = "before";
139
+ }
140
+
141
+ if (!referenceBlockId || !placement) {
142
+ return;
143
+ }
144
+
145
+ moveSelectedBlockAndSelection(editor, referenceBlockId, placement);
146
+ }
147
+
148
+ export function moveBlockDown(editor: BlockNoteEditor<any, any, any>) {
149
+ // This function currently only supports moving a single block.
150
+ const editorSelection = editor.getSelection();
151
+ if (editorSelection && editorSelection.blocks.length > 1) {
152
+ return;
153
+ }
154
+
155
+ const { nextBlock, parentBlock } = editor.getTextCursorPosition();
156
+
157
+ let referenceBlockId: string | undefined;
158
+ let placement: "before" | "after" | undefined;
159
+
160
+ if (!nextBlock) {
161
+ if (parentBlock) {
162
+ referenceBlockId = parentBlock.id;
163
+ placement = "after";
164
+ }
165
+ } else if (nextBlock.children.length > 0) {
166
+ referenceBlockId = nextBlock.children[0].id;
167
+ placement = "before";
168
+ } else {
169
+ referenceBlockId = nextBlock.id;
170
+ placement = "after";
171
+ }
172
+
173
+ if (!referenceBlockId || !placement) {
174
+ return;
175
+ }
176
+
177
+ moveSelectedBlockAndSelection(editor, referenceBlockId, placement);
178
+ }