@blocknote/core 0.42.3 → 0.44.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 (200) hide show
  1. package/dist/BlockNoteExtension-BWw0r8Gy.cjs +2 -0
  2. package/dist/BlockNoteExtension-BWw0r8Gy.cjs.map +1 -0
  3. package/dist/BlockNoteExtension-C2X7LW-V.js +25 -0
  4. package/dist/BlockNoteExtension-C2X7LW-V.js.map +1 -0
  5. package/dist/BlockNoteSchema-B4gm-Qco.cjs +2 -0
  6. package/dist/BlockNoteSchema-B4gm-Qco.cjs.map +1 -0
  7. package/dist/BlockNoteSchema-C-l154WP.js +270 -0
  8. package/dist/BlockNoteSchema-C-l154WP.js.map +1 -0
  9. package/dist/EventEmitter-CLwfmbqG.cjs +2 -0
  10. package/dist/EventEmitter-CLwfmbqG.cjs.map +1 -0
  11. package/dist/EventEmitter-CjSwpTbz.js +27 -0
  12. package/dist/EventEmitter-CjSwpTbz.js.map +1 -0
  13. package/dist/ShowSelection-BW37oJ6h.cjs +2 -0
  14. package/dist/ShowSelection-BW37oJ6h.cjs.map +1 -0
  15. package/dist/ShowSelection-Dz-NEase.js +43 -0
  16. package/dist/ShowSelection-Dz-NEase.js.map +1 -0
  17. package/dist/TrailingNode-B_zPMWxw.js +2098 -0
  18. package/dist/TrailingNode-B_zPMWxw.js.map +1 -0
  19. package/dist/TrailingNode-CRHrgOnK.cjs +2 -0
  20. package/dist/TrailingNode-CRHrgOnK.cjs.map +1 -0
  21. package/dist/{blockToNode-DIfPWLH8.js → blockToNode-DBNbhwwC.js} +33 -33
  22. package/dist/blockToNode-DBNbhwwC.js.map +1 -0
  23. package/dist/blockToNode-w7H99R6p.cjs.map +1 -1
  24. package/dist/blocknote.cjs +4 -4
  25. package/dist/blocknote.cjs.map +1 -1
  26. package/dist/blocknote.js +2496 -5686
  27. package/dist/blocknote.js.map +1 -1
  28. package/dist/blocks.cjs +1 -1
  29. package/dist/blocks.js +71 -70
  30. package/dist/blocks.js.map +1 -1
  31. package/dist/comments.cjs +1 -1
  32. package/dist/comments.cjs.map +1 -1
  33. package/dist/comments.js +451 -137
  34. package/dist/comments.js.map +1 -1
  35. package/dist/defaultBlocks-DLJ4Q1_J.cjs +6 -0
  36. package/dist/defaultBlocks-DLJ4Q1_J.cjs.map +1 -0
  37. package/dist/{BlockNoteSchema-Bi-eeHal.js → defaultBlocks-DgA_mtQV.js} +974 -1027
  38. package/dist/defaultBlocks-DgA_mtQV.js.map +1 -0
  39. package/dist/extensions.cjs +2 -0
  40. package/dist/extensions.cjs.map +1 -0
  41. package/dist/extensions.js +57 -0
  42. package/dist/extensions.js.map +1 -0
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/dist/webpack-stats.json +1 -1
  45. package/dist/yjs.js +1 -1
  46. package/package.json +9 -3
  47. package/src/api/nodeConversions/blockToNode.ts +1 -1
  48. package/src/api/nodeConversions/nodeToBlock.ts +1 -1
  49. package/src/blocks/Code/block.ts +4 -4
  50. package/src/blocks/Divider/block.ts +2 -2
  51. package/src/blocks/File/helpers/render/createAddFileButton.ts +7 -5
  52. package/src/blocks/Heading/block.ts +23 -20
  53. package/src/blocks/ListItem/BulletListItem/block.ts +2 -2
  54. package/src/blocks/ListItem/CheckListItem/block.ts +2 -2
  55. package/src/blocks/ListItem/NumberedListItem/block.ts +3 -3
  56. package/src/blocks/ListItem/ToggleListItem/block.ts +2 -2
  57. package/src/blocks/PageBreak/getPageBreakSlashMenuItems.ts +2 -2
  58. package/src/blocks/Paragraph/block.ts +2 -2
  59. package/src/blocks/Quote/block.ts +2 -2
  60. package/src/blocks/Table/block.ts +4 -3
  61. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +2 -1
  62. package/src/comments/extension.ts +353 -0
  63. package/src/comments/index.ts +2 -1
  64. package/src/comments/types.ts +8 -0
  65. package/src/{extensions/Comments → comments}/userstore/UserStore.ts +2 -2
  66. package/src/editor/BlockNoteEditor.test.ts +2 -23
  67. package/src/editor/BlockNoteEditor.ts +60 -453
  68. package/src/editor/BlockNoteExtension.test.ts +103 -0
  69. package/src/editor/BlockNoteExtension.ts +174 -56
  70. package/src/editor/managers/EventManager.ts +64 -35
  71. package/src/editor/managers/ExtensionManager/extensions.ts +214 -0
  72. package/src/editor/managers/ExtensionManager/index.ts +514 -0
  73. package/src/editor/managers/ExtensionManager/symbol.ts +6 -0
  74. package/src/editor/managers/SelectionManager.ts +5 -1
  75. package/src/editor/managers/StateManager.ts +29 -17
  76. package/src/editor/managers/index.ts +1 -5
  77. package/src/extensions/BlockChange/{BlockChangePlugin.ts → BlockChange.ts} +27 -29
  78. package/src/extensions/Collaboration/{ForkYDocPlugin.test.ts → ForkYDoc.test.ts} +6 -5
  79. package/src/extensions/Collaboration/ForkYDoc.ts +158 -0
  80. package/src/extensions/Collaboration/YCursorPlugin.ts +183 -0
  81. package/src/extensions/Collaboration/YSync.ts +16 -0
  82. package/src/extensions/Collaboration/YUndo.ts +12 -0
  83. package/src/extensions/Collaboration/schemaMigration/SchemaMigration.ts +59 -0
  84. package/src/extensions/DropCursor/DropCursor.ts +26 -0
  85. package/src/extensions/FilePanel/FilePanel.ts +41 -0
  86. package/src/extensions/FormattingToolbar/FormattingToolbar.ts +119 -0
  87. package/src/extensions/History/History.ts +11 -0
  88. package/src/extensions/LinkToolbar/LinkToolbar.ts +121 -0
  89. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.ts +74 -0
  90. package/src/extensions/Placeholder/Placeholder.ts +148 -0
  91. package/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.ts → PreviousBlockType.ts} +9 -13
  92. package/src/extensions/ShowSelection/{ShowSelectionPlugin.ts → ShowSelection.ts} +27 -33
  93. package/src/extensions/SideMenu/{SideMenuPlugin.ts → SideMenu.ts} +63 -83
  94. package/src/extensions/SuggestionMenu/{SuggestionPlugin.ts → SuggestionMenu.ts} +71 -77
  95. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +29 -44
  96. package/src/extensions/TableHandles/{TableHandlesPlugin.ts → TableHandles.ts} +416 -437
  97. package/src/extensions/TrailingNode/{TrailingNodeExtension.ts → TrailingNode.ts} +8 -17
  98. package/src/extensions/index.ts +24 -0
  99. package/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.ts +1 -1
  100. package/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.ts +21 -16
  101. package/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.ts +1 -1
  102. package/src/extensions/tiptap-extensions/index.ts +31 -0
  103. package/src/index.ts +1 -13
  104. package/src/schema/blocks/createSpec.ts +14 -11
  105. package/src/schema/blocks/internal.ts +2 -2
  106. package/src/schema/blocks/types.ts +8 -5
  107. package/src/schema/schema.ts +11 -36
  108. package/src/util/topo-sort.ts +46 -0
  109. package/types/src/comments/extension.d.ts +70 -0
  110. package/types/src/comments/index.d.ts +2 -1
  111. package/types/src/comments/types.d.ts +8 -0
  112. package/types/src/{extensions/Comments → comments}/userstore/UserStore.d.ts +2 -2
  113. package/types/src/editor/BlockNoteEditor.d.ts +34 -105
  114. package/types/src/editor/BlockNoteExtension.d.ts +87 -22
  115. package/types/src/editor/managers/EventManager.d.ts +25 -16
  116. package/types/src/editor/managers/ExtensionManager/extensions.d.ts +8 -0
  117. package/types/src/editor/managers/ExtensionManager/index.d.ts +83 -0
  118. package/types/src/editor/managers/ExtensionManager/symbol.d.ts +5 -0
  119. package/types/src/editor/managers/StateManager.d.ts +1 -12
  120. package/types/src/editor/managers/index.d.ts +1 -2
  121. package/types/src/extensions/BlockChange/BlockChange.d.ts +16 -0
  122. package/types/src/extensions/Collaboration/ForkYDoc.d.ts +34 -0
  123. package/types/src/extensions/Collaboration/ForkYDoc.test.d.ts +1 -0
  124. package/types/src/extensions/Collaboration/YCursorPlugin.d.ts +24 -0
  125. package/types/src/extensions/Collaboration/YSync.d.ts +8 -0
  126. package/types/src/extensions/Collaboration/YUndo.d.ts +12 -0
  127. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigration.d.ts +8 -0
  128. package/types/src/extensions/DropCursor/DropCursor.d.ts +5 -0
  129. package/types/src/extensions/FilePanel/FilePanel.d.ts +11 -0
  130. package/types/src/extensions/FormattingToolbar/FormattingToolbar.d.ts +9 -0
  131. package/types/src/extensions/History/History.d.ts +6 -0
  132. package/types/src/extensions/LinkToolbar/LinkToolbar.d.ts +24 -0
  133. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.d.ts +5 -0
  134. package/types/src/extensions/Placeholder/Placeholder.d.ts +6 -0
  135. package/types/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.d.ts → PreviousBlockType.d.ts} +9 -5
  136. package/types/src/extensions/ShowSelection/ShowSelection.d.ts +21 -0
  137. package/types/src/extensions/SideMenu/{SideMenuPlugin.d.ts → SideMenu.d.ts} +11 -15
  138. package/types/src/extensions/SuggestionMenu/SuggestionMenu.d.ts +54 -0
  139. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +1 -1
  140. package/types/src/extensions/TableHandles/{TableHandlesPlugin.d.ts → TableHandles.d.ts} +28 -31
  141. package/types/src/extensions/TrailingNode/TrailingNode.d.ts +8 -0
  142. package/types/src/extensions/index.d.ts +24 -0
  143. package/types/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.d.ts +1 -1
  144. package/types/src/extensions/tiptap-extensions/index.d.ts +11 -0
  145. package/types/src/index.d.ts +1 -13
  146. package/types/src/schema/blocks/createSpec.d.ts +4 -4
  147. package/types/src/schema/blocks/internal.d.ts +2 -2
  148. package/types/src/schema/blocks/types.d.ts +5 -5
  149. package/types/src/util/topo-sort.d.ts +8 -0
  150. package/dist/BlockNoteSchema-Bi-eeHal.js.map +0 -1
  151. package/dist/BlockNoteSchema-DjDaA2C3.cjs +0 -6
  152. package/dist/BlockNoteSchema-DjDaA2C3.cjs.map +0 -1
  153. package/dist/blockToNode-DIfPWLH8.js.map +0 -1
  154. package/src/comments/models/User.ts +0 -8
  155. package/src/editor/BlockNoteExtensions.ts +0 -325
  156. package/src/editor/managers/CollaborationManager.ts +0 -212
  157. package/src/editor/managers/ExtensionManager.ts +0 -130
  158. package/src/extensions/Collaboration/CursorPlugin.ts +0 -189
  159. package/src/extensions/Collaboration/ForkYDocPlugin.ts +0 -192
  160. package/src/extensions/Collaboration/SyncPlugin.ts +0 -18
  161. package/src/extensions/Collaboration/UndoPlugin.ts +0 -18
  162. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +0 -59
  163. package/src/extensions/Comments/CommentsPlugin.ts +0 -392
  164. package/src/extensions/FilePanel/FilePanelPlugin.ts +0 -206
  165. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +0 -363
  166. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +0 -380
  167. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +0 -75
  168. package/src/extensions/Placeholder/PlaceholderPlugin.ts +0 -147
  169. package/types/src/comments/models/User.d.ts +0 -8
  170. package/types/src/editor/BlockNoteExtensions.d.ts +0 -43
  171. package/types/src/editor/managers/CollaborationManager.d.ts +0 -115
  172. package/types/src/editor/managers/ExtensionManager.d.ts +0 -68
  173. package/types/src/extensions/BlockChange/BlockChangePlugin.d.ts +0 -15
  174. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +0 -37
  175. package/types/src/extensions/Collaboration/ForkYDocPlugin.d.ts +0 -41
  176. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +0 -7
  177. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +0 -9
  178. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +0 -7
  179. package/types/src/extensions/Comments/CommentsPlugin.d.ts +0 -66
  180. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +0 -31
  181. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +0 -41
  182. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +0 -42
  183. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +0 -5
  184. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +0 -6
  185. package/types/src/extensions/ShowSelection/ShowSelectionPlugin.d.ts +0 -15
  186. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +0 -31
  187. package/types/src/extensions/TrailingNode/TrailingNodeExtension.d.ts +0 -13
  188. /package/src/{extensions/Comments/CommentMark.ts → comments/mark.ts} +0 -0
  189. /package/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.ts +0 -0
  190. /package/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.ts +0 -0
  191. /package/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.ts +0 -0
  192. /package/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.ts +0 -0
  193. /package/types/src/{extensions/Comments/CommentMark.d.ts → comments/mark.d.ts} +0 -0
  194. /package/types/src/{extensions/Collaboration/ForkYDocPlugin.test.d.ts → editor/BlockNoteExtension.test.d.ts} +0 -0
  195. /package/types/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.d.ts +0 -0
  196. /package/types/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.d.ts +0 -0
  197. /package/types/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.d.ts +0 -0
  198. /package/types/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.d.ts +0 -0
  199. /package/types/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.d.ts +0 -0
  200. /package/types/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.d.ts +0 -0
@@ -1,22 +1,16 @@
1
1
  import {
2
- AnyExtension,
3
2
  createDocument,
4
3
  EditorOptions,
5
- Extension,
6
4
  FocusPosition,
7
5
  getSchema,
8
- InputRule,
9
- Mark,
10
6
  Editor as TiptapEditor,
11
- Node as TipTapNode,
12
7
  } from "@tiptap/core";
13
8
  import { type Command, type Plugin, type Transaction } from "@tiptap/pm/state";
14
- import { dropCursor } from "prosemirror-dropcursor";
15
9
  import { Node, Schema } from "prosemirror-model";
16
10
  import * as Y from "yjs";
17
11
 
18
12
  import type { BlocksChanged } from "../api/getBlocksChangedByTransaction.js";
19
- import { editorHasBlockWithType } from "../blocks/defaultBlockTypeGuards.js";
13
+ import { blockToNode } from "../api/nodeConversions/blockToNode.js";
20
14
  import {
21
15
  Block,
22
16
  BlockNoteSchema,
@@ -25,16 +19,7 @@ import {
25
19
  DefaultStyleSchema,
26
20
  PartialBlock,
27
21
  } from "../blocks/index.js";
28
- import type { ThreadStore, User } from "../comments/index.js";
29
- import type { CommentsPlugin } from "../extensions/Comments/CommentsPlugin.js";
30
- import type { FilePanelProsemirrorPlugin } from "../extensions/FilePanel/FilePanelPlugin.js";
31
- import type { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin.js";
32
- import type { LinkToolbarProsemirrorPlugin } from "../extensions/LinkToolbar/LinkToolbarPlugin.js";
33
- import type { ShowSelectionPlugin } from "../extensions/ShowSelection/ShowSelectionPlugin.js";
34
- import type { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin.js";
35
- import type { SuggestionMenuProseMirrorPlugin } from "../extensions/SuggestionMenu/SuggestionPlugin.js";
36
- import type { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin.js";
37
- import { UniqueID } from "../extensions/UniqueID/UniqueID.js";
22
+ import { UniqueID } from "../extensions/tiptap-extensions/UniqueID/UniqueID.js";
38
23
  import type { Dictionary } from "../i18n/dictionary.js";
39
24
  import { en } from "../i18n/locales/index.js";
40
25
  import type {
@@ -50,16 +35,14 @@ import type {
50
35
  StyleSchema,
51
36
  StyleSpecs,
52
37
  } from "../schema/index.js";
38
+ import "../style.css";
53
39
  import { mergeCSSClasses } from "../util/browser.js";
54
40
  import { EventEmitter } from "../util/EventEmitter.js";
55
41
  import type { NoInfer } from "../util/typescript.js";
56
- import { BlockNoteExtension } from "./BlockNoteExtension.js";
57
- import { getBlockNoteExtensions } from "./BlockNoteExtensions.js";
42
+ import { ExtensionFactoryInstance } from "./BlockNoteExtension.js";
58
43
  import type { TextCursorPosition } from "./cursorPositionTypes.js";
59
44
  import {
60
45
  BlockManager,
61
- CollaborationManager,
62
- type CollaborationOptions,
63
46
  EventManager,
64
47
  ExportManager,
65
48
  ExtensionManager,
@@ -70,36 +53,17 @@ import {
70
53
  import type { Selection } from "./selectionTypes.js";
71
54
  import { transformPasted } from "./transformPasted.js";
72
55
 
73
- import { updateBlockTr } from "../api/blockManipulation/commands/updateBlock/updateBlock.js";
74
- import { getBlockInfoFromTransaction } from "../api/getBlockInfoFromPos.js";
75
- import { blockToNode } from "../api/nodeConversions/blockToNode.js";
76
- import "../style.css";
77
-
78
- /**
79
- * A factory function that returns a BlockNoteExtension
80
- * This is useful so we can create extensions that require an editor instance
81
- * in the constructor
82
- */
83
- export type BlockNoteExtensionFactory = (
84
- editor: BlockNoteEditor<any, any, any>,
85
- ) => BlockNoteExtension;
86
-
87
- /**
88
- * We support Tiptap extensions and BlockNoteExtension based extensions
89
- */
90
- export type SupportedExtension = AnyExtension | BlockNoteExtension;
91
-
92
56
  export type BlockCache<
93
57
  BSchema extends BlockSchema = any,
94
58
  ISchema extends InlineContentSchema = any,
95
59
  SSchema extends StyleSchema = any,
96
60
  > = WeakMap<Node, Block<BSchema, ISchema, SSchema>>;
97
61
 
98
- export type BlockNoteEditorOptions<
62
+ export interface BlockNoteEditorOptions<
99
63
  BSchema extends BlockSchema,
100
64
  ISchema extends InlineContentSchema,
101
65
  SSchema extends StyleSchema,
102
- > = {
66
+ > {
103
67
  /**
104
68
  * Whether changes to blocks (like indentation, creating lists, changing headings) should be animated or not. Defaults to `true`.
105
69
  *
@@ -149,17 +113,6 @@ export type BlockNoteEditorOptions<
149
113
  showCursorLabels?: "always" | "activity";
150
114
  };
151
115
 
152
- /**
153
- * Configuration for the comments feature, requires a `threadStore`.
154
- *
155
- * See [Comments](https://www.blocknotejs.org/docs/features/collaboration/comments) for more info.
156
- * @remarks `CommentsOptions`
157
- */
158
- comments?: {
159
- schema?: BlockNoteSchema<any, any, any>;
160
- threadStore: ThreadStore;
161
- };
162
-
163
116
  /**
164
117
  * Use default BlockNote font and reset the styles of <p> <li> <h1> elements etc., that are used in BlockNote.
165
118
  *
@@ -278,13 +231,6 @@ export type BlockNoteEditorOptions<
278
231
  */
279
232
  resolveFileUrl?: (url: string) => Promise<string>;
280
233
 
281
- /**
282
- * Resolve user information for comments.
283
- *
284
- * See [Comments](https://www.blocknotejs.org/docs/features/collaboration/comments) for more info.
285
- */
286
- resolveUsers?: (userIds: string[]) => Promise<User[]>;
287
-
288
234
  /**
289
235
  * The schema of the editor. The schema defines which Blocks, InlineContent, and Styles are available in the editor.
290
236
  *
@@ -373,30 +319,15 @@ export type BlockNoteEditorOptions<
373
319
  */
374
320
  _tiptapOptions?: Partial<EditorOptions>;
375
321
 
376
- /**
377
- * (experimental) add extra extensions to the editor
378
- *
379
- * @deprecated, should use `extensions` instead
380
- * @internal
381
- */
382
- _extensions?: Record<
383
- string,
384
- | { plugin: Plugin; priority?: number }
385
- | ((editor: BlockNoteEditor<any, any, any>) => {
386
- plugin: Plugin;
387
- priority?: number;
388
- })
389
- >;
390
-
391
322
  /**
392
323
  * Register extensions to the editor.
393
324
  *
394
325
  * See [Extensions](/docs/features/extensions) for more info.
395
326
  *
396
- * @remarks `BlockNoteExtension[]`
327
+ * @remarks `ExtensionFactory[]`
397
328
  */
398
- extensions?: Array<BlockNoteExtension | BlockNoteExtensionFactory>;
399
- };
329
+ extensions?: Array<ExtensionFactoryInstance>;
330
+ }
400
331
 
401
332
  const blockNoteTipTapOptions = {
402
333
  enableInputRules: true,
@@ -416,11 +347,6 @@ export class BlockNoteEditor<
416
347
  */
417
348
  public readonly pmSchema: Schema;
418
349
 
419
- /**
420
- * extensions that are added to the editor, can be tiptap extensions or prosemirror plugins
421
- */
422
- public extensions: Record<string, SupportedExtension> = {};
423
-
424
350
  public readonly _tiptapEditor: TiptapEditor & {
425
351
  contentComponent: any;
426
352
  };
@@ -453,56 +379,6 @@ export class BlockNoteEditor<
453
379
  public readonly inlineContentImplementations: InlineContentSpecs;
454
380
  public readonly styleImplementations: StyleSpecs;
455
381
 
456
- public get formattingToolbar(): FormattingToolbarProsemirrorPlugin {
457
- return this._extensionManager.formattingToolbar;
458
- }
459
-
460
- public get linkToolbar(): LinkToolbarProsemirrorPlugin<
461
- BSchema,
462
- ISchema,
463
- SSchema
464
- > {
465
- return this._extensionManager.linkToolbar;
466
- }
467
-
468
- public get sideMenu(): SideMenuProsemirrorPlugin<BSchema, ISchema, SSchema> {
469
- return this._extensionManager.sideMenu;
470
- }
471
-
472
- public get suggestionMenus(): SuggestionMenuProseMirrorPlugin<
473
- BSchema,
474
- ISchema,
475
- SSchema
476
- > {
477
- return this._extensionManager.suggestionMenus;
478
- }
479
-
480
- public get filePanel():
481
- | FilePanelProsemirrorPlugin<ISchema, SSchema>
482
- | undefined {
483
- return this._extensionManager.filePanel;
484
- }
485
-
486
- public get tableHandles():
487
- | TableHandlesProsemirrorPlugin<ISchema, SSchema>
488
- | undefined {
489
- return this._extensionManager.tableHandles;
490
- }
491
-
492
- public get comments(): CommentsPlugin | undefined {
493
- return this._collaborationManager?.comments;
494
- }
495
-
496
- public get showSelectionPlugin(): ShowSelectionPlugin {
497
- return this._extensionManager.showSelectionPlugin;
498
- }
499
-
500
- /**
501
- * The plugin for forking a document, only defined if in collaboration mode
502
- */
503
- public get forkYDocPlugin() {
504
- return this._collaborationManager?.forkYDocPlugin;
505
- }
506
382
  /**
507
383
  * The `uploadFile` method is what the editor uses when files need to be uploaded (for example when selecting an image to upload).
508
384
  * This method should set when creating the editor as this is application-specific.
@@ -520,7 +396,6 @@ export class BlockNoteEditor<
520
396
  private onUploadEndCallbacks: ((blockId?: string) => void)[] = [];
521
397
 
522
398
  public readonly resolveFileUrl?: (url: string) => Promise<string>;
523
- public readonly resolveUsers?: (userIds: string[]) => Promise<User[]>;
524
399
  /**
525
400
  * Editor settings
526
401
  */
@@ -554,30 +429,6 @@ export class BlockNoteEditor<
554
429
  >,
555
430
  ) {
556
431
  super();
557
- const anyOpts = options as any;
558
- if (anyOpts.onEditorContentChange) {
559
- throw new Error(
560
- "onEditorContentChange initialization option is deprecated, use <BlockNoteView onChange={...} />, the useEditorChange(...) hook, or editor.onChange(...)",
561
- );
562
- }
563
-
564
- if (anyOpts.onTextCursorPositionChange) {
565
- throw new Error(
566
- "onTextCursorPositionChange initialization option is deprecated, use <BlockNoteView onSelectionChange={...} />, the useEditorSelectionChange(...) hook, or editor.onSelectionChange(...)",
567
- );
568
- }
569
-
570
- if (anyOpts.onEditorReady) {
571
- throw new Error(
572
- "onEditorReady is deprecated. Editor is immediately ready for use after creation.",
573
- );
574
- }
575
-
576
- if (anyOpts.editable) {
577
- throw new Error(
578
- "editable initialization option is deprecated, use <BlockNoteView editable={true/false} />, or alternatively editor.isEditable = true/false",
579
- );
580
- }
581
432
 
582
433
  this.dictionary = options.dictionary || en;
583
434
  this.settings = {
@@ -606,111 +457,13 @@ export class BlockNoteEditor<
606
457
  },
607
458
  };
608
459
 
609
- // Initialize CollaborationManager if collaboration is enabled or if comments are configured
610
- if (newOptions.collaboration || newOptions.comments) {
611
- const collaborationOptions: CollaborationOptions = {
612
- // Use collaboration options if available, otherwise provide defaults
613
- fragment: newOptions.collaboration?.fragment || new Y.XmlFragment(),
614
- user: newOptions.collaboration?.user || {
615
- name: "User",
616
- color: "#FF0000",
617
- },
618
- provider: newOptions.collaboration?.provider || null,
619
- renderCursor: newOptions.collaboration?.renderCursor,
620
- showCursorLabels: newOptions.collaboration?.showCursorLabels,
621
- comments: newOptions.comments,
622
- resolveUsers: newOptions.resolveUsers,
623
- };
624
- this._collaborationManager = new CollaborationManager(
625
- this as any,
626
- collaborationOptions,
627
- );
628
- } else {
629
- this._collaborationManager = undefined;
630
- }
631
-
632
- if (newOptions.comments && !newOptions.resolveUsers) {
633
- throw new Error("resolveUsers is required when using comments");
634
- }
635
-
636
460
  // @ts-ignore
637
461
  this.schema = newOptions.schema;
638
462
  this.blockImplementations = newOptions.schema.blockSpecs;
639
463
  this.inlineContentImplementations = newOptions.schema.inlineContentSpecs;
640
464
  this.styleImplementations = newOptions.schema.styleSpecs;
641
465
 
642
- this.extensions = {
643
- ...getBlockNoteExtensions({
644
- editor: this,
645
- domAttributes: newOptions.domAttributes || {},
646
- blockSpecs: this.schema.blockSpecs,
647
- styleSpecs: this.schema.styleSpecs,
648
- inlineContentSpecs: this.schema.inlineContentSpecs,
649
- collaboration: newOptions.collaboration,
650
- trailingBlock: newOptions.trailingBlock,
651
- disableExtensions: newOptions.disableExtensions,
652
- setIdAttribute: newOptions.setIdAttribute,
653
- animations: newOptions.animations ?? true,
654
- tableHandles: editorHasBlockWithType(this, "table"),
655
- dropCursor: this.options.dropCursor ?? dropCursor,
656
- placeholders: newOptions.placeholders,
657
- tabBehavior: newOptions.tabBehavior,
658
- pasteHandler: newOptions.pasteHandler,
659
- }),
660
- ...this._collaborationManager?.initExtensions(),
661
- } as any;
662
-
663
- // add extensions from _tiptapOptions
664
- (newOptions._tiptapOptions?.extensions || []).forEach((ext) => {
665
- this.extensions[ext.name] = ext;
666
- });
667
-
668
- // add extensions from options
669
- for (let ext of newOptions.extensions || []) {
670
- if (typeof ext === "function") {
671
- // factory
672
- ext = ext(this);
673
- }
674
- const key = (ext as any).key ?? (ext.constructor as any).key();
675
- if (!key) {
676
- throw new Error(
677
- `Extension ${ext.constructor.name} does not have a key method`,
678
- );
679
- }
680
- if (this.extensions[key]) {
681
- throw new Error(
682
- `Extension ${ext.constructor.name} already exists with key ${key}`,
683
- );
684
- }
685
- this.extensions[key] = ext;
686
- }
687
-
688
- // (when passed in via the deprecated `_extensions` option)
689
- Object.entries(newOptions._extensions || {}).forEach(([key, ext]) => {
690
- // eslint-disable-next-line @typescript-eslint/no-this-alias
691
- const editor = this;
692
-
693
- const instance = typeof ext === "function" ? ext(editor) : ext;
694
- if (!("plugin" in instance)) {
695
- // Assume it is an Extension/Mark/Node
696
- this.extensions[key] = instance;
697
- return;
698
- }
699
-
700
- this.extensions[key] = new (class extends BlockNoteExtension {
701
- public static key() {
702
- return key;
703
- }
704
- constructor() {
705
- super();
706
- this.addProsemirrorPlugin(instance.plugin);
707
- }
708
- public get priority() {
709
- return instance.priority;
710
- }
711
- })();
712
- });
713
-
466
+ // TODO this should just be an extension
714
467
  if (newOptions.uploadFile) {
715
468
  const uploadFile = newOptions.uploadFile;
716
469
  this.uploadFile = async (file, blockId) => {
@@ -729,9 +482,14 @@ export class BlockNoteEditor<
729
482
 
730
483
  this.resolveFileUrl = newOptions.resolveFileUrl;
731
484
 
485
+ this._eventManager = new EventManager(this as any);
486
+ this._extensionManager = new ExtensionManager(this, newOptions);
487
+
488
+ const tiptapExtensions = this._extensionManager.getTiptapExtensions();
489
+
732
490
  const collaborationEnabled =
733
- "ySyncPlugin" in this.extensions ||
734
- "liveblocksExtension" in this.extensions;
491
+ this._extensionManager.hasExtension("ySync") ||
492
+ this._extensionManager.hasExtension("liveblocksExtension");
735
493
 
736
494
  if (collaborationEnabled && newOptions.initialContent) {
737
495
  // eslint-disable-next-line no-console
@@ -740,105 +498,6 @@ export class BlockNoteEditor<
740
498
  );
741
499
  }
742
500
 
743
- const blockExtensions = Object.fromEntries(
744
- Object.values(this.schema.blockSpecs)
745
- .map((block) => (block as any).extensions as any)
746
- .filter((ext) => ext !== undefined)
747
- .flat()
748
- .map((ext) => [ext.key ?? ext.constructor.key(), ext]),
749
- );
750
- const tiptapExtensions = [
751
- ...Object.entries({ ...this.extensions, ...blockExtensions }).map(
752
- ([key, ext]) => {
753
- if (
754
- ext instanceof Extension ||
755
- ext instanceof TipTapNode ||
756
- ext instanceof Mark
757
- ) {
758
- // tiptap extension
759
- return ext;
760
- }
761
-
762
- if (ext instanceof BlockNoteExtension) {
763
- if (
764
- !ext.plugins.length &&
765
- !ext.keyboardShortcuts &&
766
- !ext.inputRules &&
767
- !ext.tiptapExtensions
768
- ) {
769
- return undefined;
770
- }
771
- // "blocknote" extensions (prosemirror plugins)
772
- return Extension.create({
773
- name: key,
774
- priority: ext.priority,
775
- addProseMirrorPlugins: () => ext.plugins,
776
- addExtensions: () => ext.tiptapExtensions || [],
777
- // TODO maybe collect all input rules from all extensions into one plugin
778
- // TODO consider using the prosemirror-inputrules package instead
779
- addInputRules: ext.inputRules
780
- ? () =>
781
- ext.inputRules!.map(
782
- (inputRule) =>
783
- new InputRule({
784
- find: inputRule.find,
785
- handler: ({ range, match, state }) => {
786
- const replaceWith = inputRule.replace({
787
- match,
788
- range,
789
- editor: this,
790
- });
791
- if (replaceWith) {
792
- const cursorPosition =
793
- this.getTextCursorPosition();
794
-
795
- if (
796
- this.schema.blockSchema[
797
- cursorPosition.block.type
798
- ].content !== "inline"
799
- ) {
800
- return undefined;
801
- }
802
-
803
- const blockInfo = getBlockInfoFromTransaction(
804
- state.tr,
805
- );
806
- const tr = state.tr.deleteRange(
807
- range.from,
808
- range.to,
809
- );
810
-
811
- updateBlockTr(
812
- tr,
813
- blockInfo.bnBlock.beforePos,
814
- replaceWith,
815
- );
816
- return undefined;
817
- }
818
- return null;
819
- },
820
- }),
821
- )
822
- : undefined,
823
- addKeyboardShortcuts: ext.keyboardShortcuts
824
- ? () => {
825
- return Object.fromEntries(
826
- Object.entries(ext.keyboardShortcuts!).map(
827
- ([key, value]) => [
828
- key,
829
- () => value({ editor: this as any }),
830
- ],
831
- ),
832
- );
833
- }
834
- : undefined,
835
- });
836
- }
837
-
838
- return undefined;
839
- },
840
- ),
841
- ].filter((ext): ext is Extension => ext !== undefined);
842
501
  const tiptapOptions: EditorOptions = {
843
502
  ...blockNoteTipTapOptions,
844
503
  ...newOptions._tiptapOptions,
@@ -941,19 +600,9 @@ export class BlockNoteEditor<
941
600
  // Initialize managers
942
601
  this._blockManager = new BlockManager(this as any);
943
602
 
944
- this._eventManager = new EventManager(this as any);
945
603
  this._exportManager = new ExportManager(this as any);
946
- this._extensionManager = new ExtensionManager(this as any);
947
604
  this._selectionManager = new SelectionManager(this as any);
948
- this._stateManager = new StateManager(
949
- this as any,
950
- collaborationEnabled
951
- ? {
952
- undo: this._collaborationManager?.getUndoCommand(),
953
- redo: this._collaborationManager?.getRedoCommand(),
954
- }
955
- : undefined,
956
- );
605
+ this._stateManager = new StateManager(this as any);
957
606
  this._styleManager = new StyleManager(this as any);
958
607
 
959
608
  this.emit("create");
@@ -961,14 +610,20 @@ export class BlockNoteEditor<
961
610
 
962
611
  // Manager instances
963
612
  private readonly _blockManager: BlockManager<any, any, any>;
964
- private readonly _collaborationManager?: CollaborationManager;
965
- private readonly _eventManager: EventManager<any>;
613
+ private readonly _eventManager: EventManager<any, any, any>;
966
614
  private readonly _exportManager: ExportManager<any, any, any>;
967
615
  private readonly _extensionManager: ExtensionManager;
968
616
  private readonly _selectionManager: SelectionManager<any, any, any>;
969
617
  private readonly _stateManager: StateManager;
970
618
  private readonly _styleManager: StyleManager<any, any, any>;
971
619
 
620
+ /**
621
+ * BlockNote extensions that are added to the editor, keyed by the extension key
622
+ */
623
+ public get extensions() {
624
+ return this._extensionManager.getExtensions();
625
+ }
626
+
972
627
  /**
973
628
  * Execute a prosemirror command. This is mostly for backwards compatibility with older code.
974
629
  *
@@ -1032,21 +687,26 @@ export class BlockNoteEditor<
1032
687
  return this._stateManager.transact(callback);
1033
688
  }
1034
689
 
1035
- // TO DISCUSS
1036
690
  /**
1037
- * Shorthand to get a typed extension from the editor, by
1038
- * just passing in the extension class.
1039
- *
1040
- * @param ext - The extension class to get
1041
- * @param key - optional, the key of the extension in the extensions object (defaults to the extension name)
1042
- * @returns The extension instance
691
+ * Remove extension(s) from the editor
1043
692
  */
1044
- public extension<T extends BlockNoteExtension>(
1045
- ext: { new (...args: any[]): T } & typeof BlockNoteExtension,
1046
- key = ext.key(),
1047
- ): T {
1048
- return this._extensionManager.extension(ext, key);
1049
- }
693
+ public unregisterExtension: ExtensionManager["unregisterExtension"] = (
694
+ ...args: Parameters<ExtensionManager["unregisterExtension"]>
695
+ ) => this._extensionManager.unregisterExtension(...args);
696
+
697
+ /**
698
+ * Register extension(s) to the editor
699
+ */
700
+ public registerExtension: ExtensionManager["registerExtension"] = (
701
+ ...args: Parameters<ExtensionManager["registerExtension"]>
702
+ ) => this._extensionManager.registerExtension(...args) as any;
703
+
704
+ /**
705
+ * Get an extension from the editor
706
+ */
707
+ public getExtension: ExtensionManager["getExtension"] = ((
708
+ ...args: Parameters<ExtensionManager["getExtension"]>
709
+ ) => this._extensionManager.getExtension(...args)) as any;
1050
710
 
1051
711
  /**
1052
712
  * Mount the editor to a DOM element.
@@ -1099,6 +759,9 @@ export class BlockNoteEditor<
1099
759
  return !this._tiptapEditor.isInitialized;
1100
760
  }
1101
761
 
762
+ /**
763
+ * Focus on the editor
764
+ */
1102
765
  public focus() {
1103
766
  if (this.headless) {
1104
767
  return;
@@ -1106,6 +769,9 @@ export class BlockNoteEditor<
1106
769
  this.prosemirrorView.focus();
1107
770
  }
1108
771
 
772
+ /**
773
+ * Blur the editor
774
+ */
1109
775
  public blur() {
1110
776
  if (this.headless) {
1111
777
  return;
@@ -1113,6 +779,7 @@ export class BlockNoteEditor<
1113
779
  this.prosemirrorView.dom.blur();
1114
780
  }
1115
781
 
782
+ // TODO move to extension
1116
783
  public onUploadStart(callback: (blockId?: string) => void) {
1117
784
  this.onUploadStartCallbacks.push(callback);
1118
785
 
@@ -1367,14 +1034,14 @@ export class BlockNoteEditor<
1367
1034
  /**
1368
1035
  * Undo the last action.
1369
1036
  */
1370
- public undo() {
1037
+ public undo(): boolean {
1371
1038
  return this._stateManager.undo();
1372
1039
  }
1373
1040
 
1374
1041
  /**
1375
1042
  * Redo the last action.
1376
1043
  */
1377
- public redo() {
1044
+ public redo(): boolean {
1378
1045
  return this._stateManager.redo();
1379
1046
  }
1380
1047
 
@@ -1517,6 +1184,7 @@ export class BlockNoteEditor<
1517
1184
  ): string {
1518
1185
  return this._exportManager.blocksToFullHTML(blocks);
1519
1186
  }
1187
+
1520
1188
  /**
1521
1189
  * Parses blocks from an HTML string. Tries to create `Block` objects out of any HTML block-level elements, and
1522
1190
  * `InlineNode` objects from any HTML inline elements, though not all element types are recognized. If BlockNote
@@ -1555,19 +1223,6 @@ export class BlockNoteEditor<
1555
1223
  return this._exportManager.tryParseMarkdownToBlocks(markdown);
1556
1224
  }
1557
1225
 
1558
- /**
1559
- * Updates the user info for the current user that's shown to other collaborators.
1560
- */
1561
- public updateCollaborationUserInfo(user: { name: string; color: string }) {
1562
- if (!this._collaborationManager) {
1563
- throw new Error(
1564
- "Cannot update collaboration user info when collaboration is disabled.",
1565
- );
1566
- }
1567
-
1568
- this._collaborationManager.updateUserInfo(user);
1569
- }
1570
-
1571
1226
  /**
1572
1227
  * A callback function that runs whenever the editor's contents change.
1573
1228
  *
@@ -1584,8 +1239,13 @@ export class BlockNoteEditor<
1584
1239
  getChanges(): BlocksChanged<BSchema, ISchema, SSchema>;
1585
1240
  },
1586
1241
  ) => void,
1242
+ /**
1243
+ * If true, the callback will be triggered when the changes are caused by a remote user
1244
+ * @default true
1245
+ */
1246
+ includeUpdatesFromRemote?: boolean,
1587
1247
  ) {
1588
- return this._eventManager.onChange(callback);
1248
+ return this._eventManager.onChange(callback, includeUpdatesFromRemote);
1589
1249
  }
1590
1250
 
1591
1251
  /**
@@ -1604,22 +1264,6 @@ export class BlockNoteEditor<
1604
1264
  );
1605
1265
  }
1606
1266
 
1607
- /**
1608
- * A callback function that runs when the editor has been initialized.
1609
- *
1610
- * This can be useful for plugins to initialize themselves after the editor has been initialized.
1611
- *
1612
- * @param callback The callback to execute.
1613
- * @returns A function to remove the callback.
1614
- */
1615
- public onCreate(callback: () => void) {
1616
- this.on("create", callback);
1617
-
1618
- return () => {
1619
- this.off("create", callback);
1620
- };
1621
- }
1622
-
1623
1267
  /**
1624
1268
  * A callback function that runs when the editor has been mounted.
1625
1269
  *
@@ -1672,43 +1316,6 @@ export class BlockNoteEditor<
1672
1316
  );
1673
1317
  }
1674
1318
 
1675
- public openSuggestionMenu(
1676
- triggerCharacter: string,
1677
- pluginState?: {
1678
- deleteTriggerCharacter?: boolean;
1679
- ignoreQueryLength?: boolean;
1680
- },
1681
- ) {
1682
- if (!this.prosemirrorView || this.headless) {
1683
- return;
1684
- }
1685
-
1686
- this.focus();
1687
- this.transact((tr) => {
1688
- if (pluginState?.deleteTriggerCharacter) {
1689
- tr.insertText(triggerCharacter);
1690
- }
1691
- tr.scrollIntoView().setMeta(this.suggestionMenus.plugins[0], {
1692
- triggerCharacter: triggerCharacter,
1693
- deleteTriggerCharacter: pluginState?.deleteTriggerCharacter || false,
1694
- ignoreQueryLength: pluginState?.ignoreQueryLength || false,
1695
- });
1696
- });
1697
- }
1698
-
1699
- // `forceSelectionVisible` determines whether the editor selection is shows
1700
- // even when the editor is not focused. This is useful for e.g. creating new
1701
- // links, so the user still sees the affected content when an input field is
1702
- // focused.
1703
- // TODO: Reconsider naming?
1704
- public getForceSelectionVisible() {
1705
- return this.showSelectionPlugin.getEnabled();
1706
- }
1707
-
1708
- public setForceSelectionVisible(forceSelectionVisible: boolean) {
1709
- this.showSelectionPlugin.setEnabled(forceSelectionVisible);
1710
- }
1711
-
1712
1319
  /**
1713
1320
  * Paste HTML into the editor. Defaults to converting HTML to BlockNote HTML.
1714
1321
  * @param html The HTML to paste.