@blocknote/core 0.30.0 → 0.31.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 (245) hide show
  1. package/dist/blocknote.cjs +9 -9
  2. package/dist/blocknote.cjs.map +1 -1
  3. package/dist/blocknote.js +2771 -2245
  4. package/dist/blocknote.js.map +1 -1
  5. package/dist/comments.cjs.map +1 -1
  6. package/dist/comments.js.map +1 -1
  7. package/dist/{en-D4taoCs4.cjs → en-BXVKCwYt.cjs} +2 -2
  8. package/dist/en-BXVKCwYt.cjs.map +1 -0
  9. package/dist/{en-B7ycW7c8.js → en-qGo6sk9V.js} +2 -3
  10. package/dist/en-qGo6sk9V.js.map +1 -0
  11. package/dist/locales.cjs +1 -1
  12. package/dist/locales.cjs.map +1 -1
  13. package/dist/locales.js +20 -39
  14. package/dist/locales.js.map +1 -1
  15. package/dist/style.css +1 -1
  16. package/dist/webpack-stats.json +1 -1
  17. package/package.json +8 -7
  18. package/src/api/README.md +1 -1
  19. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.ts +19 -14
  20. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +7 -8
  21. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +3 -3
  22. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +12 -12
  23. package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.ts +14 -14
  24. package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts +16 -16
  25. package/src/api/blockManipulation/commands/nestBlock/nestBlock.ts +8 -8
  26. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.ts +12 -12
  27. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +8 -8
  28. package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +10 -10
  29. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +2 -2
  30. package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +2816 -0
  31. package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +200 -42
  32. package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +104 -34
  33. package/src/api/blockManipulation/getBlock/getBlock.ts +9 -9
  34. package/src/api/blockManipulation/insertContentAt.ts +1 -1
  35. package/src/api/blockManipulation/selections/selection.ts +59 -12
  36. package/src/api/blockManipulation/selections/{textCursorPosition/textCursorPosition.ts → textCursorPosition.ts} +13 -13
  37. package/src/api/blockManipulation/tables/tables.test.ts +106 -106
  38. package/src/api/blockManipulation/tables/tables.ts +35 -35
  39. package/src/api/clipboard/fromClipboard/fileDropExtension.ts +2 -2
  40. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +9 -9
  41. package/src/api/clipboard/fromClipboard/handleVSCodePaste.ts +3 -3
  42. package/src/api/clipboard/fromClipboard/pasteExtension.ts +3 -3
  43. package/src/api/clipboard/toClipboard/copyExtension.ts +22 -22
  44. package/src/api/exporters/html/externalHTMLExporter.ts +6 -6
  45. package/src/api/exporters/html/internalHTMLSerializer.ts +3 -3
  46. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +16 -16
  47. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +14 -14
  48. package/src/api/exporters/markdown/markdownExporter.ts +3 -3
  49. package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +3 -3
  50. package/src/api/getBlockInfoFromPos.ts +6 -6
  51. package/src/api/nodeConversions/blockToNode.ts +31 -28
  52. package/src/api/nodeConversions/fragmentToBlocks.ts +1 -1
  53. package/src/api/nodeConversions/nodeToBlock.ts +240 -41
  54. package/src/api/nodeUtil.test.ts +16 -16
  55. package/src/api/nodeUtil.ts +10 -10
  56. package/src/api/parsers/html/parseHTML.ts +1 -1
  57. package/src/api/parsers/html/util/nestedLists.ts +2 -2
  58. package/src/api/parsers/markdown/parseMarkdown.ts +1 -1
  59. package/src/api/pmUtil.ts +7 -7
  60. package/src/api/positionMapping.test.ts +3 -3
  61. package/src/api/positionMapping.ts +5 -5
  62. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +4 -4
  63. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +18 -18
  64. package/src/blocks/FileBlockContent/FileBlockContent.ts +2 -2
  65. package/src/blocks/FileBlockContent/helpers/parse/parseFigureElement.ts +2 -2
  66. package/src/blocks/FileBlockContent/helpers/render/createAddFileButton.ts +6 -6
  67. package/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.ts +2 -2
  68. package/src/blocks/FileBlockContent/helpers/render/createFileNameWithIcon.ts +1 -1
  69. package/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.ts +7 -7
  70. package/src/blocks/FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.ts +1 -1
  71. package/src/blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.ts +1 -1
  72. package/src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +2 -2
  73. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +6 -6
  74. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +4 -4
  75. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +4 -4
  76. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +10 -10
  77. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  78. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
  79. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +4 -4
  80. package/src/blocks/ListItemBlockContent/getListItemContent.ts +5 -5
  81. package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +1 -1
  82. package/src/blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.ts +3 -3
  83. package/src/blocks/PageBreakBlockContent/schema.ts +2 -2
  84. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +3 -3
  85. package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +4 -4
  86. package/src/blocks/README.md +1 -1
  87. package/src/blocks/TableBlockContent/TableBlockContent.ts +37 -7
  88. package/src/blocks/TableBlockContent/TableExtension.ts +3 -3
  89. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +4 -4
  90. package/src/blocks/defaultBlockHelpers.ts +8 -8
  91. package/src/blocks/defaultBlockTypeGuards.ts +16 -16
  92. package/src/blocks/defaultBlocks.ts +3 -3
  93. package/src/comments/threadstore/DefaultThreadStoreAuth.ts +3 -3
  94. package/src/comments/threadstore/ThreadStore.ts +1 -1
  95. package/src/comments/threadstore/TipTapThreadStore.ts +10 -10
  96. package/src/comments/threadstore/yjs/RESTYjsThreadStore.ts +4 -4
  97. package/src/comments/threadstore/yjs/YjsThreadStore.test.ts +2 -2
  98. package/src/comments/threadstore/yjs/YjsThreadStore.ts +14 -14
  99. package/src/comments/threadstore/yjs/YjsThreadStoreBase.ts +1 -1
  100. package/src/comments/threadstore/yjs/yjsHelpers.ts +6 -6
  101. package/src/editor/Block.css +35 -1
  102. package/src/editor/BlockNoteEditor.test.ts +10 -3
  103. package/src/editor/BlockNoteEditor.ts +95 -38
  104. package/src/editor/BlockNoteExtension.ts +26 -0
  105. package/src/editor/BlockNoteExtensions.ts +38 -22
  106. package/src/editor/BlockNoteSchema.ts +4 -4
  107. package/src/editor/BlockNoteTipTapEditor.ts +33 -12
  108. package/src/editor/README.md +1 -1
  109. package/src/editor/cursorPositionTypes.ts +1 -1
  110. package/src/editor/editor.css +15 -3
  111. package/src/editor/selectionTypes.ts +1 -1
  112. package/src/editor/transformPasted.ts +2 -2
  113. package/src/exporter/Exporter.ts +5 -5
  114. package/src/exporter/mapping.ts +7 -7
  115. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +1 -1
  116. package/src/extensions/Collaboration/CursorPlugin.ts +15 -9
  117. package/src/extensions/Collaboration/ForkYDocPlugin.test.ts +166 -0
  118. package/src/extensions/Collaboration/ForkYDocPlugin.ts +174 -0
  119. package/src/extensions/Collaboration/SyncPlugin.ts +7 -4
  120. package/src/extensions/Collaboration/UndoPlugin.ts +7 -4
  121. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +30 -0
  122. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +30 -0
  123. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -0
  124. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -0
  125. package/src/extensions/Comments/CommentsPlugin.ts +80 -75
  126. package/src/extensions/Comments/userstore/UserStore.ts +2 -2
  127. package/src/extensions/FilePanel/FilePanelPlugin.ts +56 -55
  128. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +60 -30
  129. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +26 -26
  130. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +33 -32
  131. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +45 -42
  132. package/src/extensions/Placeholder/PlaceholderPlugin.ts +113 -110
  133. package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +179 -170
  134. package/src/extensions/README.md +1 -1
  135. package/src/extensions/ShowSelection/ShowSelectionPlugin.ts +22 -19
  136. package/src/extensions/SideMenu/MultipleNodeSelection.ts +1 -1
  137. package/src/extensions/SideMenu/SideMenuPlugin.ts +49 -48
  138. package/src/extensions/SideMenu/dragging.ts +8 -8
  139. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +176 -176
  140. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +2 -2
  141. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +16 -16
  142. package/src/extensions/Suggestions/SuggestionMarks.ts +175 -0
  143. package/src/extensions/TableHandles/TableHandlesPlugin.ts +199 -195
  144. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +1 -1
  145. package/src/extensions/UniqueID/UniqueID.ts +6 -6
  146. package/src/extensions/getDraggableBlockFromElement.ts +1 -1
  147. package/src/fonts/inter.css +18 -9
  148. package/src/i18n/locales/ar.ts +0 -1
  149. package/src/i18n/locales/de.ts +0 -1
  150. package/src/i18n/locales/en.ts +0 -1
  151. package/src/i18n/locales/es.ts +0 -1
  152. package/src/i18n/locales/fr.ts +0 -1
  153. package/src/i18n/locales/hr.ts +0 -1
  154. package/src/i18n/locales/is.ts +0 -1
  155. package/src/i18n/locales/it.ts +0 -1
  156. package/src/i18n/locales/ja.ts +0 -1
  157. package/src/i18n/locales/ko.ts +0 -1
  158. package/src/i18n/locales/nl.ts +0 -1
  159. package/src/i18n/locales/no.ts +0 -1
  160. package/src/i18n/locales/pl.ts +0 -1
  161. package/src/i18n/locales/pt.ts +0 -1
  162. package/src/i18n/locales/ru.ts +0 -1
  163. package/src/i18n/locales/sk.ts +0 -1
  164. package/src/i18n/locales/uk.ts +0 -1
  165. package/src/i18n/locales/vi.ts +0 -1
  166. package/src/i18n/locales/zh-tw.ts +0 -1
  167. package/src/i18n/locales/zh.ts +0 -1
  168. package/src/index.ts +18 -8
  169. package/src/locales.ts +1 -1
  170. package/src/pm-nodes/BlockContainer.ts +1 -1
  171. package/src/pm-nodes/BlockGroup.ts +2 -2
  172. package/src/pm-nodes/Doc.ts +5 -4
  173. package/src/schema/README.md +1 -1
  174. package/src/schema/blocks/createSpec.ts +14 -14
  175. package/src/schema/blocks/internal.ts +17 -17
  176. package/src/schema/blocks/types.ts +25 -25
  177. package/src/schema/inlineContent/createSpec.ts +16 -20
  178. package/src/schema/inlineContent/internal.ts +9 -9
  179. package/src/schema/inlineContent/types.ts +26 -26
  180. package/src/schema/propTypes.ts +8 -8
  181. package/src/schema/styles/createSpec.ts +2 -2
  182. package/src/schema/styles/internal.ts +7 -7
  183. package/src/schema/styles/types.ts +2 -2
  184. package/src/util/EventEmitter.ts +4 -4
  185. package/src/util/README.md +1 -1
  186. package/src/util/combineByGroup.ts +1 -1
  187. package/src/util/table.ts +33 -30
  188. package/types/src/api/blockManipulation/commands/insertBlocks/insertBlocks.d.ts +1 -1
  189. package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.d.ts +4 -0
  190. package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.d.ts +1 -0
  191. package/types/src/api/blockManipulation/commands/updateBlock/updateBlock.d.ts +3 -1
  192. package/types/src/api/blockManipulation/selections/selection.d.ts +10 -0
  193. package/types/src/api/blockManipulation/selections/textCursorPosition.d.ts +5 -0
  194. package/types/src/api/blockManipulation/transactions.test.d.ts +0 -0
  195. package/types/src/api/clipboard/clipboardExternal.test.d.ts +1 -0
  196. package/types/src/api/clipboard/clipboardInternal.test.d.ts +1 -0
  197. package/types/src/api/clipboard/testUtil.d.ts +541 -0
  198. package/types/src/api/exporters/html/htmlConversion.test.d.ts +1 -0
  199. package/types/src/api/exporters/markdown/markdownExporter.test.d.ts +1 -0
  200. package/types/src/api/nodeConversions/nodeConversions.test.d.ts +1 -0
  201. package/types/src/api/nodeConversions/nodeToBlock.d.ts +39 -2
  202. package/types/src/api/parsers/html/parseHTML.test.d.ts +1 -0
  203. package/types/src/api/parsers/markdown/parseMarkdown.test.d.ts +1 -0
  204. package/types/src/api/pmUtil.d.ts +3 -3
  205. package/types/src/api/testUtil/cases/customBlocks.d.ts +670 -0
  206. package/types/src/api/testUtil/cases/customInlineContent.d.ts +558 -0
  207. package/types/src/api/testUtil/cases/customStyles.d.ts +552 -0
  208. package/types/src/api/testUtil/cases/defaultSchema.d.ts +4 -0
  209. package/types/src/api/testUtil/index.d.ts +14 -0
  210. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +9 -0
  211. package/types/src/api/testUtil/paste.d.ts +2 -0
  212. package/types/src/blocks/CodeBlockContent/defaultSupportedLanguages.d.ts +6 -0
  213. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +9 -1
  214. package/types/src/editor/BlockNoteEditor.d.ts +58 -10
  215. package/types/src/editor/BlockNoteExtension.d.ts +9 -0
  216. package/types/src/editor/BlockNoteExtensions.d.ts +2 -2
  217. package/types/src/editor/BlockNoteTipTapEditor.d.ts +2 -2
  218. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +3 -3
  219. package/types/src/extensions/Collaboration/ForkYDocPlugin.d.ts +41 -0
  220. package/types/src/extensions/Collaboration/ForkYDocPlugin.test.d.ts +1 -0
  221. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +3 -3
  222. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +3 -3
  223. package/types/src/extensions/Collaboration/createCollaborationExtensions.d.ts +17 -0
  224. package/types/src/extensions/Comments/CommentsPlugin.d.ts +2 -4
  225. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +3 -4
  226. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +5 -5
  227. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +3 -4
  228. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +2 -3
  229. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +2 -3
  230. package/types/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.d.ts +2 -3
  231. package/types/src/extensions/ShowSelection/ShowSelectionPlugin.d.ts +2 -3
  232. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +3 -4
  233. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +2 -4
  234. package/types/src/extensions/Suggestions/SuggestionMarks.d.ts +4 -0
  235. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +5 -6
  236. package/types/src/i18n/locales/en.d.ts +0 -1
  237. package/types/src/i18n/locales/sk.d.ts +0 -1
  238. package/types/src/index.d.ts +15 -8
  239. package/dist/en-B7ycW7c8.js.map +0 -1
  240. package/dist/en-D4taoCs4.cjs.map +0 -1
  241. package/dist/tsconfig.tsbuildinfo +0 -1
  242. package/src/api/blockManipulation/selections/__snapshots__/selection.test.ts.snap +0 -844
  243. package/src/api/blockManipulation/selections/selection.test.ts +0 -72
  244. package/src/api/blockManipulation/selections/textCursorPosition/__snapshots__/textCursorPosition.test.ts.snap +0 -316
  245. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.ts +0 -74
@@ -1,5 +1,5 @@
1
- import { Mark, Node, Schema } from "@tiptap/pm/model";
2
-
1
+ import { Mark, Node, Schema, Slice } from "@tiptap/pm/model";
2
+ import type { Block } from "../../blocks/defaultBlocks.js";
3
3
  import UniqueID from "../../extensions/UniqueID/UniqueID.js";
4
4
  import type {
5
5
  BlockSchema,
@@ -13,24 +13,25 @@ import type {
13
13
  TableCell,
14
14
  TableContent,
15
15
  } from "../../schema/index.js";
16
- import { getBlockInfoWithManualOffset } from "../getBlockInfoFromPos.js";
17
-
18
- import type { Block } from "../../blocks/defaultBlocks.js";
19
16
  import {
20
17
  isLinkInlineContent,
21
18
  isStyledTextInlineContent,
22
19
  } from "../../schema/inlineContent/types.js";
23
20
  import { UnreachableCaseError } from "../../util/typescript.js";
24
- import { getBlockCache, getStyleSchema } from "../pmUtil.js";
25
- import { getInlineContentSchema } from "../pmUtil.js";
26
- import { getBlockSchema } from "../pmUtil.js";
21
+ import { getBlockInfoWithManualOffset } from "../getBlockInfoFromPos.js";
22
+ import {
23
+ getBlockCache,
24
+ getBlockSchema,
25
+ getInlineContentSchema,
26
+ getStyleSchema,
27
+ } from "../pmUtil.js";
27
28
 
28
29
  /**
29
30
  * Converts an internal (prosemirror) table node contentto a BlockNote Tablecontent
30
31
  */
31
32
  export function contentNodeToTableContent<
32
33
  I extends InlineContentSchema,
33
- S extends StyleSchema
34
+ S extends StyleSchema,
34
35
  >(contentNode: Node, inlineContentSchema: I, styleSchema: S) {
35
36
  const ret: TableContent<I, S> = {
36
37
  type: "tableContent",
@@ -70,34 +71,37 @@ export function contentNodeToTableContent<
70
71
  // Convert cell content to inline content and merge adjacent styled text nodes
71
72
  const content = cellNode.content.content
72
73
  .map((child) =>
73
- contentNodeToInlineContent(child, inlineContentSchema, styleSchema)
74
+ contentNodeToInlineContent(child, inlineContentSchema, styleSchema),
74
75
  )
75
76
  // The reason that we merge this content is that we allow table cells to contain multiple tableParagraph nodes
76
77
  // So that we can leverage prosemirror-tables native merging
77
78
  // If the schema only allowed a single tableParagraph node, then the merging would not work and cause prosemirror to fit the content into a new cell
78
- .reduce((acc, contentPartial) => {
79
- if (!acc.length) {
80
- return contentPartial;
81
- }
79
+ .reduce(
80
+ (acc, contentPartial) => {
81
+ if (!acc.length) {
82
+ return contentPartial;
83
+ }
82
84
 
83
- const last = acc[acc.length - 1];
84
- const first = contentPartial[0];
85
+ const last = acc[acc.length - 1];
86
+ const first = contentPartial[0];
85
87
 
86
- // Only merge if the last and first content are both styled text nodes and have the same styles
87
- if (
88
- first &&
89
- isStyledTextInlineContent(last) &&
90
- isStyledTextInlineContent(first) &&
91
- JSON.stringify(last.styles) === JSON.stringify(first.styles)
92
- ) {
93
- // Join them together if they have the same styles
94
- last.text += "\n" + first.text;
95
- acc.push(...contentPartial.slice(1));
88
+ // Only merge if the last and first content are both styled text nodes and have the same styles
89
+ if (
90
+ first &&
91
+ isStyledTextInlineContent(last) &&
92
+ isStyledTextInlineContent(first) &&
93
+ JSON.stringify(last.styles) === JSON.stringify(first.styles)
94
+ ) {
95
+ // Join them together if they have the same styles
96
+ last.text += "\n" + first.text;
97
+ acc.push(...contentPartial.slice(1));
98
+ return acc;
99
+ }
100
+ acc.push(...contentPartial);
96
101
  return acc;
97
- }
98
- acc.push(...contentPartial);
99
- return acc;
100
- }, [] as InlineContent<I, S>[]);
102
+ },
103
+ [] as InlineContent<I, S>[],
104
+ );
101
105
 
102
106
  return {
103
107
  type: "tableCell",
@@ -135,7 +139,7 @@ export function contentNodeToTableContent<
135
139
  */
136
140
  export function contentNodeToInlineContent<
137
141
  I extends InlineContentSchema,
138
- S extends StyleSchema
142
+ S extends StyleSchema,
139
143
  >(contentNode: Node, inlineContentSchema: I, styleSchema: S) {
140
144
  const content: InlineContent<any, S>[] = [];
141
145
  let currentContent: InlineContent<any, S> | undefined = undefined;
@@ -182,7 +186,7 @@ export function contentNodeToInlineContent<
182
186
  }
183
187
 
184
188
  content.push(
185
- nodeToCustomInlineContent(node, inlineContentSchema, styleSchema)
189
+ nodeToCustomInlineContent(node, inlineContentSchema, styleSchema),
186
190
  );
187
191
 
188
192
  return;
@@ -259,7 +263,8 @@ export function contentNodeToInlineContent<
259
263
  // Styles are the same.
260
264
  if (
261
265
  JSON.stringify(
262
- currentContent.content[currentContent.content.length - 1].styles
266
+ currentContent.content[currentContent.content.length - 1]
267
+ .styles,
263
268
  ) === JSON.stringify(styles)
264
269
  ) {
265
270
  currentContent.content[currentContent.content.length - 1].text +=
@@ -336,7 +341,7 @@ export function contentNodeToInlineContent<
336
341
 
337
342
  export function nodeToCustomInlineContent<
338
343
  I extends InlineContentSchema,
339
- S extends StyleSchema
344
+ S extends StyleSchema,
340
345
  >(node: Node, inlineContentSchema: I, styleSchema: S): InlineContent<I, S> {
341
346
  if (node.type.name === "text" || node.type.name === "link") {
342
347
  throw new Error("unexpected");
@@ -363,7 +368,7 @@ export function nodeToCustomInlineContent<
363
368
  content = contentNodeToInlineContent(
364
369
  node,
365
370
  inlineContentSchema,
366
- styleSchema
371
+ styleSchema,
367
372
  ) as any; // TODO: is this safe? could we have Links here that are undesired?
368
373
  } else {
369
374
  content = undefined;
@@ -385,14 +390,14 @@ export function nodeToCustomInlineContent<
385
390
  export function nodeToBlock<
386
391
  BSchema extends BlockSchema,
387
392
  I extends InlineContentSchema,
388
- S extends StyleSchema
393
+ S extends StyleSchema,
389
394
  >(
390
395
  node: Node,
391
396
  schema: Schema,
392
397
  blockSchema: BSchema = getBlockSchema(schema) as BSchema,
393
398
  inlineContentSchema: I = getInlineContentSchema(schema) as I,
394
399
  styleSchema: S = getStyleSchema(schema) as S,
395
- blockCache = getBlockCache(schema)
400
+ blockCache = getBlockCache(schema),
396
401
  ): Block<BSchema, I, S> {
397
402
  if (!node.type.isInGroup("bnBlock")) {
398
403
  throw Error("Node should be a bnBlock, but is instead: " + node.type.name);
@@ -445,8 +450,8 @@ export function nodeToBlock<
445
450
  blockSchema,
446
451
  inlineContentSchema,
447
452
  styleSchema,
448
- blockCache
449
- )
453
+ blockCache,
454
+ ),
450
455
  );
451
456
  });
452
457
 
@@ -459,7 +464,7 @@ export function nodeToBlock<
459
464
  content = contentNodeToInlineContent(
460
465
  blockInfo.blockContent.node,
461
466
  inlineContentSchema,
462
- styleSchema
467
+ styleSchema,
463
468
  );
464
469
  } else if (blockConfig.content === "table") {
465
470
  if (!blockInfo.isBlockContainer) {
@@ -468,7 +473,7 @@ export function nodeToBlock<
468
473
  content = contentNodeToTableContent(
469
474
  blockInfo.blockContent.node,
470
475
  inlineContentSchema,
471
- styleSchema
476
+ styleSchema,
472
477
  );
473
478
  } else if (blockConfig.content === "none") {
474
479
  content = undefined;
@@ -488,3 +493,197 @@ export function nodeToBlock<
488
493
 
489
494
  return block;
490
495
  }
496
+
497
+ /**
498
+ * Convert a Prosemirror document to a BlockNote document (array of blocks)
499
+ */
500
+ export function docToBlocks<
501
+ BSchema extends BlockSchema,
502
+ I extends InlineContentSchema,
503
+ S extends StyleSchema,
504
+ >(
505
+ doc: Node,
506
+ schema: Schema,
507
+ blockSchema: BSchema = getBlockSchema(schema) as BSchema,
508
+ inlineContentSchema: I = getInlineContentSchema(schema) as I,
509
+ styleSchema: S = getStyleSchema(schema) as S,
510
+ blockCache = getBlockCache(schema),
511
+ ) {
512
+ const blocks: Block<BSchema, I, S>[] = [];
513
+ doc.firstChild!.descendants((node) => {
514
+ blocks.push(
515
+ nodeToBlock(
516
+ node,
517
+ schema,
518
+ blockSchema,
519
+ inlineContentSchema,
520
+ styleSchema,
521
+ blockCache,
522
+ ),
523
+ );
524
+ return false;
525
+ });
526
+ return blocks;
527
+ }
528
+
529
+ /**
530
+ *
531
+ * Parse a Prosemirror Slice into a BlockNote selection. The prosemirror schema looks like this:
532
+ *
533
+ * <blockGroup>
534
+ * <blockContainer> (main content of block)
535
+ * <p, heading, etc.>
536
+ * <blockGroup> (only if blocks has children)
537
+ * <blockContainer> (child block)
538
+ * <p, heading, etc.>
539
+ * </blockContainer>
540
+ * <blockContainer> (child block 2)
541
+ * <p, heading, etc.>
542
+ * </blockContainer>
543
+ * </blockContainer>
544
+ * </blockGroup>
545
+ * </blockGroup>
546
+ *
547
+ */
548
+ export function prosemirrorSliceToSlicedBlocks<
549
+ BSchema extends BlockSchema,
550
+ I extends InlineContentSchema,
551
+ S extends StyleSchema,
552
+ >(
553
+ slice: Slice,
554
+ schema: Schema,
555
+ blockSchema: BSchema = getBlockSchema(schema) as BSchema,
556
+ inlineContentSchema: I = getInlineContentSchema(schema) as I,
557
+ styleSchema: S = getStyleSchema(schema) as S,
558
+ blockCache: WeakMap<Node, Block<BSchema, I, S>> = getBlockCache(schema),
559
+ ): {
560
+ /**
561
+ * The blocks that are included in the selection.
562
+ */
563
+ blocks: Block<BSchema, I, S>[];
564
+ /**
565
+ * If a block was "cut" at the start of the selection, this will be the id of the block that was cut.
566
+ */
567
+ blockCutAtStart: string | undefined;
568
+ /**
569
+ * If a block was "cut" at the end of the selection, this will be the id of the block that was cut.
570
+ */
571
+ blockCutAtEnd: string | undefined;
572
+ } {
573
+ // console.log(JSON.stringify(slice.toJSON()));
574
+ function processNode(
575
+ node: Node,
576
+ openStart: number,
577
+ openEnd: number,
578
+ ): {
579
+ blocks: Block<BSchema, I, S>[];
580
+ blockCutAtStart: string | undefined;
581
+ blockCutAtEnd: string | undefined;
582
+ } {
583
+ if (node.type.name !== "blockGroup") {
584
+ throw new Error("unexpected");
585
+ }
586
+ const blocks: Block<BSchema, I, S>[] = [];
587
+ let blockCutAtStart: string | undefined;
588
+ let blockCutAtEnd: string | undefined;
589
+
590
+ node.forEach((blockContainer, _offset, index) => {
591
+ if (blockContainer.type.name !== "blockContainer") {
592
+ throw new Error("unexpected");
593
+ }
594
+ if (blockContainer.childCount === 0) {
595
+ return;
596
+ }
597
+ if (blockContainer.childCount === 0 || blockContainer.childCount > 2) {
598
+ throw new Error(
599
+ "unexpected, blockContainer.childCount: " + blockContainer.childCount,
600
+ );
601
+ }
602
+
603
+ const isFirstBlock = index === 0;
604
+ const isLastBlock = index === node.childCount - 1;
605
+
606
+ if (blockContainer.firstChild!.type.name === "blockGroup") {
607
+ // this is the parent where a selection starts within one of its children,
608
+ // e.g.:
609
+ // A
610
+ // ├── B
611
+ // selection starts within B, then this blockContainer is A, but we don't care about A
612
+ // so let's descend into B and continue processing
613
+ if (!isFirstBlock) {
614
+ throw new Error("unexpected");
615
+ }
616
+ const ret = processNode(
617
+ blockContainer.firstChild!,
618
+ Math.max(0, openStart - 1),
619
+ isLastBlock ? Math.max(0, openEnd - 1) : 0,
620
+ );
621
+ blockCutAtStart = ret.blockCutAtStart;
622
+ if (isLastBlock) {
623
+ blockCutAtEnd = ret.blockCutAtEnd;
624
+ }
625
+ blocks.push(...ret.blocks);
626
+ return;
627
+ }
628
+
629
+ const block = nodeToBlock(
630
+ blockContainer,
631
+ schema,
632
+ blockSchema,
633
+ inlineContentSchema,
634
+ styleSchema,
635
+ blockCache,
636
+ );
637
+ const childGroup =
638
+ blockContainer.childCount > 1 ? blockContainer.child(1) : undefined;
639
+
640
+ let childBlocks: Block<BSchema, I, S>[] = [];
641
+ if (childGroup) {
642
+ const ret = processNode(
643
+ childGroup,
644
+ 0, // TODO: can this be anything other than 0?
645
+ isLastBlock ? Math.max(0, openEnd - 1) : 0,
646
+ );
647
+ childBlocks = ret.blocks;
648
+ if (isLastBlock) {
649
+ blockCutAtEnd = ret.blockCutAtEnd;
650
+ }
651
+ }
652
+
653
+ if (isLastBlock && !childGroup && openEnd > 1) {
654
+ blockCutAtEnd = block.id;
655
+ }
656
+
657
+ if (isFirstBlock && openStart > 1) {
658
+ blockCutAtStart = block.id;
659
+ }
660
+
661
+ blocks.push({
662
+ ...(block as any),
663
+ children: childBlocks,
664
+ });
665
+ });
666
+
667
+ return { blocks, blockCutAtStart, blockCutAtEnd };
668
+ }
669
+
670
+ if (slice.content.childCount === 0) {
671
+ return {
672
+ blocks: [],
673
+ blockCutAtStart: undefined,
674
+ blockCutAtEnd: undefined,
675
+ };
676
+ }
677
+
678
+ if (slice.content.childCount !== 1) {
679
+ throw new Error(
680
+ "slice must be a single block, did you forget includeParents=true?",
681
+ );
682
+ }
683
+
684
+ return processNode(
685
+ slice.content.firstChild!,
686
+ Math.max(slice.openStart - 1, 0),
687
+ Math.max(slice.openEnd - 1, 0),
688
+ );
689
+ }
@@ -27,7 +27,7 @@ describe("Test getBlocksChangedByTransaction", () => {
27
27
  });
28
28
 
29
29
  await expect(blocksChanged).toMatchFileSnapshot(
30
- "__snapshots__/blocks-inserted.json"
30
+ "__snapshots__/blocks-inserted.json",
31
31
  );
32
32
  });
33
33
 
@@ -41,14 +41,14 @@ describe("Test getBlocksChangedByTransaction", () => {
41
41
  },
42
42
  ],
43
43
  "paragraph-0",
44
- "after"
44
+ "after",
45
45
  );
46
46
 
47
47
  return getBlocksChangedByTransaction(tr);
48
48
  });
49
49
 
50
50
  await expect(blocksChanged).toMatchFileSnapshot(
51
- "__snapshots__/blocks-inserted-nested.json"
51
+ "__snapshots__/blocks-inserted-nested.json",
52
52
  );
53
53
  });
54
54
 
@@ -59,7 +59,7 @@ describe("Test getBlocksChangedByTransaction", () => {
59
59
  });
60
60
 
61
61
  await expect(blocksChanged).toMatchFileSnapshot(
62
- "__snapshots__/blocks-deleted.json"
62
+ "__snapshots__/blocks-deleted.json",
63
63
  );
64
64
  });
65
65
 
@@ -70,7 +70,7 @@ describe("Test getBlocksChangedByTransaction", () => {
70
70
  });
71
71
 
72
72
  await expect(blocksChanged).toMatchFileSnapshot(
73
- "__snapshots__/blocks-deleted-nested-deep.json"
73
+ "__snapshots__/blocks-deleted-nested-deep.json",
74
74
  );
75
75
  });
76
76
 
@@ -81,7 +81,7 @@ describe("Test getBlocksChangedByTransaction", () => {
81
81
  });
82
82
 
83
83
  await expect(blocksChanged).toMatchFileSnapshot(
84
- "__snapshots__/blocks-deleted-nested.json"
84
+ "__snapshots__/blocks-deleted-nested.json",
85
85
  );
86
86
  });
87
87
 
@@ -97,7 +97,7 @@ describe("Test getBlocksChangedByTransaction", () => {
97
97
  });
98
98
 
99
99
  await expect(blocksChanged).toMatchFileSnapshot(
100
- "__snapshots__/blocks-updated.json"
100
+ "__snapshots__/blocks-updated.json",
101
101
  );
102
102
  });
103
103
 
@@ -113,7 +113,7 @@ describe("Test getBlocksChangedByTransaction", () => {
113
113
  });
114
114
 
115
115
  await expect(blocksChanged).toMatchFileSnapshot(
116
- "__snapshots__/blocks-updated-nested.json"
116
+ "__snapshots__/blocks-updated-nested.json",
117
117
  );
118
118
  });
119
119
 
@@ -127,7 +127,7 @@ describe("Test getBlocksChangedByTransaction", () => {
127
127
  });
128
128
 
129
129
  await expect(blocksChanged).toMatchFileSnapshot(
130
- "__snapshots__/blocks-updated-nested-deep.json"
130
+ "__snapshots__/blocks-updated-nested-deep.json",
131
131
  );
132
132
  });
133
133
 
@@ -146,7 +146,7 @@ describe("Test getBlocksChangedByTransaction", () => {
146
146
  });
147
147
 
148
148
  await expect(blocksChanged).toMatchFileSnapshot(
149
- "__snapshots__/blocks-updated-nested-multiple.json"
149
+ "__snapshots__/blocks-updated-nested-multiple.json",
150
150
  );
151
151
  });
152
152
 
@@ -167,7 +167,7 @@ describe("Test getBlocksChangedByTransaction", () => {
167
167
  });
168
168
 
169
169
  await expect(blocksChanged).toMatchFileSnapshot(
170
- "__snapshots__/blocks-updated-single.json"
170
+ "__snapshots__/blocks-updated-single.json",
171
171
  );
172
172
  });
173
173
 
@@ -188,7 +188,7 @@ describe("Test getBlocksChangedByTransaction", () => {
188
188
  });
189
189
 
190
190
  await expect(blocksChanged).toMatchFileSnapshot(
191
- "__snapshots__/blocks-updated-multiple.json"
191
+ "__snapshots__/blocks-updated-multiple.json",
192
192
  );
193
193
  });
194
194
 
@@ -197,19 +197,19 @@ describe("Test getBlocksChangedByTransaction", () => {
197
197
  editor.insertBlocks(
198
198
  [{ type: "paragraph", content: "ABC" }],
199
199
  "paragraph-0",
200
- "after"
200
+ "after",
201
201
  );
202
202
  editor.insertBlocks(
203
203
  [{ type: "paragraph", content: "DEF" }],
204
204
  "paragraph-1",
205
- "after"
205
+ "after",
206
206
  );
207
207
 
208
208
  return getBlocksChangedByTransaction(tr);
209
209
  });
210
210
 
211
211
  await expect(blocksChanged).toMatchFileSnapshot(
212
- "__snapshots__/blocks-updated-multiple-insert.json"
212
+ "__snapshots__/blocks-updated-multiple-insert.json",
213
213
  );
214
214
  });
215
215
 
@@ -222,7 +222,7 @@ describe("Test getBlocksChangedByTransaction", () => {
222
222
  });
223
223
 
224
224
  await expect(blocksChanged).toMatchFileSnapshot(
225
- "__snapshots__/blocks-updated-content-inserted.json"
225
+ "__snapshots__/blocks-updated-content-inserted.json",
226
226
  );
227
227
  });
228
228
  });
@@ -22,7 +22,7 @@ import { getPmSchema } from "./pmUtil.js";
22
22
  */
23
23
  export function getNodeById(
24
24
  id: string,
25
- doc: Node
25
+ doc: Node,
26
26
  ): { node: Node; posBeforeNode: number } | undefined {
27
27
  let targetNode: Node | undefined = undefined;
28
28
  let posBeforeNode: number | undefined = undefined;
@@ -98,7 +98,7 @@ export type BlockChangeSource =
98
98
  export type BlocksChanged<
99
99
  BSchema extends BlockSchema = DefaultBlockSchema,
100
100
  ISchema extends InlineContentSchema = DefaultInlineContentSchema,
101
- SSchema extends StyleSchema = DefaultStyleSchema
101
+ SSchema extends StyleSchema = DefaultStyleSchema,
102
102
  > = Array<
103
103
  {
104
104
  /**
@@ -134,10 +134,10 @@ export type BlocksChanged<
134
134
  function areBlocksDifferentExcludingChildren<
135
135
  BSchema extends BlockSchema,
136
136
  ISchema extends InlineContentSchema,
137
- SSchema extends StyleSchema
137
+ SSchema extends StyleSchema,
138
138
  >(
139
139
  block1: Block<BSchema, ISchema, SSchema>,
140
- block2: Block<BSchema, ISchema, SSchema>
140
+ block2: Block<BSchema, ISchema, SSchema>,
141
141
  ): boolean {
142
142
  // TODO use an actual diff algorithm
143
143
  // Compare all properties except children
@@ -158,10 +158,10 @@ function areBlocksDifferentExcludingChildren<
158
158
  export function getBlocksChangedByTransaction<
159
159
  BSchema extends BlockSchema = DefaultBlockSchema,
160
160
  ISchema extends InlineContentSchema = DefaultInlineContentSchema,
161
- SSchema extends StyleSchema = DefaultStyleSchema
161
+ SSchema extends StyleSchema = DefaultStyleSchema,
162
162
  >(
163
163
  transaction: Transaction,
164
- appendedTransactions: Transaction[] = []
164
+ appendedTransactions: Transaction[] = [],
165
165
  ): BlocksChanged<BSchema, ISchema, SSchema> {
166
166
  let source: BlockChangeSource = { type: "local" };
167
167
 
@@ -198,7 +198,7 @@ export function getBlocksChangedByTransaction<
198
198
  return findChildrenInRange(
199
199
  combinedTransaction.before,
200
200
  range.oldRange,
201
- isNodeBlock
201
+ isNodeBlock,
202
202
  );
203
203
  })
204
204
  .map(({ node }) => nodeToBlock(node, pmSchema));
@@ -208,7 +208,7 @@ export function getBlocksChangedByTransaction<
208
208
  return findChildrenInRange(
209
209
  combinedTransaction.doc,
210
210
  range.newRange,
211
- isNodeBlock
211
+ isNodeBlock,
212
212
  );
213
213
  })
214
214
  .map(({ node }) => nodeToBlock(node, pmSchema));
@@ -216,12 +216,12 @@ export function getBlocksChangedByTransaction<
216
216
  const nextBlocks = new Map(
217
217
  nextAffectedBlocks.map((block) => {
218
218
  return [block.id, block];
219
- })
219
+ }),
220
220
  );
221
221
  const prevBlocks = new Map(
222
222
  prevAffectedBlocks.map((block) => {
223
223
  return [block.id, block];
224
- })
224
+ }),
225
225
  );
226
226
 
227
227
  const changes: BlocksChanged<BSchema, ISchema, SSchema> = [];
@@ -11,7 +11,7 @@ import { nestedListsToBlockNoteStructure } from "./util/nestedLists.js";
11
11
  export async function HTMLToBlocks<
12
12
  BSchema extends BlockSchema,
13
13
  I extends InlineContentSchema,
14
- S extends StyleSchema
14
+ S extends StyleSchema,
15
15
  >(html: string, pmSchema: Schema): Promise<Block<BSchema, I, S>[]> {
16
16
  const htmlNode = nestedListsToBlockNoteStructure(html);
17
17
  const parser = DOMParser.fromSchema(pmSchema);
@@ -33,7 +33,7 @@ function liftNestedListsToParent(element: HTMLElement) {
33
33
  const index = getChildIndex(list);
34
34
  const parentListItem = list.parentElement!;
35
35
  const siblingsAfter = Array.from(parentListItem.childNodes).slice(
36
- index + 1
36
+ index + 1,
37
37
  );
38
38
  list.remove();
39
39
  siblingsAfter.forEach((sibling) => {
@@ -110,7 +110,7 @@ function detachedDoc() {
110
110
  }
111
111
 
112
112
  export function nestedListsToBlockNoteStructure(
113
- elementOrHTML: HTMLElement | string
113
+ elementOrHTML: HTMLElement | string,
114
114
  ) {
115
115
  if (typeof elementOrHTML === "string") {
116
116
  const element = detachedDoc().createElement("div");
@@ -70,7 +70,7 @@ export async function markdownToHTML(markdown: string): Promise<string> {
70
70
  export async function markdownToBlocks<
71
71
  BSchema extends BlockSchema,
72
72
  I extends InlineContentSchema,
73
- S extends StyleSchema
73
+ S extends StyleSchema,
74
74
  >(markdown: string, pmSchema: Schema): Promise<Block<BSchema, I, S>[]> {
75
75
  const htmlString = await markdownToHTML(markdown);
76
76
 
package/src/api/pmUtil.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { Node, Schema } from "prosemirror-model";
2
- import type { Transaction } from "prosemirror-state";
2
+ import { Transform } from "prosemirror-transform";
3
3
  import type { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
4
+ import { BlockNoteSchema } from "../editor/BlockNoteSchema.js";
4
5
  import type { BlockSchema } from "../schema/blocks/types.js";
5
6
  import type { InlineContentSchema } from "../schema/inlineContent/types.js";
6
7
  import type { StyleSchema } from "../schema/styles/types.js";
7
- import { BlockNoteSchema } from "../editor/BlockNoteSchema.js";
8
8
 
9
- export function getPmSchema(trOrNode: Transaction | Node) {
9
+ export function getPmSchema(trOrNode: Transform | Node) {
10
10
  if ("doc" in trOrNode) {
11
11
  return trOrNode.doc.type.schema;
12
12
  }
@@ -16,7 +16,7 @@ export function getPmSchema(trOrNode: Transaction | Node) {
16
16
  function getBlockNoteEditor<
17
17
  BSchema extends BlockSchema,
18
18
  I extends InlineContentSchema,
19
- S extends StyleSchema
19
+ S extends StyleSchema,
20
20
  >(schema: Schema): BlockNoteEditor<BSchema, I, S> {
21
21
  return schema.cached.blockNoteEditor as BlockNoteEditor<BSchema, I, S>;
22
22
  }
@@ -24,7 +24,7 @@ function getBlockNoteEditor<
24
24
  export function getBlockNoteSchema<
25
25
  BSchema extends BlockSchema,
26
26
  I extends InlineContentSchema,
27
- S extends StyleSchema
27
+ S extends StyleSchema,
28
28
  >(schema: Schema): BlockNoteSchema<BSchema, I, S> {
29
29
  return getBlockNoteEditor(schema).schema as unknown as BlockNoteSchema<
30
30
  BSchema,
@@ -34,13 +34,13 @@ export function getBlockNoteSchema<
34
34
  }
35
35
 
36
36
  export function getBlockSchema<BSchema extends BlockSchema>(
37
- schema: Schema
37
+ schema: Schema,
38
38
  ): BSchema {
39
39
  return getBlockNoteSchema(schema).blockSchema as BSchema;
40
40
  }
41
41
 
42
42
  export function getInlineContentSchema<I extends InlineContentSchema>(
43
- schema: Schema
43
+ schema: Schema,
44
44
  ): I {
45
45
  return getBlockNoteSchema(schema).inlineContentSchema as I;
46
46
  }