@blocknote/core 0.9.6 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/dist/blocknote.js +3696 -2609
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +7 -7
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/dist/webpack-stats.json +1 -0
  7. package/package.json +11 -5
  8. package/src/api/README.md +8 -0
  9. package/src/api/blockManipulation/blockManipulation.test.ts +72 -10
  10. package/src/api/blockManipulation/blockManipulation.ts +38 -18
  11. package/src/api/exporters/copyExtension.ts +68 -0
  12. package/src/api/exporters/html/__snapshots__/complex/misc/external.html +1 -0
  13. package/src/api/exporters/html/__snapshots__/complex/misc/internal.html +1 -0
  14. package/src/api/exporters/html/__snapshots__/customParagraph/basic/external.html +1 -0
  15. package/src/api/exporters/html/__snapshots__/customParagraph/basic/internal.html +1 -0
  16. package/src/api/exporters/html/__snapshots__/customParagraph/nested/external.html +1 -0
  17. package/src/api/exporters/html/__snapshots__/customParagraph/nested/internal.html +1 -0
  18. package/src/api/exporters/html/__snapshots__/customParagraph/styled/external.html +1 -0
  19. package/src/api/exporters/html/__snapshots__/customParagraph/styled/internal.html +1 -0
  20. package/src/api/exporters/html/__snapshots__/fontSize/basic/external.html +1 -0
  21. package/src/api/exporters/html/__snapshots__/fontSize/basic/internal.html +1 -0
  22. package/src/api/exporters/html/__snapshots__/hardbreak/basic/external.html +1 -0
  23. package/src/api/exporters/html/__snapshots__/hardbreak/basic/internal.html +1 -0
  24. package/src/api/exporters/html/__snapshots__/hardbreak/between-links/external.html +1 -0
  25. package/src/api/exporters/html/__snapshots__/hardbreak/between-links/internal.html +1 -0
  26. package/src/api/exporters/html/__snapshots__/hardbreak/end/external.html +1 -0
  27. package/src/api/exporters/html/__snapshots__/hardbreak/end/internal.html +1 -0
  28. package/src/api/exporters/html/__snapshots__/hardbreak/link/external.html +1 -0
  29. package/src/api/exporters/html/__snapshots__/hardbreak/link/internal.html +1 -0
  30. package/src/api/exporters/html/__snapshots__/hardbreak/multiple/external.html +1 -0
  31. package/src/api/exporters/html/__snapshots__/hardbreak/multiple/internal.html +1 -0
  32. package/src/api/exporters/html/__snapshots__/hardbreak/only/external.html +1 -0
  33. package/src/api/exporters/html/__snapshots__/hardbreak/only/internal.html +1 -0
  34. package/src/api/exporters/html/__snapshots__/hardbreak/start/external.html +1 -0
  35. package/src/api/exporters/html/__snapshots__/hardbreak/start/internal.html +1 -0
  36. package/src/api/exporters/html/__snapshots__/hardbreak/styles/external.html +1 -0
  37. package/src/api/exporters/html/__snapshots__/hardbreak/styles/internal.html +1 -0
  38. package/src/api/exporters/html/__snapshots__/image/basic/external.html +1 -0
  39. package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -0
  40. package/src/api/exporters/html/__snapshots__/image/button/external.html +1 -0
  41. package/src/api/exporters/html/__snapshots__/image/button/internal.html +1 -0
  42. package/src/api/exporters/html/__snapshots__/image/nested/external.html +1 -0
  43. package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -0
  44. package/src/api/exporters/html/__snapshots__/link/adjacent/external.html +1 -0
  45. package/src/api/exporters/html/__snapshots__/link/adjacent/internal.html +1 -0
  46. package/src/api/exporters/html/__snapshots__/link/basic/external.html +1 -0
  47. package/src/api/exporters/html/__snapshots__/link/basic/internal.html +1 -0
  48. package/src/api/exporters/html/__snapshots__/link/styled/external.html +1 -0
  49. package/src/api/exporters/html/__snapshots__/link/styled/internal.html +1 -0
  50. package/src/api/exporters/html/__snapshots__/mention/basic/external.html +1 -0
  51. package/src/api/exporters/html/__snapshots__/mention/basic/internal.html +1 -0
  52. package/src/api/exporters/html/__snapshots__/paragraph/basic/external.html +1 -0
  53. package/src/api/exporters/html/__snapshots__/paragraph/basic/internal.html +1 -0
  54. package/src/api/exporters/html/__snapshots__/paragraph/empty/external.html +1 -0
  55. package/src/api/exporters/html/__snapshots__/paragraph/empty/internal.html +1 -0
  56. package/src/api/exporters/html/__snapshots__/paragraph/nested/external.html +1 -0
  57. package/src/api/exporters/html/__snapshots__/paragraph/nested/internal.html +1 -0
  58. package/src/api/exporters/html/__snapshots__/paragraph/styled/external.html +1 -0
  59. package/src/api/exporters/html/__snapshots__/paragraph/styled/internal.html +1 -0
  60. package/src/api/exporters/html/__snapshots__/paste/parse-basic-block-types.json +140 -0
  61. package/src/api/exporters/html/__snapshots__/paste/parse-deep-nested-content.json +240 -0
  62. package/src/api/exporters/html/__snapshots__/paste/parse-div-with-inline-content.json +91 -0
  63. package/src/api/exporters/html/__snapshots__/paste/parse-divs.json +19 -0
  64. package/src/api/exporters/html/__snapshots__/paste/parse-fake-image-caption.json +31 -0
  65. package/src/api/exporters/html/__snapshots__/paste/parse-mixed-nested-lists.json +70 -0
  66. package/src/api/exporters/html/__snapshots__/paste/parse-nested-lists-with-paragraphs.json +70 -0
  67. package/src/api/exporters/html/__snapshots__/paste/parse-nested-lists.json +70 -0
  68. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/basic/external.html +1 -0
  69. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/basic/internal.html +1 -0
  70. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/nested/external.html +1 -0
  71. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/nested/internal.html +1 -0
  72. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/styled/external.html +1 -0
  73. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/styled/internal.html +1 -0
  74. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -0
  75. package/src/api/exporters/html/__snapshots__/simpleImage/basic/internal.html +1 -0
  76. package/src/api/exporters/html/__snapshots__/simpleImage/button/external.html +1 -0
  77. package/src/api/exporters/html/__snapshots__/simpleImage/button/internal.html +1 -0
  78. package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -0
  79. package/src/api/exporters/html/__snapshots__/simpleImage/nested/internal.html +1 -0
  80. package/src/api/exporters/html/__snapshots__/small/basic/external.html +1 -0
  81. package/src/api/exporters/html/__snapshots__/small/basic/internal.html +1 -0
  82. package/src/api/exporters/html/__snapshots__/tag/basic/external.html +1 -0
  83. package/src/api/exporters/html/__snapshots__/tag/basic/internal.html +1 -0
  84. package/src/api/exporters/html/externalHTMLExporter.ts +98 -0
  85. package/src/api/exporters/html/htmlConversion.test.ts +100 -0
  86. package/src/api/exporters/html/internalHTMLSerializer.ts +80 -0
  87. package/src/api/exporters/html/util/sharedHTMLConversion.ts +128 -0
  88. package/src/api/{formatConversions → exporters/html/util}/simplifyBlocksRehypePlugin.ts +13 -0
  89. package/src/api/exporters/markdown/__snapshots__/complex/misc/markdown.md +5 -0
  90. package/src/api/exporters/markdown/__snapshots__/customParagraph/basic/markdown.md +1 -0
  91. package/src/api/exporters/markdown/__snapshots__/customParagraph/nested/markdown.md +5 -0
  92. package/src/api/exporters/markdown/__snapshots__/customParagraph/styled/markdown.md +1 -0
  93. package/src/api/exporters/markdown/__snapshots__/fontSize/basic/markdown.md +1 -0
  94. package/src/api/exporters/markdown/__snapshots__/hardbreak/basic/markdown.md +2 -0
  95. package/src/api/exporters/markdown/__snapshots__/hardbreak/between-links/markdown.md +2 -0
  96. package/src/api/exporters/markdown/__snapshots__/hardbreak/end/markdown.md +1 -0
  97. package/src/api/exporters/markdown/__snapshots__/hardbreak/link/markdown.md +2 -0
  98. package/src/api/exporters/markdown/__snapshots__/hardbreak/multiple/markdown.md +3 -0
  99. package/src/api/exporters/markdown/__snapshots__/hardbreak/start/markdown.md +1 -0
  100. package/src/api/exporters/markdown/__snapshots__/hardbreak/styles/markdown.md +2 -0
  101. package/src/api/exporters/markdown/__snapshots__/image/basic/markdown.md +3 -0
  102. package/src/api/exporters/markdown/__snapshots__/image/button/markdown.md +1 -0
  103. package/src/api/exporters/markdown/__snapshots__/image/nested/markdown.md +7 -0
  104. package/src/api/exporters/markdown/__snapshots__/link/adjacent/markdown.md +1 -0
  105. package/src/api/exporters/markdown/__snapshots__/link/basic/markdown.md +1 -0
  106. package/src/api/exporters/markdown/__snapshots__/link/styled/markdown.md +1 -0
  107. package/src/api/exporters/markdown/__snapshots__/mention/basic/markdown.md +1 -0
  108. package/src/api/exporters/markdown/__snapshots__/paragraph/basic/markdown.md +1 -0
  109. package/src/api/exporters/markdown/__snapshots__/paragraph/nested/markdown.md +5 -0
  110. package/src/api/exporters/markdown/__snapshots__/paragraph/styled/markdown.md +1 -0
  111. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/basic/markdown.md +1 -0
  112. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/nested/markdown.md +5 -0
  113. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/styled/markdown.md +1 -0
  114. package/src/api/exporters/markdown/__snapshots__/simpleImage/basic/markdown.md +1 -0
  115. package/src/api/exporters/markdown/__snapshots__/simpleImage/button/markdown.md +1 -0
  116. package/src/api/exporters/markdown/__snapshots__/simpleImage/nested/markdown.md +3 -0
  117. package/src/api/exporters/markdown/__snapshots__/small/basic/markdown.md +1 -0
  118. package/src/api/exporters/markdown/__snapshots__/tag/basic/markdown.md +1 -0
  119. package/src/api/exporters/markdown/markdownExporter.test.ts +85 -0
  120. package/src/api/exporters/markdown/markdownExporter.ts +42 -0
  121. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +486 -125
  122. package/src/api/nodeConversions/nodeConversions.test.ts +67 -498
  123. package/src/api/nodeConversions/nodeConversions.ts +311 -85
  124. package/src/api/parsers/html/__snapshots__/paste/list-test.json +105 -0
  125. package/src/api/parsers/html/__snapshots__/paste/parse-basic-block-types.json +140 -0
  126. package/src/api/parsers/html/__snapshots__/paste/parse-deep-nested-content.json +240 -0
  127. package/src/api/parsers/html/__snapshots__/paste/parse-div-with-inline-content.json +91 -0
  128. package/src/api/parsers/html/__snapshots__/paste/parse-divs.json +121 -0
  129. package/src/api/parsers/html/__snapshots__/paste/parse-fake-image-caption.json +31 -0
  130. package/src/api/parsers/html/__snapshots__/paste/parse-google-docs-html.json +476 -0
  131. package/src/api/parsers/html/__snapshots__/paste/parse-mixed-nested-lists.json +140 -0
  132. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists-with-paragraphs.json +140 -0
  133. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists.json +157 -0
  134. package/src/api/parsers/html/__snapshots__/paste/parse-notion-html.json +470 -0
  135. package/src/api/parsers/html/__snapshots__/paste/parse-two-divs.json +36 -0
  136. package/src/api/parsers/html/parseHTML.test.ts +440 -0
  137. package/src/api/parsers/html/parseHTML.ts +42 -0
  138. package/src/api/parsers/html/util/__snapshots__/nestedLists.test.ts.snap +129 -0
  139. package/src/api/parsers/html/util/nestedLists.test.ts +176 -0
  140. package/src/api/parsers/html/util/nestedLists.ts +113 -0
  141. package/src/api/parsers/markdown/__snapshots__/complex.json +353 -0
  142. package/src/api/parsers/markdown/__snapshots__/issue-226-1.json +71 -0
  143. package/src/api/parsers/markdown/__snapshots__/issue-226-2.json +144 -0
  144. package/src/api/parsers/markdown/__snapshots__/nested.json +72 -0
  145. package/src/api/parsers/markdown/__snapshots__/non-nested.json +71 -0
  146. package/src/api/parsers/markdown/__snapshots__/styled.json +58 -0
  147. package/src/api/parsers/markdown/parseMarkdown.test.ts +114 -0
  148. package/src/api/parsers/markdown/parseMarkdown.ts +84 -0
  149. package/src/api/parsers/pasteExtension.ts +59 -0
  150. package/src/api/testUtil/cases/customBlocks.ts +282 -0
  151. package/src/api/testUtil/cases/customInlineContent.ts +114 -0
  152. package/src/api/testUtil/cases/customStyles.ts +100 -0
  153. package/src/api/testUtil/cases/defaultSchema.ts +399 -0
  154. package/src/api/testUtil/index.ts +17 -0
  155. package/src/api/testUtil/partialBlockTestUtil.ts +127 -0
  156. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +136 -0
  157. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/ImageBlockContent.ts +87 -31
  158. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +34 -47
  159. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  160. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
  161. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +34 -56
  162. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +43 -0
  163. package/src/blocks/README.md +3 -0
  164. package/src/blocks/TableBlockContent/TableBlockContent.ts +74 -0
  165. package/src/blocks/TableBlockContent/TableExtension.ts +63 -0
  166. package/src/blocks/defaultBlockHelpers.ts +95 -0
  167. package/src/blocks/defaultBlocks.ts +60 -0
  168. package/src/blocks/defaultProps.ts +24 -0
  169. package/src/{extensions/Blocks/nodes/Block.module.css → editor/Block.css} +69 -62
  170. package/src/{BlockNoteEditor.test.ts → editor/BlockNoteEditor.test.ts} +2 -2
  171. package/src/{BlockNoteEditor.ts → editor/BlockNoteEditor.ts} +363 -153
  172. package/src/{BlockNoteExtensions.ts → editor/BlockNoteExtensions.ts} +59 -40
  173. package/src/editor/README.md +3 -0
  174. package/src/editor/cursorPositionTypes.ts +16 -0
  175. package/src/{editor.module.css → editor/editor.css} +43 -15
  176. package/src/editor/selectionTypes.ts +14 -0
  177. package/src/editor/transformPasted.ts +58 -0
  178. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +1 -36
  179. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +12 -27
  180. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +16 -24
  181. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +12 -10
  182. package/src/extensions/ImageToolbar/ImageToolbarPlugin.ts +35 -73
  183. package/src/extensions/Placeholder/PlaceholderExtension.ts +4 -4
  184. package/src/extensions/README.md +3 -0
  185. package/src/extensions/SideMenu/SideMenuPlugin.ts +66 -37
  186. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +7 -6
  187. package/src/extensions/SlashMenu/SlashMenuPlugin.ts +9 -7
  188. package/src/extensions/SlashMenu/defaultSlashMenuItems.ts +98 -35
  189. package/src/extensions/TableHandles/TableHandlesPlugin.ts +617 -0
  190. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +3 -51
  191. package/src/extensions/TextColor/TextColorExtension.ts +1 -29
  192. package/src/extensions/TextColor/TextColorMark.ts +7 -27
  193. package/src/extensions/UniqueID/UniqueID.ts +28 -2
  194. package/src/extensions-shared/README.md +3 -0
  195. package/src/{shared/plugins → extensions-shared}/suggestion/SuggestionPlugin.ts +19 -13
  196. package/src/index.ts +21 -15
  197. package/src/{extensions/Blocks/nodes → pm-nodes}/BlockContainer.ts +161 -96
  198. package/src/pm-nodes/BlockGroup.ts +54 -0
  199. package/src/pm-nodes/Doc.ts +7 -0
  200. package/src/pm-nodes/README.md +42 -0
  201. package/src/pm-nodes/index.ts +3 -0
  202. package/src/schema/README.md +3 -0
  203. package/src/schema/blocks/createSpec.ts +220 -0
  204. package/src/schema/blocks/internal.ts +253 -0
  205. package/src/schema/blocks/types.ts +252 -0
  206. package/src/schema/index.ts +10 -0
  207. package/src/schema/inlineContent/createSpec.ts +119 -0
  208. package/src/schema/inlineContent/internal.ts +105 -0
  209. package/src/schema/inlineContent/types.ts +144 -0
  210. package/src/schema/propTypes.ts +32 -0
  211. package/src/schema/styles/createSpec.ts +85 -0
  212. package/src/schema/styles/internal.ts +96 -0
  213. package/src/schema/styles/types.ts +42 -0
  214. package/src/util/README.md +3 -0
  215. package/src/{shared/utils.ts → util/browser.ts} +4 -8
  216. package/src/util/string.ts +3 -0
  217. package/src/util/typescript.ts +5 -0
  218. package/types/src/api/blockManipulation/blockManipulation.d.ts +5 -4
  219. package/types/src/api/exporters/copyExtension.d.ts +6 -0
  220. package/types/src/api/exporters/html/externalHTMLExporter.d.ts +8 -0
  221. package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +8 -0
  222. package/types/src/api/exporters/html/util/sharedHTMLConversion.d.ts +7 -0
  223. package/types/src/api/exporters/markdown/markdownExporter.d.ts +5 -0
  224. package/types/src/api/nodeConversions/nodeConversions.d.ts +14 -6
  225. package/types/src/api/parsers/html/parseHTML.d.ts +3 -0
  226. package/types/src/api/parsers/html/parseHTML.test.d.ts +1 -0
  227. package/types/src/api/parsers/html/util/nestedLists.d.ts +1 -0
  228. package/types/src/api/parsers/html/util/nestedLists.test.d.ts +1 -0
  229. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +3 -0
  230. package/types/src/api/parsers/markdown/parseMarkdown.test.d.ts +1 -0
  231. package/types/src/api/parsers/pasteExtension.d.ts +6 -0
  232. package/types/src/api/testUtil/cases/customBlocks.d.ts +345 -0
  233. package/types/src/api/testUtil/cases/customInlineContent.d.ts +29 -0
  234. package/types/src/api/testUtil/cases/customStyles.d.ts +64 -0
  235. package/types/src/api/testUtil/cases/defaultSchema.d.ts +3 -0
  236. package/types/src/api/testUtil/index.d.ts +12 -0
  237. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +7 -0
  238. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +58 -0
  239. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +93 -0
  240. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +46 -0
  241. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +46 -0
  242. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +52 -0
  243. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +53 -0
  244. package/types/src/blocks/TableBlockContent/TableExtension.d.ts +2 -0
  245. package/types/src/blocks/defaultBlockHelpers.d.ts +10 -0
  246. package/types/src/blocks/defaultBlocks.d.ts +577 -0
  247. package/types/src/{extensions/Blocks/api → blocks}/defaultProps.d.ts +2 -1
  248. package/types/src/{BlockNoteEditor.d.ts → editor/BlockNoteEditor.d.ts} +54 -43
  249. package/types/src/editor/BlockNoteEditor.test.d.ts +1 -0
  250. package/types/src/{BlockNoteExtensions.d.ts → editor/BlockNoteExtensions.d.ts} +7 -4
  251. package/types/src/editor/cursorPositionTypes.d.ts +6 -0
  252. package/types/src/editor/selectionTypes.d.ts +4 -0
  253. package/types/src/editor/transformPasted.d.ts +12 -0
  254. package/types/src/extensions/BackgroundColor/BackgroundColorExtension.d.ts +0 -7
  255. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +7 -9
  256. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +8 -6
  257. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +6 -6
  258. package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +11 -16
  259. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +18 -11
  260. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +5 -6
  261. package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +6 -6
  262. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +2 -1
  263. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +74 -0
  264. package/types/src/extensions/TextAlignment/TextAlignmentExtension.d.ts +0 -7
  265. package/types/src/extensions/TextColor/TextColorExtension.d.ts +0 -7
  266. package/types/src/extensions/TextColor/TextColorMark.d.ts +7 -9
  267. package/types/src/extensions/UniqueID/UniqueID.d.ts +1 -1
  268. package/types/src/{shared/plugins → extensions-shared}/suggestion/SuggestionPlugin.d.ts +5 -4
  269. package/types/src/index.d.ts +20 -15
  270. package/types/src/{extensions/Blocks/nodes → pm-nodes}/BlockContainer.d.ts +5 -3
  271. package/types/src/pm-nodes/Doc.d.ts +2 -0
  272. package/types/src/pm-nodes/index.d.ts +3 -0
  273. package/types/src/schema/blocks/createSpec.d.ts +35 -0
  274. package/types/src/schema/blocks/internal.d.ts +45 -0
  275. package/types/src/schema/blocks/types.d.ts +107 -0
  276. package/types/src/schema/index.d.ts +10 -0
  277. package/types/src/schema/inlineContent/createSpec.d.ts +21 -0
  278. package/types/src/schema/inlineContent/internal.d.ts +28 -0
  279. package/types/src/schema/inlineContent/types.d.ts +62 -0
  280. package/types/src/schema/propTypes.d.ts +8 -0
  281. package/types/src/schema/styles/createSpec.d.ts +13 -0
  282. package/types/src/schema/styles/internal.d.ts +22 -0
  283. package/types/src/schema/styles/types.d.ts +21 -0
  284. package/types/src/{shared/utils.d.ts → util/browser.d.ts} +0 -3
  285. package/types/src/util/string.d.ts +1 -0
  286. package/types/src/util/typescript.d.ts +3 -0
  287. package/src/api/formatConversions/__snapshots__/formatConversions.test.ts.snap +0 -346
  288. package/src/api/formatConversions/formatConversions.test.ts +0 -753
  289. package/src/api/formatConversions/formatConversions.ts +0 -133
  290. package/src/api/nodeConversions/testUtil.ts +0 -65
  291. package/src/extensions/Blocks/api/block.ts +0 -307
  292. package/src/extensions/Blocks/api/blockTypes.ts +0 -249
  293. package/src/extensions/Blocks/api/cursorPositionTypes.ts +0 -7
  294. package/src/extensions/Blocks/api/defaultBlocks.ts +0 -16
  295. package/src/extensions/Blocks/api/defaultProps.ts +0 -16
  296. package/src/extensions/Blocks/api/inlineContentTypes.ts +0 -36
  297. package/src/extensions/Blocks/api/selectionTypes.ts +0 -5
  298. package/src/extensions/Blocks/api/serialization.ts +0 -29
  299. package/src/extensions/Blocks/helpers/findBlock.ts +0 -5
  300. package/src/extensions/Blocks/index.ts +0 -8
  301. package/src/extensions/Blocks/nodes/BlockAttributes.ts +0 -10
  302. package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +0 -142
  303. package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +0 -62
  304. package/src/extensions/Blocks/nodes/BlockGroup.ts +0 -53
  305. package/types/src/api/formatConversions/formatConversions.d.ts +0 -6
  306. package/types/src/api/nodeConversions/testUtil.d.ts +0 -2
  307. package/types/src/extensions/Blocks/api/block.d.ts +0 -20
  308. package/types/src/extensions/Blocks/api/blockTypes.d.ts +0 -103
  309. package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +0 -6
  310. package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +0 -117
  311. package/types/src/extensions/Blocks/api/inlineContentTypes.d.ts +0 -30
  312. package/types/src/extensions/Blocks/api/selectionTypes.d.ts +0 -4
  313. package/types/src/extensions/Blocks/api/serialization.d.ts +0 -2
  314. package/types/src/extensions/Blocks/helpers/findBlock.d.ts +0 -6
  315. package/types/src/extensions/Blocks/index.d.ts +0 -4
  316. package/types/src/extensions/Blocks/nodes/BlockAttributes.d.ts +0 -2
  317. package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +0 -43
  318. package/types/src/extensions/Blocks/nodes/BlockContent/ImageBlockContent/ImageBlockContent.d.ts +0 -37
  319. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -35
  320. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -35
  321. package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -44
  322. /package/src/{shared/EditorElement.ts → api/exporters/markdown/__snapshots__/hardbreak/only/markdown.md} +0 -0
  323. /package/{types/src/shared/EditorElement.d.ts → src/api/exporters/markdown/__snapshots__/paragraph/empty/markdown.md} +0 -0
  324. /package/src/api/{formatConversions → exporters/markdown}/removeUnderlinesRehypePlugin.ts +0 -0
  325. /package/src/{extensions/Blocks/helpers → api}/getBlockInfoFromPos.ts +0 -0
  326. /package/src/api/{util/nodeUtil.ts → nodeUtil.ts} +0 -0
  327. /package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  328. /package/src/extensions/{Blocks → NonEditableBlocks}/NonEditableBlockPlugin.ts +0 -0
  329. /package/src/extensions/{Blocks → PreviousBlockType}/PreviousBlockTypePlugin.ts +0 -0
  330. /package/src/{shared → extensions-shared}/BaseUiElementTypes.ts +0 -0
  331. /package/src/{shared/plugins → extensions-shared}/suggestion/SuggestionItem.ts +0 -0
  332. /package/src/{shared → util}/EventEmitter.ts +0 -0
  333. /package/types/src/{BlockNoteEditor.test.d.ts → api/exporters/html/htmlConversion.test.d.ts} +0 -0
  334. /package/types/src/api/{formatConversions → exporters/html/util}/simplifyBlocksRehypePlugin.d.ts +0 -0
  335. /package/types/src/api/{formatConversions/formatConversions.test.d.ts → exporters/markdown/markdownExporter.test.d.ts} +0 -0
  336. /package/types/src/api/{formatConversions → exporters/markdown}/removeUnderlinesRehypePlugin.d.ts +0 -0
  337. /package/types/src/{extensions/Blocks/helpers → api}/getBlockInfoFromPos.d.ts +0 -0
  338. /package/types/src/api/{util/nodeUtil.d.ts → nodeUtil.d.ts} +0 -0
  339. /package/types/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
  340. /package/types/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/ListItemKeyboardShortcuts.d.ts +0 -0
  341. /package/types/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -0
  342. /package/types/src/extensions/{Blocks → NonEditableBlocks}/NonEditableBlockPlugin.d.ts +0 -0
  343. /package/types/src/extensions/{Blocks → PreviousBlockType}/PreviousBlockTypePlugin.d.ts +0 -0
  344. /package/types/src/{shared → extensions-shared}/BaseUiElementTypes.d.ts +0 -0
  345. /package/types/src/{shared/plugins → extensions-shared}/suggestion/SuggestionItem.d.ts +0 -0
  346. /package/types/src/{extensions/Blocks/nodes → pm-nodes}/BlockGroup.d.ts +0 -0
  347. /package/types/src/{shared → util}/EventEmitter.d.ts +0 -0
@@ -3,56 +3,78 @@ import { Node } from "prosemirror-model";
3
3
  // import "./blocknote.css";
4
4
  import { Editor as TiptapEditor } from "@tiptap/core/dist/packages/core/src/Editor";
5
5
  import * as Y from "yjs";
6
- import { getBlockNoteExtensions } from "./BlockNoteExtensions";
7
6
  import {
8
7
  insertBlocks,
9
8
  removeBlocks,
10
9
  replaceBlocks,
11
10
  updateBlock,
12
- } from "./api/blockManipulation/blockManipulation";
13
- import {
14
- HTMLToBlocks,
15
- blocksToHTML,
16
- blocksToMarkdown,
17
- markdownToBlocks,
18
- } from "./api/formatConversions/formatConversions";
11
+ } from "../api/blockManipulation/blockManipulation";
12
+ import { createExternalHTMLExporter } from "../api/exporters/html/externalHTMLExporter";
13
+ import { blocksToMarkdown } from "../api/exporters/markdown/markdownExporter";
14
+ import { getBlockInfoFromPos } from "../api/getBlockInfoFromPos";
19
15
  import {
20
16
  blockToNode,
21
17
  nodeToBlock,
22
- } from "./api/nodeConversions/nodeConversions";
23
- import { getNodeById } from "./api/util/nodeUtil";
24
- import styles from "./editor.module.css";
18
+ } from "../api/nodeConversions/nodeConversions";
19
+ import { getNodeById } from "../api/nodeUtil";
20
+ import { HTMLToBlocks } from "../api/parsers/html/parseHTML";
21
+ import { markdownToBlocks } from "../api/parsers/markdown/parseMarkdown";
22
+ import {
23
+ DefaultBlockSchema,
24
+ DefaultInlineContentSchema,
25
+ DefaultStyleSchema,
26
+ defaultBlockSchema,
27
+ defaultBlockSpecs,
28
+ defaultInlineContentSpecs,
29
+ defaultStyleSpecs,
30
+ } from "../blocks/defaultBlocks";
31
+ import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin";
32
+ import { HyperlinkToolbarProsemirrorPlugin } from "../extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
33
+ import { ImageToolbarProsemirrorPlugin } from "../extensions/ImageToolbar/ImageToolbarPlugin";
34
+ import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin";
35
+ import { BaseSlashMenuItem } from "../extensions/SlashMenu/BaseSlashMenuItem";
36
+ import { SlashMenuProsemirrorPlugin } from "../extensions/SlashMenu/SlashMenuPlugin";
37
+ import { getDefaultSlashMenuItems } from "../extensions/SlashMenu/defaultSlashMenuItems";
38
+ import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin";
39
+ import { UniqueID } from "../extensions/UniqueID/UniqueID";
25
40
  import {
26
41
  Block,
27
42
  BlockIdentifier,
28
43
  BlockNoteDOMAttributes,
29
44
  BlockSchema,
45
+ BlockSchemaFromSpecs,
46
+ BlockSchemaWithBlock,
47
+ BlockSpecs,
48
+ InlineContentSchema,
49
+ InlineContentSchemaFromSpecs,
50
+ InlineContentSpecs,
30
51
  PartialBlock,
31
- } from "./extensions/Blocks/api/blockTypes";
32
- import { TextCursorPosition } from "./extensions/Blocks/api/cursorPositionTypes";
33
- import {
34
- DefaultBlockSchema,
35
- defaultBlockSchema,
36
- } from "./extensions/Blocks/api/defaultBlocks";
37
- import {
38
- ColorStyle,
52
+ StyleSchema,
53
+ StyleSchemaFromSpecs,
54
+ StyleSpecs,
39
55
  Styles,
40
- ToggledStyle,
41
- } from "./extensions/Blocks/api/inlineContentTypes";
42
- import { Selection } from "./extensions/Blocks/api/selectionTypes";
43
- import { getBlockInfoFromPos } from "./extensions/Blocks/helpers/getBlockInfoFromPos";
44
-
45
- import { FormattingToolbarProsemirrorPlugin } from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
46
- import { HyperlinkToolbarProsemirrorPlugin } from "./extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
47
- import { ImageToolbarProsemirrorPlugin } from "./extensions/ImageToolbar/ImageToolbarPlugin";
48
- import { SideMenuProsemirrorPlugin } from "./extensions/SideMenu/SideMenuPlugin";
49
- import { BaseSlashMenuItem } from "./extensions/SlashMenu/BaseSlashMenuItem";
50
- import { SlashMenuProsemirrorPlugin } from "./extensions/SlashMenu/SlashMenuPlugin";
51
- import { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMenuItems";
52
- import { UniqueID } from "./extensions/UniqueID/UniqueID";
53
- import { mergeCSSClasses } from "./shared/utils";
54
-
55
- export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
56
+ getBlockSchemaFromSpecs,
57
+ getInlineContentSchemaFromSpecs,
58
+ getStyleSchemaFromSpecs,
59
+ } from "../schema";
60
+ import { mergeCSSClasses } from "../util/browser";
61
+ import { UnreachableCaseError } from "../util/typescript";
62
+
63
+ import { getBlockNoteExtensions } from "./BlockNoteExtensions";
64
+ import { TextCursorPosition } from "./cursorPositionTypes";
65
+
66
+ import { Selection } from "./selectionTypes";
67
+ import { transformPasted } from "./transformPasted";
68
+
69
+ // CSS
70
+ import "./Block.css";
71
+ import "./editor.css";
72
+
73
+ export type BlockNoteEditorOptions<
74
+ BSpecs extends BlockSpecs,
75
+ ISpecs extends InlineContentSpecs,
76
+ SSpecs extends StyleSpecs
77
+ > = {
56
78
  // TODO: Figure out if enableBlockNoteExtensions/disableHistoryExtension are needed and document them.
57
79
  enableBlockNoteExtensions: boolean;
58
80
  /**
@@ -61,7 +83,7 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
61
83
  *
62
84
  * @default defaultSlashMenuItems from `./extensions/SlashMenu`
63
85
  */
64
- slashMenuItems: BaseSlashMenuItem<any>[];
86
+ slashMenuItems: BaseSlashMenuItem<any, any, any>[];
65
87
 
66
88
  /**
67
89
  * The HTML element that should be used as the parent element for the editor.
@@ -78,15 +100,33 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
78
100
  /**
79
101
  * A callback function that runs when the editor is ready to be used.
80
102
  */
81
- onEditorReady: (editor: BlockNoteEditor<BSchema>) => void;
103
+ onEditorReady: (
104
+ editor: BlockNoteEditor<
105
+ BlockSchemaFromSpecs<BSpecs>,
106
+ InlineContentSchemaFromSpecs<ISpecs>,
107
+ StyleSchemaFromSpecs<SSpecs>
108
+ >
109
+ ) => void;
82
110
  /**
83
111
  * A callback function that runs whenever the editor's contents change.
84
112
  */
85
- onEditorContentChange: (editor: BlockNoteEditor<BSchema>) => void;
113
+ onEditorContentChange: (
114
+ editor: BlockNoteEditor<
115
+ BlockSchemaFromSpecs<BSpecs>,
116
+ InlineContentSchemaFromSpecs<ISpecs>,
117
+ StyleSchemaFromSpecs<SSpecs>
118
+ >
119
+ ) => void;
86
120
  /**
87
121
  * A callback function that runs whenever the text cursor position changes.
88
122
  */
89
- onTextCursorPositionChange: (editor: BlockNoteEditor<BSchema>) => void;
123
+ onTextCursorPositionChange: (
124
+ editor: BlockNoteEditor<
125
+ BlockSchemaFromSpecs<BSpecs>,
126
+ InlineContentSchemaFromSpecs<ISpecs>,
127
+ StyleSchemaFromSpecs<SSpecs>
128
+ >
129
+ ) => void;
90
130
  /**
91
131
  * Locks the editor from being editable by the user if set to `false`.
92
132
  */
@@ -94,7 +134,11 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
94
134
  /**
95
135
  * The content that should be in the editor when it's created, represented as an array of partial block objects.
96
136
  */
97
- initialContent: PartialBlock<BSchema>[];
137
+ initialContent: PartialBlock<
138
+ BlockSchemaFromSpecs<BSpecs>,
139
+ InlineContentSchemaFromSpecs<ISpecs>,
140
+ StyleSchemaFromSpecs<SSpecs>
141
+ >[];
98
142
  /**
99
143
  * Use default BlockNote font and reset the styles of <p> <li> <h1> elements etc., that are used in BlockNote.
100
144
  *
@@ -105,7 +149,11 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
105
149
  /**
106
150
  * A list of block types that should be available in the editor.
107
151
  */
108
- blockSchema: BSchema;
152
+ blockSpecs: BSpecs;
153
+
154
+ styleSpecs: SSpecs;
155
+
156
+ inlineContentSpecs: ISpecs;
109
157
 
110
158
  /**
111
159
  * A custom function to handle file uploads.
@@ -149,52 +197,115 @@ const blockNoteTipTapOptions = {
149
197
  enableCoreExtensions: false,
150
198
  };
151
199
 
152
- export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
200
+ export class BlockNoteEditor<
201
+ BSchema extends BlockSchema = DefaultBlockSchema,
202
+ ISchema extends InlineContentSchema = DefaultInlineContentSchema,
203
+ SSchema extends StyleSchema = DefaultStyleSchema
204
+ > {
153
205
  public readonly _tiptapEditor: TiptapEditor & { contentComponent: any };
154
- public blockCache = new WeakMap<Node, Block<BSchema>>();
155
- public readonly schema: BSchema;
206
+ public blockCache = new WeakMap<Node, Block<any, any, any>>();
207
+ public readonly blockSchema: BSchema;
208
+ public readonly inlineContentSchema: ISchema;
209
+ public readonly styleSchema: SSchema;
210
+
211
+ public readonly blockImplementations: BlockSpecs;
212
+ public readonly inlineContentImplementations: InlineContentSpecs;
213
+ public readonly styleImplementations: StyleSpecs;
214
+
156
215
  public ready = false;
157
216
 
158
- public readonly sideMenu: SideMenuProsemirrorPlugin<BSchema>;
159
- public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin<BSchema>;
160
- public readonly slashMenu: SlashMenuProsemirrorPlugin<BSchema, any>;
161
- public readonly hyperlinkToolbar: HyperlinkToolbarProsemirrorPlugin<BSchema>;
162
- public readonly imageToolbar: ImageToolbarProsemirrorPlugin<BSchema>;
217
+ public readonly sideMenu: SideMenuProsemirrorPlugin<
218
+ BSchema,
219
+ ISchema,
220
+ SSchema
221
+ >;
222
+ public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin;
223
+ public readonly slashMenu: SlashMenuProsemirrorPlugin<
224
+ BSchema,
225
+ ISchema,
226
+ SSchema,
227
+ any
228
+ >;
229
+ public readonly hyperlinkToolbar: HyperlinkToolbarProsemirrorPlugin<
230
+ BSchema,
231
+ ISchema,
232
+ SSchema
233
+ >;
234
+ public readonly imageToolbar: ImageToolbarProsemirrorPlugin<
235
+ BSchema,
236
+ ISchema,
237
+ SSchema
238
+ >;
239
+ public readonly tableHandles:
240
+ | TableHandlesProsemirrorPlugin<
241
+ BSchema extends BlockSchemaWithBlock<
242
+ "table",
243
+ DefaultBlockSchema["table"]
244
+ >
245
+ ? BSchema
246
+ : any,
247
+ ISchema,
248
+ SSchema
249
+ >
250
+ | undefined;
163
251
 
164
252
  public readonly uploadFile: ((file: File) => Promise<string>) | undefined;
165
253
 
166
- constructor(
167
- private readonly options: Partial<BlockNoteEditorOptions<BSchema>> = {}
254
+ public static create<
255
+ BSpecs extends BlockSpecs = typeof defaultBlockSpecs,
256
+ ISpecs extends InlineContentSpecs = typeof defaultInlineContentSpecs,
257
+ SSpecs extends StyleSpecs = typeof defaultStyleSpecs
258
+ >(options: Partial<BlockNoteEditorOptions<BSpecs, ISpecs, SSpecs>> = {}) {
259
+ return new BlockNoteEditor(options) as BlockNoteEditor<
260
+ BlockSchemaFromSpecs<BSpecs>,
261
+ InlineContentSchemaFromSpecs<ISpecs>,
262
+ StyleSchemaFromSpecs<SSpecs>
263
+ >;
264
+ }
265
+
266
+ private constructor(
267
+ private readonly options: Partial<BlockNoteEditorOptions<any, any, any>>
168
268
  ) {
169
269
  // apply defaults
170
- const newOptions: Omit<typeof options, "defaultStyles" | "blockSchema"> & {
171
- defaultStyles: boolean;
172
- blockSchema: BSchema;
173
- } = {
270
+ const newOptions = {
174
271
  defaultStyles: true,
175
- // TODO: There's a lot of annoying typing stuff to deal with here. If
176
- // BSchema is specified, then options.blockSchema should also be required.
177
- // If BSchema is not specified, then options.blockSchema should also not
178
- // be defined. Unfortunately, trying to implement these constraints seems
179
- // to be a huge pain, hence the `as any` casts.
180
- blockSchema: options.blockSchema || (defaultBlockSchema as any),
272
+ blockSpecs: options.blockSpecs || defaultBlockSpecs,
273
+ styleSpecs: options.styleSpecs || defaultStyleSpecs,
274
+ inlineContentSpecs:
275
+ options.inlineContentSpecs || defaultInlineContentSpecs,
181
276
  ...options,
182
277
  };
183
278
 
279
+ this.blockSchema = getBlockSchemaFromSpecs(newOptions.blockSpecs);
280
+ this.inlineContentSchema = getInlineContentSchemaFromSpecs(
281
+ newOptions.inlineContentSpecs
282
+ );
283
+ this.styleSchema = getStyleSchemaFromSpecs(newOptions.styleSpecs);
284
+ this.blockImplementations = newOptions.blockSpecs;
285
+ this.inlineContentImplementations = newOptions.inlineContentSpecs;
286
+ this.styleImplementations = newOptions.styleSpecs;
287
+
184
288
  this.sideMenu = new SideMenuProsemirrorPlugin(this);
185
289
  this.formattingToolbar = new FormattingToolbarProsemirrorPlugin(this);
186
290
  this.slashMenu = new SlashMenuProsemirrorPlugin(
187
291
  this,
188
292
  newOptions.slashMenuItems ||
189
- getDefaultSlashMenuItems(newOptions.blockSchema)
293
+ (getDefaultSlashMenuItems(this.blockSchema) as any)
190
294
  );
191
295
  this.hyperlinkToolbar = new HyperlinkToolbarProsemirrorPlugin(this);
192
296
  this.imageToolbar = new ImageToolbarProsemirrorPlugin(this);
193
297
 
194
- const extensions = getBlockNoteExtensions<BSchema>({
298
+ if (this.blockSchema.table === defaultBlockSchema.table) {
299
+ this.tableHandles = new TableHandlesProsemirrorPlugin(this as any);
300
+ }
301
+
302
+ const extensions = getBlockNoteExtensions({
195
303
  editor: this,
196
304
  domAttributes: newOptions.domAttributes || {},
197
- blockSchema: newOptions.blockSchema,
305
+ blockSchema: this.blockSchema,
306
+ blockSpecs: newOptions.blockSpecs,
307
+ styleSpecs: newOptions.styleSpecs,
308
+ inlineContentSpecs: newOptions.inlineContentSpecs,
198
309
  collaboration: newOptions.collaboration,
199
310
  });
200
311
 
@@ -208,15 +319,20 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
208
319
  this.slashMenu.plugin,
209
320
  this.hyperlinkToolbar.plugin,
210
321
  this.imageToolbar.plugin,
322
+ ...(this.tableHandles ? [this.tableHandles.plugin] : []),
211
323
  ];
212
324
  },
213
325
  });
214
326
  extensions.push(blockNoteUIExtension);
215
327
 
216
- this.schema = newOptions.blockSchema;
217
-
218
328
  this.uploadFile = newOptions.uploadFile;
219
329
 
330
+ if (newOptions.collaboration && newOptions.initialContent) {
331
+ console.warn(
332
+ "When using Collaboration, initialContent might cause conflicts, because changes should come from the collaboration provider"
333
+ );
334
+ }
335
+
220
336
  const initialContent =
221
337
  newOptions.initialContent ||
222
338
  (options.collaboration
@@ -227,26 +343,46 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
227
343
  id: UniqueID.options.generateID(),
228
344
  },
229
345
  ]);
346
+ const styleSchema = this.styleSchema;
230
347
 
231
348
  const tiptapOptions: Partial<EditorOptions> = {
232
349
  ...blockNoteTipTapOptions,
233
350
  ...newOptions._tiptapOptions,
234
351
  onBeforeCreate(editor) {
235
352
  newOptions._tiptapOptions?.onBeforeCreate?.(editor);
236
- if (!initialContent) {
237
- // when using collaboration
238
- return;
239
- }
240
-
241
353
  // We always set the initial content to a single paragraph block. This
242
354
  // allows us to easily replace it with the actual initial content once
243
355
  // the TipTap editor is initialized.
244
356
  const schema = editor.editor.schema;
357
+
358
+ // This is a hack to make "initial content detection" by y-prosemirror (and also tiptap isEmpty)
359
+ // properly detect whether or not the document has changed.
360
+ // We change the doc.createAndFill function to make sure the initial block id is set, instead of null
361
+ let cache: any;
362
+ const oldCreateAndFill = schema.nodes.doc.createAndFill;
363
+ (schema.nodes.doc as any).createAndFill = (...args: any) => {
364
+ if (cache) {
365
+ return cache;
366
+ }
367
+ const ret = oldCreateAndFill.apply(schema.nodes.doc, args);
368
+
369
+ // create a copy that we can mutate (otherwise, assigning attrs is not safe and corrupts the pm state)
370
+ const jsonNode = JSON.parse(JSON.stringify(ret!.toJSON()));
371
+ jsonNode.content[0].content[0].attrs.id = "initialBlockId";
372
+
373
+ cache = Node.fromJSON(schema, jsonNode);
374
+ return ret;
375
+ };
376
+
245
377
  const root = schema.node(
246
378
  "doc",
247
379
  undefined,
248
380
  schema.node("blockGroup", undefined, [
249
- blockToNode({ id: "initialBlock", type: "paragraph" }, schema),
381
+ blockToNode(
382
+ { id: "initialBlockId", type: "paragraph" },
383
+ schema,
384
+ styleSchema
385
+ ),
250
386
  ])
251
387
  );
252
388
  editor.editor.options.content = root.toJSON();
@@ -257,7 +393,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
257
393
  // initial content, as the schema may contain custom blocks which need
258
394
  // it to render.
259
395
  if (initialContent !== undefined) {
260
- this.replaceBlocks(this.topLevelBlocks, initialContent);
396
+ this.replaceBlocks(this.topLevelBlocks, initialContent as any);
261
397
  }
262
398
 
263
399
  newOptions.onEditorReady?.(this);
@@ -299,13 +435,13 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
299
435
  ...newOptions._tiptapOptions?.editorProps?.attributes,
300
436
  ...newOptions.domAttributes?.editor,
301
437
  class: mergeCSSClasses(
302
- styles.bnEditor,
303
- styles.bnRoot,
304
- newOptions.domAttributes?.editor?.class || "",
305
- newOptions.defaultStyles ? styles.defaultStyles : "",
438
+ "bn-root",
439
+ "bn-editor",
440
+ newOptions.defaultStyles ? "bn-default-styles" : "",
306
441
  newOptions.domAttributes?.editor?.class || ""
307
442
  ),
308
443
  },
444
+ transformPasted,
309
445
  },
310
446
  };
311
447
 
@@ -338,11 +474,19 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
338
474
  * Gets a snapshot of all top-level (non-nested) blocks in the editor.
339
475
  * @returns A snapshot of all top-level (non-nested) blocks in the editor.
340
476
  */
341
- public get topLevelBlocks(): Block<BSchema>[] {
342
- const blocks: Block<BSchema>[] = [];
477
+ public get topLevelBlocks(): Block<BSchema, ISchema, SSchema>[] {
478
+ const blocks: Block<BSchema, ISchema, SSchema>[] = [];
343
479
 
344
480
  this._tiptapEditor.state.doc.firstChild!.descendants((node) => {
345
- blocks.push(nodeToBlock(node, this.schema, this.blockCache));
481
+ blocks.push(
482
+ nodeToBlock(
483
+ node,
484
+ this.blockSchema,
485
+ this.inlineContentSchema,
486
+ this.styleSchema,
487
+ this.blockCache
488
+ )
489
+ );
346
490
 
347
491
  return false;
348
492
  });
@@ -357,12 +501,12 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
357
501
  */
358
502
  public getBlock(
359
503
  blockIdentifier: BlockIdentifier
360
- ): Block<BSchema> | undefined {
504
+ ): Block<BSchema, ISchema, SSchema> | undefined {
361
505
  const id =
362
506
  typeof blockIdentifier === "string"
363
507
  ? blockIdentifier
364
508
  : blockIdentifier.id;
365
- let newBlock: Block<BSchema> | undefined = undefined;
509
+ let newBlock: Block<BSchema, ISchema, SSchema> | undefined = undefined;
366
510
 
367
511
  this._tiptapEditor.state.doc.firstChild!.descendants((node) => {
368
512
  if (typeof newBlock !== "undefined") {
@@ -373,7 +517,13 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
373
517
  return true;
374
518
  }
375
519
 
376
- newBlock = nodeToBlock(node, this.schema, this.blockCache);
520
+ newBlock = nodeToBlock(
521
+ node,
522
+ this.blockSchema,
523
+ this.inlineContentSchema,
524
+ this.styleSchema,
525
+ this.blockCache
526
+ );
377
527
 
378
528
  return false;
379
529
  });
@@ -387,7 +537,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
387
537
  * @param reverse Whether the blocks should be traversed in reverse order.
388
538
  */
389
539
  public forEachBlock(
390
- callback: (block: Block<BSchema>) => boolean,
540
+ callback: (block: Block<BSchema, ISchema, SSchema>) => boolean,
391
541
  reverse = false
392
542
  ): void {
393
543
  const blocks = this.topLevelBlocks.slice();
@@ -396,7 +546,9 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
396
546
  blocks.reverse();
397
547
  }
398
548
 
399
- function traverseBlockArray(blockArray: Block<BSchema>[]): boolean {
549
+ function traverseBlockArray(
550
+ blockArray: Block<BSchema, ISchema, SSchema>[]
551
+ ): boolean {
400
552
  for (const block of blockArray) {
401
553
  if (!callback(block)) {
402
554
  return false;
@@ -437,7 +589,11 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
437
589
  * Gets a snapshot of the current text cursor position.
438
590
  * @returns A snapshot of the current text cursor position.
439
591
  */
440
- public getTextCursorPosition(): TextCursorPosition<BSchema> {
592
+ public getTextCursorPosition(): TextCursorPosition<
593
+ BSchema,
594
+ ISchema,
595
+ SSchema
596
+ > {
441
597
  const { node, depth, startPos, endPos } = getBlockInfoFromPos(
442
598
  this._tiptapEditor.state.doc,
443
599
  this._tiptapEditor.state.selection.from
@@ -465,15 +621,33 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
465
621
  }
466
622
 
467
623
  return {
468
- block: nodeToBlock(node, this.schema, this.blockCache),
624
+ block: nodeToBlock(
625
+ node,
626
+ this.blockSchema,
627
+ this.inlineContentSchema,
628
+ this.styleSchema,
629
+ this.blockCache
630
+ ),
469
631
  prevBlock:
470
632
  prevNode === undefined
471
633
  ? undefined
472
- : nodeToBlock(prevNode, this.schema, this.blockCache),
634
+ : nodeToBlock(
635
+ prevNode,
636
+ this.blockSchema,
637
+ this.inlineContentSchema,
638
+ this.styleSchema,
639
+ this.blockCache
640
+ ),
473
641
  nextBlock:
474
642
  nextNode === undefined
475
643
  ? undefined
476
- : nodeToBlock(nextNode, this.schema, this.blockCache),
644
+ : nodeToBlock(
645
+ nextNode,
646
+ this.blockSchema,
647
+ this.inlineContentSchema,
648
+ this.styleSchema,
649
+ this.blockCache
650
+ ),
477
651
  };
478
652
  }
479
653
 
@@ -495,25 +669,42 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
495
669
  posBeforeNode + 2
496
670
  )!;
497
671
 
498
- // For blocks without inline content
499
- if (contentNode.type.spec.content === "") {
672
+ const contentType: "none" | "inline" | "table" =
673
+ this.blockSchema[contentNode.type.name]!.content;
674
+
675
+ if (contentType === "none") {
500
676
  this._tiptapEditor.commands.setNodeSelection(startPos);
501
677
  return;
502
678
  }
503
679
 
504
- if (placement === "start") {
505
- this._tiptapEditor.commands.setTextSelection(startPos + 1);
680
+ if (contentType === "inline") {
681
+ if (placement === "start") {
682
+ this._tiptapEditor.commands.setTextSelection(startPos + 1);
683
+ } else {
684
+ this._tiptapEditor.commands.setTextSelection(
685
+ startPos + contentNode.nodeSize - 1
686
+ );
687
+ }
688
+ } else if (contentType === "table") {
689
+ if (placement === "start") {
690
+ // Need to offset the position as we have to get through the `tableRow`
691
+ // and `tableCell` nodes to get to the `tableParagraph` node we want to
692
+ // set the selection in.
693
+ this._tiptapEditor.commands.setTextSelection(startPos + 4);
694
+ } else {
695
+ this._tiptapEditor.commands.setTextSelection(
696
+ startPos + contentNode.nodeSize - 4
697
+ );
698
+ }
506
699
  } else {
507
- this._tiptapEditor.commands.setTextSelection(
508
- startPos + contentNode.nodeSize - 1
509
- );
700
+ throw new UnreachableCaseError(contentType);
510
701
  }
511
702
  }
512
703
 
513
704
  /**
514
705
  * Gets a snapshot of the current selection.
515
706
  */
516
- public getSelection(): Selection<BSchema> | undefined {
707
+ public getSelection(): Selection<BSchema, ISchema, SSchema> | undefined {
517
708
  // Either the TipTap selection is empty, or it's a node selection. In either
518
709
  // case, it only spans one block, so we return undefined.
519
710
  if (
@@ -524,8 +715,10 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
524
715
  return undefined;
525
716
  }
526
717
 
527
- const blocks: Block<BSchema>[] = [];
718
+ const blocks: Block<BSchema, ISchema, SSchema>[] = [];
528
719
 
720
+ // TODO: This adds all child blocks to the same array. Needs to find min
721
+ // depth and only add blocks at that depth.
529
722
  this._tiptapEditor.state.doc.descendants((node, pos) => {
530
723
  if (node.type.spec.group !== "blockContent") {
531
724
  return true;
@@ -541,7 +734,9 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
541
734
  blocks.push(
542
735
  nodeToBlock(
543
736
  this._tiptapEditor.state.doc.resolve(pos).node(),
544
- this.schema,
737
+ this.blockSchema,
738
+ this.inlineContentSchema,
739
+ this.styleSchema,
545
740
  this.blockCache
546
741
  )
547
742
  );
@@ -577,11 +772,11 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
577
772
  * `referenceBlock`. Inserts the blocks at the start of the existing block's children if "nested" is used.
578
773
  */
579
774
  public insertBlocks(
580
- blocksToInsert: PartialBlock<BSchema>[],
775
+ blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[],
581
776
  referenceBlock: BlockIdentifier,
582
777
  placement: "before" | "after" | "nested" = "before"
583
778
  ): void {
584
- insertBlocks(blocksToInsert, referenceBlock, placement, this._tiptapEditor);
779
+ insertBlocks(blocksToInsert, referenceBlock, placement, this);
585
780
  }
586
781
 
587
782
  /**
@@ -593,7 +788,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
593
788
  */
594
789
  public updateBlock(
595
790
  blockToUpdate: BlockIdentifier,
596
- update: PartialBlock<BSchema>
791
+ update: PartialBlock<BSchema, ISchema, SSchema>
597
792
  ) {
598
793
  updateBlock(blockToUpdate, update, this._tiptapEditor);
599
794
  }
@@ -615,32 +810,28 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
615
810
  */
616
811
  public replaceBlocks(
617
812
  blocksToRemove: BlockIdentifier[],
618
- blocksToInsert: PartialBlock<BSchema>[]
813
+ blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[]
619
814
  ) {
620
- replaceBlocks(blocksToRemove, blocksToInsert, this._tiptapEditor);
815
+ replaceBlocks(blocksToRemove, blocksToInsert, this);
621
816
  }
622
817
 
623
818
  /**
624
819
  * Gets the active text styles at the text cursor position or at the end of the current selection if it's active.
625
820
  */
626
821
  public getActiveStyles() {
627
- const styles: Styles = {};
822
+ const styles: Styles<SSchema> = {};
628
823
  const marks = this._tiptapEditor.state.selection.$to.marks();
629
824
 
630
- const toggleStyles = new Set<ToggledStyle>([
631
- "bold",
632
- "italic",
633
- "underline",
634
- "strike",
635
- "code",
636
- ]);
637
- const colorStyles = new Set<ColorStyle>(["textColor", "backgroundColor"]);
638
-
639
825
  for (const mark of marks) {
640
- if (toggleStyles.has(mark.type.name as ToggledStyle)) {
641
- styles[mark.type.name as ToggledStyle] = true;
642
- } else if (colorStyles.has(mark.type.name as ColorStyle)) {
643
- styles[mark.type.name as ColorStyle] = mark.attrs.color;
826
+ const config = this.styleSchema[mark.type.name];
827
+ if (!config) {
828
+ console.warn("mark not found in styleschema", mark.type.name);
829
+ continue;
830
+ }
831
+ if (config.propSchema === "boolean") {
832
+ (styles as any)[config.type] = true;
833
+ } else {
834
+ (styles as any)[config.type] = mark.attrs.stringValue;
644
835
  }
645
836
  }
646
837
 
@@ -651,23 +842,20 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
651
842
  * Adds styles to the currently selected content.
652
843
  * @param styles The styles to add.
653
844
  */
654
- public addStyles(styles: Styles) {
655
- const toggleStyles = new Set<ToggledStyle>([
656
- "bold",
657
- "italic",
658
- "underline",
659
- "strike",
660
- "code",
661
- ]);
662
- const colorStyles = new Set<ColorStyle>(["textColor", "backgroundColor"]);
663
-
845
+ public addStyles(styles: Styles<SSchema>) {
664
846
  this._tiptapEditor.view.focus();
665
847
 
666
848
  for (const [style, value] of Object.entries(styles)) {
667
- if (toggleStyles.has(style as ToggledStyle)) {
849
+ const config = this.styleSchema[style];
850
+ if (!config) {
851
+ throw new Error(`style ${style} not found in styleSchema`);
852
+ }
853
+ if (config.propSchema === "boolean") {
668
854
  this._tiptapEditor.commands.setMark(style);
669
- } else if (colorStyles.has(style as ColorStyle)) {
670
- this._tiptapEditor.commands.setMark(style, { color: value });
855
+ } else if (config.propSchema === "string") {
856
+ this._tiptapEditor.commands.setMark(style, { stringValue: value });
857
+ } else {
858
+ throw new UnreachableCaseError(config.propSchema);
671
859
  }
672
860
  }
673
861
  }
@@ -676,7 +864,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
676
864
  * Removes styles from the currently selected content.
677
865
  * @param styles The styles to remove.
678
866
  */
679
- public removeStyles(styles: Styles) {
867
+ public removeStyles(styles: Styles<SSchema>) {
680
868
  this._tiptapEditor.view.focus();
681
869
 
682
870
  for (const style of Object.keys(styles)) {
@@ -688,23 +876,20 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
688
876
  * Toggles styles on the currently selected content.
689
877
  * @param styles The styles to toggle.
690
878
  */
691
- public toggleStyles(styles: Styles) {
692
- const toggleStyles = new Set<ToggledStyle>([
693
- "bold",
694
- "italic",
695
- "underline",
696
- "strike",
697
- "code",
698
- ]);
699
- const colorStyles = new Set<ColorStyle>(["textColor", "backgroundColor"]);
700
-
879
+ public toggleStyles(styles: Styles<SSchema>) {
701
880
  this._tiptapEditor.view.focus();
702
881
 
703
882
  for (const [style, value] of Object.entries(styles)) {
704
- if (toggleStyles.has(style as ToggledStyle)) {
883
+ const config = this.styleSchema[style];
884
+ if (!config) {
885
+ throw new Error(`style ${style} not found in styleSchema`);
886
+ }
887
+ if (config.propSchema === "boolean") {
705
888
  this._tiptapEditor.commands.toggleMark(style);
706
- } else if (colorStyles.has(style as ColorStyle)) {
707
- this._tiptapEditor.commands.toggleMark(style, { color: value });
889
+ } else if (config.propSchema === "string") {
890
+ this._tiptapEditor.commands.toggleMark(style, { stringValue: value });
891
+ } else {
892
+ throw new UnreachableCaseError(config.propSchema);
708
893
  }
709
894
  }
710
895
  }
@@ -789,14 +974,21 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
789
974
  this._tiptapEditor.commands.liftListItem("blockContainer");
790
975
  }
791
976
 
977
+ // TODO: Fix when implementing HTML/Markdown import & export
792
978
  /**
793
979
  * Serializes blocks into an HTML string. To better conform to HTML standards, children of blocks which aren't list
794
980
  * items are un-nested in the output HTML.
795
981
  * @param blocks An array of blocks that should be serialized into HTML.
796
982
  * @returns The blocks, serialized as an HTML string.
797
983
  */
798
- public async blocksToHTML(blocks: Block<BSchema>[]): Promise<string> {
799
- return blocksToHTML(blocks, this._tiptapEditor.schema);
984
+ public async blocksToHTMLLossy(
985
+ blocks = this.topLevelBlocks
986
+ ): Promise<string> {
987
+ const exporter = createExternalHTMLExporter(
988
+ this._tiptapEditor.schema,
989
+ this
990
+ );
991
+ return exporter.exportBlocks(blocks);
800
992
  }
801
993
 
802
994
  /**
@@ -806,8 +998,16 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
806
998
  * @param html The HTML string to parse blocks from.
807
999
  * @returns The blocks parsed from the HTML string.
808
1000
  */
809
- public async HTMLToBlocks(html: string): Promise<Block<BSchema>[]> {
810
- return HTMLToBlocks(html, this.schema, this._tiptapEditor.schema);
1001
+ public async tryParseHTMLToBlocks(
1002
+ html: string
1003
+ ): Promise<Block<BSchema, ISchema, SSchema>[]> {
1004
+ return HTMLToBlocks(
1005
+ html,
1006
+ this.blockSchema,
1007
+ this.inlineContentSchema,
1008
+ this.styleSchema,
1009
+ this._tiptapEditor.schema
1010
+ );
811
1011
  }
812
1012
 
813
1013
  /**
@@ -816,8 +1016,10 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
816
1016
  * @param blocks An array of blocks that should be serialized into Markdown.
817
1017
  * @returns The blocks, serialized as a Markdown string.
818
1018
  */
819
- public async blocksToMarkdown(blocks: Block<BSchema>[]): Promise<string> {
820
- return blocksToMarkdown(blocks, this._tiptapEditor.schema);
1019
+ public async blocksToMarkdownLossy(
1020
+ blocks: Block<BSchema, ISchema, SSchema>[] = this.topLevelBlocks
1021
+ ): Promise<string> {
1022
+ return blocksToMarkdown(blocks, this._tiptapEditor.schema, this);
821
1023
  }
822
1024
 
823
1025
  /**
@@ -827,8 +1029,16 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
827
1029
  * @param markdown The Markdown string to parse blocks from.
828
1030
  * @returns The blocks parsed from the Markdown string.
829
1031
  */
830
- public async markdownToBlocks(markdown: string): Promise<Block<BSchema>[]> {
831
- return markdownToBlocks(markdown, this.schema, this._tiptapEditor.schema);
1032
+ public async tryParseMarkdownToBlocks(
1033
+ markdown: string
1034
+ ): Promise<Block<BSchema, ISchema, SSchema>[]> {
1035
+ return markdownToBlocks(
1036
+ markdown,
1037
+ this.blockSchema,
1038
+ this.inlineContentSchema,
1039
+ this.styleSchema,
1040
+ this._tiptapEditor.schema
1041
+ );
832
1042
  }
833
1043
 
834
1044
  /**