@blocknote/core 0.17.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/dist/blocknote.js +2774 -1804
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +9 -6
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/src/api/blockManipulation/commands/insertBlocks/insertBlocks.js +27 -0
  6. package/dist/src/api/blockManipulation/commands/insertBlocks/insertBlocks.js.map +1 -0
  7. package/dist/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.js +99 -0
  8. package/dist/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.js.map +1 -0
  9. package/dist/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.js +97 -0
  10. package/dist/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.js.map +1 -0
  11. package/dist/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.js +88 -0
  12. package/dist/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.js.map +1 -0
  13. package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.js +116 -0
  14. package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.js.map +1 -0
  15. package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.test.js +106 -0
  16. package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.test.js.map +1 -0
  17. package/dist/src/api/blockManipulation/commands/nestBlock/nestBlock.js +57 -0
  18. package/dist/src/api/blockManipulation/commands/nestBlock/nestBlock.js.map +1 -0
  19. package/dist/src/api/blockManipulation/commands/removeBlocks/removeBlocks.js +43 -0
  20. package/dist/src/api/blockManipulation/commands/removeBlocks/removeBlocks.js.map +1 -0
  21. package/dist/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.js +27 -0
  22. package/dist/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.js.map +1 -0
  23. package/dist/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.js +29 -0
  24. package/dist/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.js.map +1 -0
  25. package/dist/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.js +157 -0
  26. package/dist/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.js.map +1 -0
  27. package/dist/src/api/blockManipulation/commands/splitBlock/splitBlock.js +27 -0
  28. package/dist/src/api/blockManipulation/commands/splitBlock/splitBlock.js.map +1 -0
  29. package/dist/src/api/blockManipulation/commands/splitBlock/splitBlock.test.js +64 -0
  30. package/dist/src/api/blockManipulation/commands/splitBlock/splitBlock.test.js.map +1 -0
  31. package/dist/src/api/blockManipulation/commands/updateBlock/updateBlock.js +145 -0
  32. package/dist/src/api/blockManipulation/commands/updateBlock/updateBlock.js.map +1 -0
  33. package/dist/src/api/blockManipulation/commands/updateBlock/updateBlock.test.js +252 -0
  34. package/dist/src/api/blockManipulation/commands/updateBlock/updateBlock.test.js.map +1 -0
  35. package/dist/src/api/blockManipulation/insertContentAt.js +64 -0
  36. package/dist/src/api/blockManipulation/insertContentAt.js.map +1 -0
  37. package/dist/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.js +76 -0
  38. package/dist/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.js.map +1 -0
  39. package/dist/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.js +33 -0
  40. package/dist/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.js.map +1 -0
  41. package/dist/src/api/blockManipulation/setupTestEnv.js +172 -0
  42. package/dist/src/api/blockManipulation/setupTestEnv.js.map +1 -0
  43. package/dist/src/api/clipboard/clipboard.test.js +246 -0
  44. package/dist/src/api/clipboard/clipboard.test.js.map +1 -0
  45. package/dist/src/api/clipboard/fromClipboard/acceptedMIMETypes.js +8 -0
  46. package/dist/src/api/clipboard/fromClipboard/acceptedMIMETypes.js.map +1 -0
  47. package/dist/src/api/clipboard/fromClipboard/fileDropExtension.js +38 -0
  48. package/dist/src/api/clipboard/fromClipboard/fileDropExtension.js.map +1 -0
  49. package/dist/src/api/clipboard/fromClipboard/handleFileInsertion.js +109 -0
  50. package/dist/src/api/clipboard/fromClipboard/handleFileInsertion.js.map +1 -0
  51. package/dist/src/api/clipboard/fromClipboard/handleVSCodePaste.js +26 -0
  52. package/dist/src/api/clipboard/fromClipboard/handleVSCodePaste.js.map +1 -0
  53. package/dist/src/api/clipboard/fromClipboard/pasteExtension.js +57 -0
  54. package/dist/src/api/clipboard/fromClipboard/pasteExtension.js.map +1 -0
  55. package/dist/src/api/clipboard/toClipboard/copyExtension.js +132 -0
  56. package/dist/src/api/clipboard/toClipboard/copyExtension.js.map +1 -0
  57. package/dist/src/api/exporters/html/externalHTMLExporter.js +35 -0
  58. package/dist/src/api/exporters/html/externalHTMLExporter.js.map +1 -0
  59. package/dist/src/api/exporters/html/htmlConversion.test.js +72 -0
  60. package/dist/src/api/exporters/html/htmlConversion.test.js.map +1 -0
  61. package/dist/src/api/exporters/html/internalHTMLSerializer.js +21 -0
  62. package/dist/src/api/exporters/html/internalHTMLSerializer.js.map +1 -0
  63. package/dist/src/api/exporters/html/util/serializeBlocksExternalHTML.js +141 -0
  64. package/dist/src/api/exporters/html/util/serializeBlocksExternalHTML.js.map +1 -0
  65. package/dist/src/api/exporters/html/util/serializeBlocksInternalHTML.js +96 -0
  66. package/dist/src/api/exporters/html/util/serializeBlocksInternalHTML.js.map +1 -0
  67. package/dist/src/api/exporters/markdown/markdownExporter.js +31 -0
  68. package/dist/src/api/exporters/markdown/markdownExporter.js.map +1 -0
  69. package/dist/src/api/exporters/markdown/markdownExporter.test.js +57 -0
  70. package/dist/src/api/exporters/markdown/markdownExporter.test.js.map +1 -0
  71. package/dist/src/api/exporters/markdown/removeUnderlinesRehypePlugin.js +33 -0
  72. package/dist/src/api/exporters/markdown/removeUnderlinesRehypePlugin.js.map +1 -0
  73. package/dist/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.js +37 -0
  74. package/dist/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.js.map +1 -0
  75. package/dist/src/api/getBlockInfoFromPos.js +171 -0
  76. package/dist/src/api/getBlockInfoFromPos.js.map +1 -0
  77. package/dist/src/api/nodeConversions/blockToNode.js +197 -0
  78. package/dist/src/api/nodeConversions/blockToNode.js.map +1 -0
  79. package/dist/src/api/nodeConversions/fragmentToBlocks.js +50 -0
  80. package/dist/src/api/nodeConversions/fragmentToBlocks.js.map +1 -0
  81. package/dist/src/api/nodeConversions/nodeConversions.test.js +54 -0
  82. package/dist/src/api/nodeConversions/nodeConversions.test.js.map +1 -0
  83. package/dist/src/api/nodeConversions/nodeToBlock.js +316 -0
  84. package/dist/src/api/nodeConversions/nodeToBlock.js.map +1 -0
  85. package/dist/src/api/nodeUtil.js +28 -0
  86. package/dist/src/api/nodeUtil.js.map +1 -0
  87. package/dist/src/api/parsers/html/parseHTML.js +19 -0
  88. package/dist/src/api/parsers/html/parseHTML.js.map +1 -0
  89. package/dist/src/api/parsers/html/parseHTML.test.js +470 -0
  90. package/dist/src/api/parsers/html/parseHTML.test.js.map +1 -0
  91. package/dist/src/api/parsers/html/util/nestedLists.js +106 -0
  92. package/dist/src/api/parsers/html/util/nestedLists.js.map +1 -0
  93. package/dist/src/api/parsers/html/util/nestedLists.test.js +166 -0
  94. package/dist/src/api/parsers/html/util/nestedLists.test.js.map +1 -0
  95. package/dist/src/api/parsers/markdown/parseMarkdown.js +52 -0
  96. package/dist/src/api/parsers/markdown/parseMarkdown.js.map +1 -0
  97. package/dist/src/api/parsers/markdown/parseMarkdown.test.js +109 -0
  98. package/dist/src/api/parsers/markdown/parseMarkdown.test.js.map +1 -0
  99. package/dist/src/api/testUtil/cases/customBlocks.js +313 -0
  100. package/dist/src/api/testUtil/cases/customBlocks.js.map +1 -0
  101. package/dist/src/api/testUtil/cases/customInlineContent.js +91 -0
  102. package/dist/src/api/testUtil/cases/customInlineContent.js.map +1 -0
  103. package/dist/src/api/testUtil/cases/customStyles.js +83 -0
  104. package/dist/src/api/testUtil/cases/customStyles.js.map +1 -0
  105. package/dist/src/api/testUtil/cases/defaultSchema.js +673 -0
  106. package/dist/src/api/testUtil/cases/defaultSchema.js.map +1 -0
  107. package/dist/src/api/testUtil/index.js +2 -0
  108. package/dist/src/api/testUtil/index.js.map +1 -0
  109. package/dist/src/api/testUtil/partialBlockTestUtil.js +114 -0
  110. package/dist/src/api/testUtil/partialBlockTestUtil.js.map +1 -0
  111. package/dist/src/api/testUtil/paste.js +29 -0
  112. package/dist/src/api/testUtil/paste.js.map +1 -0
  113. package/dist/src/blocks/AudioBlockContent/AudioBlockContent.js +97 -0
  114. package/dist/src/blocks/AudioBlockContent/AudioBlockContent.js.map +1 -0
  115. package/dist/src/blocks/AudioBlockContent/audioBlockHelpers.js +5 -0
  116. package/dist/src/blocks/AudioBlockContent/audioBlockHelpers.js.map +1 -0
  117. package/dist/src/blocks/CodeBlockContent/CodeBlockContent.js +273 -0
  118. package/dist/src/blocks/CodeBlockContent/CodeBlockContent.js.map +1 -0
  119. package/dist/src/blocks/CodeBlockContent/defaultSupportedLanguages.js +90 -0
  120. package/dist/src/blocks/CodeBlockContent/defaultSupportedLanguages.js.map +1 -0
  121. package/dist/src/blocks/FileBlockContent/FileBlockContent.js +70 -0
  122. package/dist/src/blocks/FileBlockContent/FileBlockContent.js.map +1 -0
  123. package/dist/src/blocks/FileBlockContent/fileBlockHelpers.js +317 -0
  124. package/dist/src/blocks/FileBlockContent/fileBlockHelpers.js.map +1 -0
  125. package/dist/src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.js +15 -0
  126. package/dist/src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.js.map +1 -0
  127. package/dist/src/blocks/HeadingBlockContent/HeadingBlockContent.js +141 -0
  128. package/dist/src/blocks/HeadingBlockContent/HeadingBlockContent.js.map +1 -0
  129. package/dist/src/blocks/ImageBlockContent/ImageBlockContent.js +106 -0
  130. package/dist/src/blocks/ImageBlockContent/ImageBlockContent.js.map +1 -0
  131. package/dist/src/blocks/ImageBlockContent/imageBlockHelpers.js +6 -0
  132. package/dist/src/blocks/ImageBlockContent/imageBlockHelpers.js.map +1 -0
  133. package/dist/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.js +111 -0
  134. package/dist/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.js.map +1 -0
  135. package/dist/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.js +218 -0
  136. package/dist/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.js.map +1 -0
  137. package/dist/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.js +41 -0
  138. package/dist/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.js.map +1 -0
  139. package/dist/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.js +58 -0
  140. package/dist/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.js.map +1 -0
  141. package/dist/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.js +128 -0
  142. package/dist/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.js.map +1 -0
  143. package/dist/src/blocks/ParagraphBlockContent/ParagraphBlockContent.js +51 -0
  144. package/dist/src/blocks/ParagraphBlockContent/ParagraphBlockContent.js.map +1 -0
  145. package/dist/src/blocks/TableBlockContent/TableBlockContent.js +130 -0
  146. package/dist/src/blocks/TableBlockContent/TableBlockContent.js.map +1 -0
  147. package/dist/src/blocks/TableBlockContent/TableExtension.js +57 -0
  148. package/dist/src/blocks/TableBlockContent/TableExtension.js.map +1 -0
  149. package/dist/src/blocks/VideoBlockContent/VideoBlockContent.js +103 -0
  150. package/dist/src/blocks/VideoBlockContent/VideoBlockContent.js.map +1 -0
  151. package/dist/src/blocks/VideoBlockContent/videoBlockHelpers.js +6 -0
  152. package/dist/src/blocks/VideoBlockContent/videoBlockHelpers.js.map +1 -0
  153. package/dist/src/blocks/defaultBlockHelpers.js +50 -0
  154. package/dist/src/blocks/defaultBlockHelpers.js.map +1 -0
  155. package/dist/src/blocks/defaultBlockTypeGuards.js +40 -0
  156. package/dist/src/blocks/defaultBlockTypeGuards.js.map +1 -0
  157. package/dist/src/blocks/defaultBlocks.js +50 -0
  158. package/dist/src/blocks/defaultBlocks.js.map +1 -0
  159. package/dist/src/blocks/defaultProps.js +19 -0
  160. package/dist/src/blocks/defaultProps.js.map +1 -0
  161. package/dist/src/editor/BlockNoteEditor.js +750 -0
  162. package/dist/src/editor/BlockNoteEditor.js.map +1 -0
  163. package/dist/src/editor/BlockNoteEditor.test.js +65 -0
  164. package/dist/src/editor/BlockNoteEditor.test.js.map +1 -0
  165. package/dist/src/editor/BlockNoteExtensions.js +149 -0
  166. package/dist/src/editor/BlockNoteExtensions.js.map +1 -0
  167. package/dist/src/editor/BlockNoteSchema.js +38 -0
  168. package/dist/src/editor/BlockNoteSchema.js.map +1 -0
  169. package/dist/src/editor/BlockNoteTipTapEditor.js +169 -0
  170. package/dist/src/editor/BlockNoteTipTapEditor.js.map +1 -0
  171. package/dist/src/editor/cursorPositionTypes.js +2 -0
  172. package/dist/src/editor/cursorPositionTypes.js.map +1 -0
  173. package/dist/src/editor/defaultColors.js +77 -0
  174. package/dist/src/editor/defaultColors.js.map +1 -0
  175. package/dist/src/editor/selectionTypes.js +2 -0
  176. package/dist/src/editor/selectionTypes.js.map +1 -0
  177. package/dist/src/editor/transformPasted.js +79 -0
  178. package/dist/src/editor/transformPasted.js.map +1 -0
  179. package/dist/src/exporter/Exporter.js +36 -0
  180. package/dist/src/exporter/Exporter.js.map +1 -0
  181. package/dist/src/exporter/index.js +3 -0
  182. package/dist/src/exporter/index.js.map +1 -0
  183. package/dist/src/exporter/mapping.js +12 -0
  184. package/dist/src/exporter/mapping.js.map +1 -0
  185. package/dist/src/extensions/BackgroundColor/BackgroundColorExtension.js +30 -0
  186. package/dist/src/extensions/BackgroundColor/BackgroundColorExtension.js.map +1 -0
  187. package/dist/src/extensions/BackgroundColor/BackgroundColorMark.js +39 -0
  188. package/dist/src/extensions/BackgroundColor/BackgroundColorMark.js.map +1 -0
  189. package/dist/src/extensions/FilePanel/FilePanelPlugin.js +131 -0
  190. package/dist/src/extensions/FilePanel/FilePanelPlugin.js.map +1 -0
  191. package/dist/src/extensions/FormattingToolbar/FormattingToolbarPlugin.js +195 -0
  192. package/dist/src/extensions/FormattingToolbar/FormattingToolbarPlugin.js.map +1 -0
  193. package/dist/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.js +309 -0
  194. package/dist/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.js.map +1 -0
  195. package/dist/src/extensions/LinkToolbar/LinkToolbarPlugin.js +247 -0
  196. package/dist/src/extensions/LinkToolbar/LinkToolbarPlugin.js.map +1 -0
  197. package/dist/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.js +51 -0
  198. package/dist/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.js.map +1 -0
  199. package/dist/src/extensions/Placeholder/PlaceholderPlugin.js +81 -0
  200. package/dist/src/extensions/Placeholder/PlaceholderPlugin.js.map +1 -0
  201. package/dist/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.js +183 -0
  202. package/dist/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.js.map +1 -0
  203. package/dist/src/extensions/SideMenu/MultipleNodeSelection.js +68 -0
  204. package/dist/src/extensions/SideMenu/MultipleNodeSelection.js.map +1 -0
  205. package/dist/src/extensions/SideMenu/SideMenuPlugin.js +339 -0
  206. package/dist/src/extensions/SideMenu/SideMenuPlugin.js.map +1 -0
  207. package/dist/src/extensions/SideMenu/dragging.js +128 -0
  208. package/dist/src/extensions/SideMenu/dragging.js.map +1 -0
  209. package/dist/src/extensions/SuggestionMenu/DefaultGridSuggestionItem.js +2 -0
  210. package/dist/src/extensions/SuggestionMenu/DefaultGridSuggestionItem.js.map +1 -0
  211. package/dist/src/extensions/SuggestionMenu/DefaultSuggestionItem.js +2 -0
  212. package/dist/src/extensions/SuggestionMenu/DefaultSuggestionItem.js.map +1 -0
  213. package/dist/src/extensions/SuggestionMenu/SuggestionPlugin.js +245 -0
  214. package/dist/src/extensions/SuggestionMenu/SuggestionPlugin.js.map +1 -0
  215. package/dist/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.js +26 -0
  216. package/dist/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.js.map +1 -0
  217. package/dist/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.js +244 -0
  218. package/dist/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.js.map +1 -0
  219. package/dist/src/extensions/TableHandles/TableHandlesPlugin.js +553 -0
  220. package/dist/src/extensions/TableHandles/TableHandlesPlugin.js.map +1 -0
  221. package/dist/src/extensions/TextAlignment/TextAlignmentExtension.js +36 -0
  222. package/dist/src/extensions/TextAlignment/TextAlignmentExtension.js.map +1 -0
  223. package/dist/src/extensions/TextColor/TextColorExtension.js +29 -0
  224. package/dist/src/extensions/TextColor/TextColorExtension.js.map +1 -0
  225. package/dist/src/extensions/TextColor/TextColorMark.js +37 -0
  226. package/dist/src/extensions/TextColor/TextColorMark.js.map +1 -0
  227. package/dist/src/extensions/TrailingNode/TrailingNodeExtension.js +58 -0
  228. package/dist/src/extensions/TrailingNode/TrailingNodeExtension.js.map +1 -0
  229. package/dist/src/extensions/UniqueID/UniqueID.js +283 -0
  230. package/dist/src/extensions/UniqueID/UniqueID.js.map +1 -0
  231. package/dist/src/extensions/getDraggableBlockFromElement.js +13 -0
  232. package/dist/src/extensions/getDraggableBlockFromElement.js.map +1 -0
  233. package/dist/src/extensions-shared/UiElementPosition.js +2 -0
  234. package/dist/src/extensions-shared/UiElementPosition.js.map +1 -0
  235. package/dist/src/i18n/dictionary.js +4 -0
  236. package/dist/src/i18n/dictionary.js.map +1 -0
  237. package/dist/src/i18n/locales/ar.js +298 -0
  238. package/dist/src/i18n/locales/ar.js.map +1 -0
  239. package/dist/src/i18n/locales/de.js +313 -0
  240. package/dist/src/i18n/locales/de.js.map +1 -0
  241. package/dist/src/i18n/locales/en.js +314 -0
  242. package/dist/src/i18n/locales/en.js.map +1 -0
  243. package/dist/src/i18n/locales/es.js +312 -0
  244. package/dist/src/i18n/locales/es.js.map +1 -0
  245. package/dist/src/i18n/locales/fr.js +313 -0
  246. package/dist/src/i18n/locales/fr.js.map +1 -0
  247. package/dist/src/i18n/locales/hr.js +308 -0
  248. package/dist/src/i18n/locales/hr.js.map +1 -0
  249. package/dist/src/i18n/locales/index.js +16 -0
  250. package/dist/src/i18n/locales/index.js.map +1 -0
  251. package/dist/src/i18n/locales/is.js +305 -0
  252. package/dist/src/i18n/locales/is.js.map +1 -0
  253. package/dist/src/i18n/locales/ja.js +333 -0
  254. package/dist/src/i18n/locales/ja.js.map +1 -0
  255. package/dist/src/i18n/locales/ko.js +326 -0
  256. package/dist/src/i18n/locales/ko.js.map +1 -0
  257. package/dist/src/i18n/locales/nl.js +313 -0
  258. package/dist/src/i18n/locales/nl.js.map +1 -0
  259. package/dist/src/i18n/locales/pl.js +297 -0
  260. package/dist/src/i18n/locales/pl.js.map +1 -0
  261. package/dist/src/i18n/locales/pt.js +305 -0
  262. package/dist/src/i18n/locales/pt.js.map +1 -0
  263. package/dist/src/i18n/locales/ru.js +340 -0
  264. package/dist/src/i18n/locales/ru.js.map +1 -0
  265. package/dist/src/i18n/locales/vi.js +312 -0
  266. package/dist/src/i18n/locales/vi.js.map +1 -0
  267. package/dist/src/i18n/locales/zh.js +346 -0
  268. package/dist/src/i18n/locales/zh.js.map +1 -0
  269. package/dist/src/index.js +55 -0
  270. package/dist/src/index.js.map +1 -0
  271. package/dist/src/pm-nodes/BlockContainer.js +72 -0
  272. package/dist/src/pm-nodes/BlockContainer.js.map +1 -0
  273. package/dist/src/pm-nodes/BlockGroup.js +43 -0
  274. package/dist/src/pm-nodes/BlockGroup.js.map +1 -0
  275. package/dist/src/pm-nodes/Doc.js +7 -0
  276. package/dist/src/pm-nodes/Doc.js.map +1 -0
  277. package/dist/src/pm-nodes/index.js +4 -0
  278. package/dist/src/pm-nodes/index.js.map +1 -0
  279. package/dist/src/schema/blocks/createSpec.js +126 -0
  280. package/dist/src/schema/blocks/createSpec.js.map +1 -0
  281. package/dist/src/schema/blocks/internal.js +147 -0
  282. package/dist/src/schema/blocks/internal.js.map +1 -0
  283. package/dist/src/schema/blocks/types.js +2 -0
  284. package/dist/src/schema/blocks/types.js.map +1 -0
  285. package/dist/src/schema/index.js +11 -0
  286. package/dist/src/schema/index.js.map +1 -0
  287. package/dist/src/schema/inlineContent/createSpec.js +64 -0
  288. package/dist/src/schema/inlineContent/createSpec.js.map +1 -0
  289. package/dist/src/schema/inlineContent/internal.js +52 -0
  290. package/dist/src/schema/inlineContent/internal.js.map +1 -0
  291. package/dist/src/schema/inlineContent/types.js +10 -0
  292. package/dist/src/schema/inlineContent/types.js.map +1 -0
  293. package/dist/src/schema/propTypes.js +2 -0
  294. package/dist/src/schema/propTypes.js.map +1 -0
  295. package/dist/src/schema/styles/createSpec.js +48 -0
  296. package/dist/src/schema/styles/createSpec.js.map +1 -0
  297. package/dist/src/schema/styles/internal.js +53 -0
  298. package/dist/src/schema/styles/internal.js.map +1 -0
  299. package/dist/src/schema/styles/types.js +2 -0
  300. package/dist/src/schema/styles/types.js.map +1 -0
  301. package/dist/src/util/EventEmitter.js +33 -0
  302. package/dist/src/util/EventEmitter.js.map +1 -0
  303. package/dist/src/util/browser.js +17 -0
  304. package/dist/src/util/browser.js.map +1 -0
  305. package/dist/src/util/combineByGroup.js +20 -0
  306. package/dist/src/util/combineByGroup.js.map +1 -0
  307. package/dist/src/util/esmDependencies.js +35 -0
  308. package/dist/src/util/esmDependencies.js.map +1 -0
  309. package/dist/src/util/string.js +14 -0
  310. package/dist/src/util/string.js.map +1 -0
  311. package/dist/src/util/typescript.js +12 -0
  312. package/dist/src/util/typescript.js.map +1 -0
  313. package/dist/style.css +1 -1
  314. package/dist/tsconfig.tsbuildinfo +1 -0
  315. package/dist/webpack-stats.json +1 -1
  316. package/package.json +9 -7
  317. package/src/api/blockManipulation/commands/insertBlocks/__snapshots__/insertBlocks.test.ts.snap +30 -0
  318. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +2 -0
  319. package/src/api/blockManipulation/commands/mergeBlocks/__snapshots__/mergeBlocks.test.ts.snap +25 -0
  320. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +2 -2
  321. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +104 -39
  322. package/src/api/blockManipulation/commands/moveBlock/__snapshots__/moveBlock.test.ts.snap +40 -0
  323. package/src/api/blockManipulation/commands/moveBlock/moveBlock.ts +3 -5
  324. package/src/api/blockManipulation/commands/nestBlock/nestBlock.ts +100 -0
  325. package/src/api/blockManipulation/commands/removeBlocks/__snapshots__/removeBlocks.test.ts.snap +10 -0
  326. package/src/api/blockManipulation/commands/removeBlocks/removeBlocks.ts +1 -1
  327. package/src/api/blockManipulation/commands/replaceBlocks/__snapshots__/replaceBlocks.test.ts.snap +40 -0
  328. package/src/api/blockManipulation/commands/splitBlock/__snapshots__/splitBlock.test.ts.snap +30 -0
  329. package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +8 -4
  330. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +11 -7
  331. package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +87 -0
  332. package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +5 -5
  333. package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +192 -107
  334. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts +48 -33
  335. package/src/api/clipboard/clipboard.test.ts +1 -1
  336. package/src/api/clipboard/fromClipboard/acceptedMIMETypes.ts +1 -0
  337. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +1 -1
  338. package/src/api/clipboard/fromClipboard/handleVSCodePaste.ts +49 -0
  339. package/src/api/clipboard/fromClipboard/pasteExtension.ts +6 -0
  340. package/src/api/clipboard/toClipboard/copyExtension.ts +1 -1
  341. package/src/api/exporters/html/__snapshots__/codeBlock/defaultLanguage/external.html +1 -0
  342. package/src/api/exporters/html/__snapshots__/codeBlock/defaultLanguage/internal.html +1 -0
  343. package/src/api/exporters/html/__snapshots__/codeBlock/empty/external.html +1 -0
  344. package/src/api/exporters/html/__snapshots__/codeBlock/empty/internal.html +1 -0
  345. package/src/api/exporters/html/__snapshots__/codeBlock/python/external.html +1 -0
  346. package/src/api/exporters/html/__snapshots__/codeBlock/python/internal.html +1 -0
  347. package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -1
  348. package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -1
  349. package/src/api/exporters/html/__snapshots__/image/noName/internal.html +1 -1
  350. package/src/api/exporters/html/__snapshots__/image/noPreview/internal.html +1 -1
  351. package/src/api/exporters/html/__snapshots__/lists/basic/internal.html +1 -1
  352. package/src/api/exporters/html/__snapshots__/lists/nested/internal.html +1 -1
  353. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -1
  354. package/src/api/exporters/html/__snapshots__/simpleImage/basic/internal.html +1 -1
  355. package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -1
  356. package/src/api/exporters/html/__snapshots__/simpleImage/nested/internal.html +1 -1
  357. package/src/api/exporters/html/__snapshots__/simpleImage/noCaption/external.html +1 -1
  358. package/src/api/exporters/html/__snapshots__/simpleImage/noName/external.html +1 -1
  359. package/src/api/exporters/html/__snapshots__/simpleImage/noName/internal.html +1 -1
  360. package/src/api/exporters/html/__snapshots__/simpleImage/noPreview/external.html +1 -1
  361. package/src/api/exporters/html/__snapshots__/simpleImage/noPreview/internal.html +1 -1
  362. package/src/api/exporters/html/__snapshots__/table/allColWidths/external.html +1 -0
  363. package/src/api/exporters/html/__snapshots__/table/allColWidths/internal.html +1 -0
  364. package/src/api/exporters/html/__snapshots__/table/basic/external.html +1 -0
  365. package/src/api/exporters/html/__snapshots__/table/basic/internal.html +1 -0
  366. package/src/api/exporters/html/__snapshots__/table/mixedColWidths/external.html +1 -0
  367. package/src/api/exporters/html/__snapshots__/table/mixedColWidths/internal.html +1 -0
  368. package/src/api/exporters/html/htmlConversion.test.ts +1 -4
  369. package/src/api/exporters/html/internalHTMLSerializer.ts +2 -7
  370. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +7 -1
  371. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +75 -33
  372. package/src/api/exporters/markdown/__snapshots__/codeBlock/defaultLanguage/markdown.md +3 -0
  373. package/src/api/exporters/markdown/__snapshots__/codeBlock/empty/markdown.md +2 -0
  374. package/src/api/exporters/markdown/__snapshots__/codeBlock/python/markdown.md +3 -0
  375. package/src/api/exporters/markdown/__snapshots__/table/allColWidths/markdown.md +5 -0
  376. package/src/api/exporters/markdown/__snapshots__/table/basic/markdown.md +5 -0
  377. package/src/api/exporters/markdown/__snapshots__/table/mixedColWidths/markdown.md +5 -0
  378. package/src/api/exporters/markdown/markdownExporter.test.ts +1 -4
  379. package/src/api/getBlockInfoFromPos.ts +113 -58
  380. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +711 -0
  381. package/src/api/nodeConversions/blockToNode.ts +62 -26
  382. package/src/api/nodeConversions/fragmentToBlocks.ts +18 -0
  383. package/src/api/nodeConversions/nodeToBlock.ts +35 -22
  384. package/src/api/nodeUtil.ts +1 -1
  385. package/src/api/parsers/html/__snapshots__/parse-notion-html.json +5 -0
  386. package/src/api/parsers/markdown/parseMarkdown.ts +1 -1
  387. package/src/api/testUtil/cases/defaultSchema.ts +95 -0
  388. package/src/api/testUtil/partialBlockTestUtil.ts +41 -4
  389. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +4 -2
  390. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +369 -0
  391. package/src/blocks/CodeBlockContent/defaultSupportedLanguages.ts +96 -0
  392. package/src/blocks/FileBlockContent/fileBlockHelpers.ts +10 -2
  393. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +19 -31
  394. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +4 -2
  395. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +5 -9
  396. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +6 -10
  397. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  398. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +11 -4
  399. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +5 -9
  400. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +4 -8
  401. package/src/blocks/TableBlockContent/TableBlockContent.ts +83 -8
  402. package/src/blocks/TableBlockContent/TableExtension.ts +10 -1
  403. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +4 -2
  404. package/src/blocks/defaultBlockHelpers.ts +7 -2
  405. package/src/blocks/defaultBlocks.ts +4 -0
  406. package/src/editor/Block.css +71 -3
  407. package/src/editor/BlockNoteEditor.test.ts +2 -2
  408. package/src/editor/BlockNoteEditor.ts +18 -21
  409. package/src/editor/BlockNoteExtensions.ts +2 -3
  410. package/src/editor/BlockNoteTipTapEditor.ts +8 -1
  411. package/src/editor/defaultColors.ts +77 -0
  412. package/src/editor/editor.css +43 -5
  413. package/src/editor/transformPasted.ts +6 -3
  414. package/src/exporter/Exporter.ts +101 -0
  415. package/src/exporter/index.ts +2 -0
  416. package/src/exporter/mapping.ts +75 -0
  417. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +8 -0
  418. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +201 -48
  419. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +1 -1
  420. package/src/extensions/Placeholder/PlaceholderPlugin.ts +5 -0
  421. package/src/extensions/SideMenu/SideMenuPlugin.ts +141 -52
  422. package/src/extensions/SideMenu/dragging.ts +3 -54
  423. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +5 -0
  424. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +2 -1
  425. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +22 -6
  426. package/src/extensions/TableHandles/TableHandlesPlugin.ts +225 -120
  427. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +1 -1
  428. package/src/extensions/getDraggableBlockFromElement.ts +19 -0
  429. package/src/i18n/locales/ar.ts +6 -0
  430. package/src/i18n/locales/de.ts +299 -294
  431. package/src/i18n/locales/en.ts +6 -0
  432. package/src/i18n/locales/es.ts +310 -274
  433. package/src/i18n/locales/fr.ts +6 -0
  434. package/src/i18n/locales/is.ts +6 -0
  435. package/src/i18n/locales/ja.ts +6 -0
  436. package/src/i18n/locales/ko.ts +6 -0
  437. package/src/i18n/locales/nl.ts +6 -0
  438. package/src/i18n/locales/pl.ts +6 -0
  439. package/src/i18n/locales/pt.ts +10 -4
  440. package/src/i18n/locales/ru.ts +6 -0
  441. package/src/i18n/locales/vi.ts +6 -0
  442. package/src/i18n/locales/zh.ts +6 -0
  443. package/src/index.ts +9 -0
  444. package/src/pm-nodes/BlockContainer.ts +1 -1
  445. package/src/pm-nodes/BlockGroup.ts +2 -2
  446. package/src/pm-nodes/README.md +127 -28
  447. package/src/schema/blocks/createSpec.ts +4 -1
  448. package/src/schema/blocks/internal.ts +12 -2
  449. package/src/schema/blocks/types.ts +3 -1
  450. package/src/util/combineByGroup.ts +25 -0
  451. package/types/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.d.ts +22 -2
  452. package/types/src/api/blockManipulation/commands/nestBlock/nestBlock.d.ts +5 -0
  453. package/types/src/api/blockManipulation/setupTestEnv.d.ts +22 -8
  454. package/types/src/api/clipboard/fromClipboard/acceptedMIMETypes.d.ts +1 -1
  455. package/types/src/api/clipboard/fromClipboard/handleVSCodePaste.d.ts +3 -0
  456. package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +2 -3
  457. package/types/src/api/getBlockInfoFromPos.d.ts +55 -5
  458. package/types/src/api/nodeConversions/blockToNode.d.ts +1 -1
  459. package/types/src/api/nodeConversions/nodeToBlock.d.ts +3 -1
  460. package/types/src/api/testUtil/cases/customBlocks.d.ts +22 -8
  461. package/types/src/api/testUtil/cases/customInlineContent.d.ts +22 -8
  462. package/types/src/api/testUtil/cases/customStyles.d.ts +22 -8
  463. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +2 -1
  464. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +1 -0
  465. package/types/src/blocks/CodeBlockContent/CodeBlockContent.d.ts +57 -0
  466. package/types/src/blocks/CodeBlockContent/defaultSupportedLanguages.d.ts +6 -0
  467. package/types/src/blocks/FileBlockContent/fileBlockHelpers.d.ts +1 -0
  468. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +1 -0
  469. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +0 -12
  470. package/types/src/blocks/TableBlockContent/TableExtension.d.ts +3 -0
  471. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +1 -0
  472. package/types/src/blocks/defaultBlocks.d.ts +45 -16
  473. package/types/src/editor/BlockNoteEditor.d.ts +4 -3
  474. package/types/src/editor/BlockNoteTipTapEditor.d.ts +1 -0
  475. package/types/src/editor/defaultColors.d.ts +76 -0
  476. package/types/src/exporter/Exporter.d.ts +43 -0
  477. package/types/src/exporter/index.d.ts +2 -0
  478. package/types/src/exporter/mapping.d.ts +30 -0
  479. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +2 -1
  480. package/types/src/extensions/SideMenu/dragging.d.ts +1 -6
  481. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +9 -5
  482. package/types/src/extensions/getDraggableBlockFromElement.d.ts +5 -0
  483. package/types/src/i18n/locales/de.d.ts +6 -0
  484. package/types/src/i18n/locales/en.d.ts +6 -0
  485. package/types/src/i18n/locales/es.d.ts +6 -0
  486. package/types/src/index.d.ts +6 -0
  487. package/types/src/schema/blocks/createSpec.d.ts +1 -1
  488. package/types/src/schema/blocks/internal.d.ts +2 -2
  489. package/types/src/schema/blocks/types.d.ts +3 -1
  490. package/types/src/util/combineByGroup.d.ts +9 -0
@@ -1,6 +1,7 @@
1
- import { Fragment, Node as PMNode, Slice } from "prosemirror-model";
1
+ import { Fragment, NodeType, Node as PMNode, Slice } from "prosemirror-model";
2
2
  import { EditorState } from "prosemirror-state";
3
3
 
4
+ import { ReplaceStep } from "prosemirror-transform";
4
5
  import { Block, PartialBlock } from "../../../../blocks/defaultBlocks.js";
5
6
  import { BlockNoteEditor } from "../../../../editor/BlockNoteEditor.js";
6
7
  import {
@@ -10,7 +11,10 @@ import {
10
11
  import { InlineContentSchema } from "../../../../schema/inlineContent/types.js";
11
12
  import { StyleSchema } from "../../../../schema/styles/types.js";
12
13
  import { UnreachableCaseError } from "../../../../util/typescript.js";
13
- import { getBlockInfoFromResolvedPos } from "../../../getBlockInfoFromPos.js";
14
+ import {
15
+ BlockInfo,
16
+ getBlockInfoFromResolvedPos,
17
+ } from "../../../getBlockInfoFromPos.js";
14
18
  import {
15
19
  blockToNode,
16
20
  inlineContentToNodes,
@@ -36,128 +40,74 @@ export const updateBlockCommand =
36
40
  state: EditorState;
37
41
  dispatch: ((args?: any) => any) | undefined;
38
42
  }) => {
39
- const { blockContainer, blockContent, blockGroup } =
40
- getBlockInfoFromResolvedPos(state.doc.resolve(posBeforeBlock));
43
+ const blockInfo = getBlockInfoFromResolvedPos(
44
+ state.doc.resolve(posBeforeBlock)
45
+ );
41
46
 
42
47
  if (dispatch) {
43
48
  // Adds blockGroup node with child blocks if necessary.
44
- if (block.children !== undefined) {
45
- const childNodes = [];
46
-
47
- // Creates ProseMirror nodes for each child block, including their descendants.
48
- for (const child of block.children) {
49
- childNodes.push(
50
- blockToNode(child, state.schema, editor.schema.styleSchema)
51
- );
52
- }
53
-
54
- // Checks if a blockGroup node already exists.
55
- if (blockGroup) {
56
- // Replaces all child nodes in the existing blockGroup with the ones created earlier.
57
- state.tr.replace(
58
- blockGroup.beforePos + 1,
59
- blockGroup.afterPos - 1,
60
- new Slice(Fragment.from(childNodes), 0, 0)
61
- );
62
- } else {
63
- // Inserts a new blockGroup containing the child nodes created earlier.
64
- state.tr.insert(
65
- blockContent.afterPos,
66
- state.schema.nodes["blockGroup"].create({}, childNodes)
67
- );
68
- }
69
- }
70
-
71
- const oldType = blockContent.node.type.name;
72
- const newType = block.type || oldType;
73
49
 
74
- // The code below determines the new content of the block.
75
- // or "keep" to keep as-is
76
- let content: PMNode[] | "keep" = "keep";
50
+ const oldNodeType = state.schema.nodes[blockInfo.blockNoteType];
51
+ const newNodeType =
52
+ state.schema.nodes[block.type || blockInfo.blockNoteType];
53
+ const newBnBlockNodeType = newNodeType.isInGroup("bnBlock")
54
+ ? newNodeType
55
+ : state.schema.nodes["blockContainer"];
77
56
 
78
- // Has there been any custom content provided?
79
- if (block.content) {
80
- if (typeof block.content === "string") {
81
- // Adds a single text node with no marks to the content.
82
- content = inlineContentToNodes(
83
- [block.content],
84
- state.schema,
85
- editor.schema.styleSchema
86
- );
87
- } else if (Array.isArray(block.content)) {
88
- // Adds a text node with the provided styles converted into marks to the content,
89
- // for each InlineContent object.
90
- content = inlineContentToNodes(
91
- block.content,
92
- state.schema,
93
- editor.schema.styleSchema
94
- );
95
- } else if (block.content.type === "tableContent") {
96
- content = tableContentToNodes(
97
- block.content,
98
- state.schema,
99
- editor.schema.styleSchema
100
- );
101
- } else {
102
- throw new UnreachableCaseError(block.content.type);
103
- }
57
+ if (blockInfo.isBlockContainer && newNodeType.isInGroup("blockContent")) {
58
+ updateChildren(block, state, editor, blockInfo);
59
+ // The code below determines the new content of the block.
60
+ // or "keep" to keep as-is
61
+ updateBlockContentNode(
62
+ block,
63
+ state,
64
+ editor,
65
+ oldNodeType,
66
+ newNodeType,
67
+ blockInfo
68
+ );
69
+ } else if (
70
+ !blockInfo.isBlockContainer &&
71
+ newNodeType.isInGroup("bnBlock")
72
+ ) {
73
+ updateChildren(block, state, editor, blockInfo);
74
+ // old node was a bnBlock type (like column or columnList) and new block as well
75
+ // No op, we just update the bnBlock below (at end of function) and have already updated the children
104
76
  } else {
105
- // no custom content has been provided, use existing content IF possible
106
-
107
- // Since some block types contain inline content and others don't,
108
- // we either need to call setNodeMarkup to just update type &
109
- // attributes, or replaceWith to replace the whole blockContent.
110
- const oldContentType = state.schema.nodes[oldType].spec.content;
111
- const newContentType = state.schema.nodes[newType].spec.content;
112
-
113
- if (oldContentType === "") {
114
- // keep old content, because it's empty anyway and should be compatible with
115
- // any newContentType
116
- } else if (newContentType !== oldContentType) {
117
- // the content type changed, replace the previous content
118
- content = [];
119
- } else {
120
- // keep old content, because the content type is the same and should be compatible
121
- }
122
- }
77
+ // switching from blockContainer to non-blockContainer or v.v.
78
+ // currently breaking for column slash menu items converting empty block
79
+ // to column.
123
80
 
124
- // Now, changes the blockContent node type and adds the provided props
125
- // as attributes. Also preserves all existing attributes that are
126
- // compatible with the new type.
127
- //
128
- // Use either setNodeMarkup or replaceWith depending on whether the
129
- // content is being replaced or not.
130
- if (content === "keep") {
131
- // use setNodeMarkup to only update the type and attributes
132
- state.tr.setNodeMarkup(
133
- blockContent.beforePos,
134
- block.type === undefined ? undefined : state.schema.nodes[block.type],
135
- {
136
- ...blockContent.node.attrs,
137
- ...block.props,
138
- }
81
+ // currently, we calculate the new node and replace the entire node with the desired new node.
82
+ // for this, we do a nodeToBlock on the existing block to get the children.
83
+ // it would be cleaner to use a ReplaceAroundStep, but this is a bit simpler and it's quite an edge case
84
+ const existingBlock = nodeToBlock(
85
+ blockInfo.bnBlock.node,
86
+ editor.schema.blockSchema,
87
+ editor.schema.inlineContentSchema,
88
+ editor.schema.styleSchema,
89
+ editor.blockCache
139
90
  );
140
- } else {
141
- // use replaceWith to replace the content and the block itself
142
- // also reset the selection since replacing the block content
143
- // sets it to the next block.
144
91
  state.tr.replaceWith(
145
- blockContent.beforePos,
146
- blockContent.afterPos,
147
- state.schema.nodes[newType].create(
92
+ blockInfo.bnBlock.beforePos,
93
+ blockInfo.bnBlock.afterPos,
94
+ blockToNode(
148
95
  {
149
- ...blockContent.node.attrs,
150
- ...block.props,
96
+ children: existingBlock.children, // if no children are passed in, use existing children
97
+ ...block,
151
98
  },
152
- content
99
+ state.schema,
100
+ editor.schema.styleSchema
153
101
  )
154
102
  );
103
+
104
+ return true;
155
105
  }
156
106
 
157
107
  // Adds all provided props as attributes to the parent blockContainer node too, and also preserves existing
158
108
  // attributes.
159
- state.tr.setNodeMarkup(blockContainer.beforePos, undefined, {
160
- ...blockContainer.node.attrs,
109
+ state.tr.setNodeMarkup(blockInfo.bnBlock.beforePos, newBnBlockNodeType, {
110
+ ...blockInfo.bnBlock.node.attrs,
161
111
  ...block.props,
162
112
  });
163
113
  }
@@ -165,6 +115,141 @@ export const updateBlockCommand =
165
115
  return true;
166
116
  };
167
117
 
118
+ function updateBlockContentNode<
119
+ BSchema extends BlockSchema,
120
+ I extends InlineContentSchema,
121
+ S extends StyleSchema
122
+ >(
123
+ block: PartialBlock<BSchema, I, S>,
124
+ state: EditorState,
125
+ editor: BlockNoteEditor<BSchema, I, S>,
126
+ oldNodeType: NodeType,
127
+ newNodeType: NodeType,
128
+ blockInfo: {
129
+ childContainer?:
130
+ | { node: PMNode; beforePos: number; afterPos: number }
131
+ | undefined;
132
+ blockContent: { node: PMNode; beforePos: number; afterPos: number };
133
+ }
134
+ ) {
135
+ let content: PMNode[] | "keep" = "keep";
136
+
137
+ // Has there been any custom content provided?
138
+ if (block.content) {
139
+ if (typeof block.content === "string") {
140
+ // Adds a single text node with no marks to the content.
141
+ content = inlineContentToNodes(
142
+ [block.content],
143
+ state.schema,
144
+ editor.schema.styleSchema
145
+ );
146
+ } else if (Array.isArray(block.content)) {
147
+ // Adds a text node with the provided styles converted into marks to the content,
148
+ // for each InlineContent object.
149
+ content = inlineContentToNodes(
150
+ block.content,
151
+ state.schema,
152
+ editor.schema.styleSchema
153
+ );
154
+ } else if (block.content.type === "tableContent") {
155
+ content = tableContentToNodes(
156
+ block.content,
157
+ state.schema,
158
+ editor.schema.styleSchema
159
+ );
160
+ } else {
161
+ throw new UnreachableCaseError(block.content.type);
162
+ }
163
+ } else {
164
+ // no custom content has been provided, use existing content IF possible
165
+ // Since some block types contain inline content and others don't,
166
+ // we either need to call setNodeMarkup to just update type &
167
+ // attributes, or replaceWith to replace the whole blockContent.
168
+ if (oldNodeType.spec.content === "") {
169
+ // keep old content, because it's empty anyway and should be compatible with
170
+ // any newContentType
171
+ } else if (newNodeType.spec.content !== oldNodeType.spec.content) {
172
+ // the content type changed, replace the previous content
173
+ content = [];
174
+ } else {
175
+ // keep old content, because the content type is the same and should be compatible
176
+ }
177
+ }
178
+
179
+ // Now, changes the blockContent node type and adds the provided props
180
+ // as attributes. Also preserves all existing attributes that are
181
+ // compatible with the new type.
182
+ //
183
+ // Use either setNodeMarkup or replaceWith depending on whether the
184
+ // content is being replaced or not.
185
+ if (content === "keep") {
186
+ // use setNodeMarkup to only update the type and attributes
187
+ state.tr.setNodeMarkup(
188
+ blockInfo.blockContent.beforePos,
189
+ block.type === undefined ? undefined : state.schema.nodes[block.type],
190
+ {
191
+ ...blockInfo.blockContent.node.attrs,
192
+ ...block.props,
193
+ }
194
+ );
195
+ } else {
196
+ // use replaceWith to replace the content and the block itself
197
+ // also reset the selection since replacing the block content
198
+ // sets it to the next block.
199
+ state.tr.replaceWith(
200
+ blockInfo.blockContent.beforePos,
201
+ blockInfo.blockContent.afterPos,
202
+ newNodeType.createChecked(
203
+ {
204
+ ...blockInfo.blockContent.node.attrs,
205
+ ...block.props,
206
+ },
207
+ content
208
+ )
209
+ );
210
+ }
211
+ }
212
+
213
+ function updateChildren<
214
+ BSchema extends BlockSchema,
215
+ I extends InlineContentSchema,
216
+ S extends StyleSchema
217
+ >(
218
+ block: PartialBlock<BSchema, I, S>,
219
+ state: EditorState,
220
+ editor: BlockNoteEditor<BSchema, I, S>,
221
+ blockInfo: BlockInfo
222
+ ) {
223
+ if (block.children !== undefined) {
224
+ const childNodes = block.children.map((child) => {
225
+ return blockToNode(child, state.schema, editor.schema.styleSchema);
226
+ });
227
+
228
+ // Checks if a blockGroup node already exists.
229
+ if (blockInfo.childContainer) {
230
+ // Replaces all child nodes in the existing blockGroup with the ones created earlier.
231
+
232
+ // use a replacestep to avoid the fitting algorithm
233
+ state.tr.step(
234
+ new ReplaceStep(
235
+ blockInfo.childContainer.beforePos + 1,
236
+ blockInfo.childContainer.afterPos - 1,
237
+ new Slice(Fragment.from(childNodes), 0, 0)
238
+ )
239
+ );
240
+ } else {
241
+ if (!blockInfo.isBlockContainer) {
242
+ throw new Error("impossible");
243
+ }
244
+ // Inserts a new blockGroup containing the child nodes created earlier.
245
+ state.tr.insert(
246
+ blockInfo.blockContent.afterPos,
247
+ state.schema.nodes["blockGroup"].createChecked({}, childNodes)
248
+ );
249
+ }
250
+ }
251
+ }
252
+
168
253
  export function updateBlock<
169
254
  BSchema extends BlockSchema,
170
255
  I extends InlineContentSchema,
@@ -21,30 +21,31 @@ export function getTextCursorPosition<
21
21
  I extends InlineContentSchema,
22
22
  S extends StyleSchema
23
23
  >(editor: BlockNoteEditor<BSchema, I, S>): TextCursorPosition<BSchema, I, S> {
24
- const { blockContainer } = getBlockInfoFromSelection(
25
- editor._tiptapEditor.state
26
- );
24
+ const { bnBlock } = getBlockInfoFromSelection(editor._tiptapEditor.state);
27
25
 
28
- const resolvedPos = editor._tiptapEditor.state.doc.resolve(
29
- blockContainer.beforePos
30
- );
26
+ const resolvedPos = editor._tiptapEditor.state.doc.resolve(bnBlock.beforePos);
31
27
  // Gets previous blockContainer node at the same nesting level, if the current node isn't the first child.
32
28
  const prevNode = resolvedPos.nodeBefore;
33
29
 
34
30
  // Gets next blockContainer node at the same nesting level, if the current node isn't the last child.
35
31
  const nextNode = editor._tiptapEditor.state.doc.resolve(
36
- blockContainer.afterPos
32
+ bnBlock.afterPos
37
33
  ).nodeAfter;
38
34
 
39
35
  // Gets parent blockContainer node, if the current node is nested.
40
36
  let parentNode: Node | undefined = undefined;
41
37
  if (resolvedPos.depth > 1) {
42
- parentNode = resolvedPos.node(resolvedPos.depth - 1);
38
+ // for nodes nested in bnBlocks
39
+ parentNode = resolvedPos.node();
40
+ if (!parentNode.type.isInGroup("bnBlock")) {
41
+ // for blockGroups, we need to go one level up
42
+ parentNode = resolvedPos.node(resolvedPos.depth - 1);
43
+ }
43
44
  }
44
45
 
45
46
  return {
46
47
  block: nodeToBlock(
47
- blockContainer.node,
48
+ bnBlock.node,
48
49
  editor.schema.blockSchema,
49
50
  editor.schema.inlineContentSchema,
50
51
  editor.schema.styleSchema,
@@ -95,36 +96,50 @@ export function setTextCursorPosition<
95
96
  const id = typeof targetBlock === "string" ? targetBlock : targetBlock.id;
96
97
 
97
98
  const posInfo = getNodeById(id, editor._tiptapEditor.state.doc);
98
- const { blockContent } = getBlockInfo(posInfo);
99
+ const info = getBlockInfo(posInfo);
99
100
 
100
101
  const contentType: "none" | "inline" | "table" =
101
- editor.schema.blockSchema[blockContent.node.type.name]!.content;
102
-
103
- if (contentType === "none") {
104
- editor._tiptapEditor.commands.setNodeSelection(blockContent.beforePos);
105
- return;
106
- }
102
+ editor.schema.blockSchema[info.blockNoteType]!.content;
107
103
 
108
- if (contentType === "inline") {
109
- if (placement === "start") {
110
- editor._tiptapEditor.commands.setTextSelection(
111
- blockContent.beforePos + 1
112
- );
113
- } else {
114
- editor._tiptapEditor.commands.setTextSelection(blockContent.afterPos - 1);
104
+ if (info.isBlockContainer) {
105
+ const blockContent = info.blockContent;
106
+ if (contentType === "none") {
107
+ editor._tiptapEditor.commands.setNodeSelection(blockContent.beforePos);
108
+ return;
115
109
  }
116
- } else if (contentType === "table") {
117
- if (placement === "start") {
118
- // Need to offset the position as we have to get through the `tableRow`
119
- // and `tableCell` nodes to get to the `tableParagraph` node we want to
120
- // set the selection in.
121
- editor._tiptapEditor.commands.setTextSelection(
122
- blockContent.beforePos + 4
123
- );
110
+
111
+ if (contentType === "inline") {
112
+ if (placement === "start") {
113
+ editor._tiptapEditor.commands.setTextSelection(
114
+ blockContent.beforePos + 1
115
+ );
116
+ } else {
117
+ editor._tiptapEditor.commands.setTextSelection(
118
+ blockContent.afterPos - 1
119
+ );
120
+ }
121
+ } else if (contentType === "table") {
122
+ if (placement === "start") {
123
+ // Need to offset the position as we have to get through the `tableRow`
124
+ // and `tableCell` nodes to get to the `tableParagraph` node we want to
125
+ // set the selection in.
126
+ editor._tiptapEditor.commands.setTextSelection(
127
+ blockContent.beforePos + 4
128
+ );
129
+ } else {
130
+ editor._tiptapEditor.commands.setTextSelection(
131
+ blockContent.afterPos - 4
132
+ );
133
+ }
124
134
  } else {
125
- editor._tiptapEditor.commands.setTextSelection(blockContent.afterPos - 4);
135
+ throw new UnreachableCaseError(contentType);
126
136
  }
127
137
  } else {
128
- throw new UnreachableCaseError(contentType);
138
+ const child =
139
+ placement === "start"
140
+ ? info.childContainer.node.firstChild!
141
+ : info.childContainer.node.lastChild!;
142
+
143
+ setTextCursorPosition(editor, child.attrs.id, placement);
129
144
  }
130
145
  }
@@ -173,7 +173,7 @@ describe("Test ProseMirror selection clipboard HTML", () => {
173
173
  )
174
174
  );
175
175
 
176
- const { clipboardHTML, externalHTML } = await selectedFragmentToHTML(
176
+ const { clipboardHTML, externalHTML } = selectedFragmentToHTML(
177
177
  editor._tiptapEditor.view,
178
178
  editor
179
179
  );
@@ -1,4 +1,5 @@
1
1
  export const acceptedMIMETypes = [
2
+ "vscode-editor-data",
2
3
  "blocknote/html",
3
4
  "Files",
4
5
  "text/html",
@@ -144,7 +144,7 @@ export async function handleFileInsertion<
144
144
 
145
145
  insertedBlockId = editor.insertBlocks(
146
146
  [fileBlock],
147
- blockInfo.blockContainer.node.attrs.id,
147
+ blockInfo.bnBlock.node.attrs.id,
148
148
  "after"
149
149
  )[0].id;
150
150
  } else {
@@ -0,0 +1,49 @@
1
+ import { BlockNoteEditor } from "../../../editor/BlockNoteEditor.js";
2
+ import {
3
+ BlockSchema,
4
+ InlineContentSchema,
5
+ StyleSchema,
6
+ } from "../../../schema/index.js";
7
+
8
+ export async function handleVSCodePaste<
9
+ BSchema extends BlockSchema,
10
+ I extends InlineContentSchema,
11
+ S extends StyleSchema
12
+ >(event: ClipboardEvent, editor: BlockNoteEditor<BSchema, I, S>) {
13
+ const view = editor.prosemirrorView;
14
+ const { schema } = view.state;
15
+
16
+ if (!event.clipboardData) {
17
+ return false;
18
+ }
19
+
20
+ const text = event.clipboardData!.getData("text/plain");
21
+ const vscode = event.clipboardData!.getData("vscode-editor-data");
22
+ const vscodeData = vscode ? JSON.parse(vscode) : undefined;
23
+ const language = vscodeData?.mode;
24
+
25
+ if (!text) {
26
+ return false;
27
+ }
28
+
29
+ if (!schema.nodes.codeBlock) {
30
+ view.pasteText(text);
31
+
32
+ return true;
33
+ }
34
+
35
+ if (!language) {
36
+ return false;
37
+ }
38
+
39
+ // strip carriage return chars from text pasted as code
40
+ // see: https://github.com/ProseMirror/prosemirror-view/commit/a50a6bcceb4ce52ac8fcc6162488d8875613aacd
41
+ editor._tiptapEditor.view.pasteHTML(
42
+ `<pre><code class="language-${language}">${text.replace(
43
+ /\r\n?/g,
44
+ "\n"
45
+ )}</code></pre>`
46
+ );
47
+
48
+ return true;
49
+ }
@@ -10,6 +10,7 @@ import {
10
10
  import { nestedListsToBlockNoteStructure } from "../../parsers/html/util/nestedLists.js";
11
11
  import { acceptedMIMETypes } from "./acceptedMIMETypes.js";
12
12
  import { handleFileInsertion } from "./handleFileInsertion.js";
13
+ import { handleVSCodePaste } from "./handleVSCodePaste.js";
13
14
 
14
15
  export const createPasteFromClipboardExtension = <
15
16
  BSchema extends BlockSchema,
@@ -43,6 +44,11 @@ export const createPasteFromClipboardExtension = <
43
44
  return true;
44
45
  }
45
46
 
47
+ if (format === "vscode-editor-data") {
48
+ handleVSCodePaste(event, editor);
49
+ return true;
50
+ }
51
+
46
52
  if (format === "Files") {
47
53
  handleFileInsertion(event, editor);
48
54
  return true;
@@ -49,7 +49,7 @@ function fragmentToExternalHTML<
49
49
  isWithinBlockContent =
50
50
  children.find(
51
51
  (child) =>
52
- child.type.name === "blockContainer" ||
52
+ child.type.isInGroup("bnBlock") ||
53
53
  child.type.name === "blockGroup" ||
54
54
  child.type.spec.group === "blockContent"
55
55
  ) === undefined;
@@ -0,0 +1 @@
1
+ <pre><code class="bn-inline-content language-javascript">console.log('Hello, world!');</code></pre>
@@ -0,0 +1 @@
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="codeBlock"><pre><code class="bn-inline-content language-javascript">console.log('Hello, world!');</code></pre></div></div></div></div>
@@ -0,0 +1 @@
1
+ <pre><code class="bn-inline-content language-javascript"></code></pre>
@@ -0,0 +1 @@
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="codeBlock"><pre><code class="bn-inline-content language-javascript"></code></pre></div></div></div></div>
@@ -0,0 +1 @@
1
+ <pre><code class="bn-inline-content language-python">print('Hello, world!')</code></pre>
@@ -0,0 +1 @@
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="codeBlock"><pre><code class="bn-inline-content language-python">print('Hello, world!')</code></pre></div></div></div></div>
@@ -1 +1 @@
1
- <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-name="example" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="example" draggable="false" width="0"></div><p class="bn-file-caption">Caption</p></div></div></div></div></div></div>
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-name="example" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="example" draggable="false" width="0"></div><p class="bn-file-caption" style="width: 256px;">Caption</p></div></div></div></div></div></div>
@@ -1 +1 @@
1
- <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="Caption" draggable="false" width="0"></div><p class="bn-file-caption">Caption</p></div></div></div><div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="2"><div class="bn-block" data-node-type="blockContainer" data-id="2"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="Caption" draggable="false" width="0"></div><p class="bn-file-caption">Caption</p></div></div></div></div></div></div></div></div></div>
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="Caption" draggable="false" width="0"></div><p class="bn-file-caption" style="width: 256px;">Caption</p></div></div></div><div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="2"><div class="bn-block" data-node-type="blockContainer" data-id="2"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="Caption" draggable="false" width="0"></div><p class="bn-file-caption" style="width: 256px;">Caption</p></div></div></div></div></div></div></div></div></div>
@@ -1 +1 @@
1
- <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="Caption" draggable="false" width="0"></div><p class="bn-file-caption">Caption</p></div></div></div></div></div></div>
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-preview-width="256" data-file-block=""><div class="bn-file-block-content-wrapper"><div class="bn-file-and-caption-wrapper"><div class="bn-visual-media-wrapper"><img class="bn-visual-media" alt="Caption" draggable="false" width="0"></div><p class="bn-file-caption" style="width: 256px;">Caption</p></div></div></div></div></div></div>
@@ -1 +1 @@
1
- <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-name="example" data-url="exampleURL" data-caption="Caption" data-show-preview="false" data-preview-width="256" data-file-block=""><div class="bn-file-and-caption-wrapper"><div class="bn-file-default-preview"><div class="bn-file-default-preview-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z"></path></svg></div><p class="bn-file-default-preview-name">example</p></div><p class="bn-file-caption">Caption</p></div></div></div></div></div>
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-name="example" data-url="exampleURL" data-caption="Caption" data-show-preview="false" data-preview-width="256" data-file-block=""><div class="bn-file-and-caption-wrapper"><div class="bn-file-default-preview"><div class="bn-file-default-preview-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z"></path></svg></div><p class="bn-file-default-preview-name">example</p></div><p class="bn-file-caption" style="width: 256px;">Caption</p></div></div></div></div></div>
@@ -1 +1 @@
1
- <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="bulletListItem"><p class="bn-inline-content">Bullet List Item 1</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="2"><div class="bn-block" data-node-type="blockContainer" data-id="2"><div class="bn-block-content" data-content-type="bulletListItem"><p class="bn-inline-content">Bullet List Item 2</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="3"><div class="bn-block" data-node-type="blockContainer" data-id="3"><div class="bn-block-content" data-content-type="numberedListItem" data-index="null"><p class="bn-inline-content">Numbered List Item 1</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="4"><div class="bn-block" data-node-type="blockContainer" data-id="4"><div class="bn-block-content" data-content-type="numberedListItem" data-index="null"><p class="bn-inline-content">Numbered List Item 2</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="5"><div class="bn-block" data-node-type="blockContainer" data-id="5"><div class="bn-block-content" data-content-type="checkListItem"><input type="checkbox"><p class="bn-inline-content">Check List Item 1</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="6"><div class="bn-block" data-node-type="blockContainer" data-id="6"><div class="bn-block-content" data-content-type="checkListItem" data-checked="true"><input type="checkbox" checked=""><p class="bn-inline-content">Check List Item 2</p></div></div></div></div>
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="bulletListItem"><p class="bn-inline-content">Bullet List Item 1</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="2"><div class="bn-block" data-node-type="blockContainer" data-id="2"><div class="bn-block-content" data-content-type="bulletListItem"><p class="bn-inline-content">Bullet List Item 2</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="3"><div class="bn-block" data-node-type="blockContainer" data-id="3"><div class="bn-block-content" data-content-type="numberedListItem" data-index="1"><p class="bn-inline-content">Numbered List Item 1</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="4"><div class="bn-block" data-node-type="blockContainer" data-id="4"><div class="bn-block-content" data-content-type="numberedListItem" data-index="2"><p class="bn-inline-content">Numbered List Item 2</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="5"><div class="bn-block" data-node-type="blockContainer" data-id="5"><div class="bn-block-content" data-content-type="checkListItem"><input type="checkbox"><p class="bn-inline-content">Check List Item 1</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="6"><div class="bn-block" data-node-type="blockContainer" data-id="6"><div class="bn-block-content" data-content-type="checkListItem" data-checked="true"><input type="checkbox" checked=""><p class="bn-inline-content">Check List Item 2</p></div></div></div></div>