@blocknote/core 0.40.0 → 0.41.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.
- package/dist/BlockNoteSchema-COA0fsXW.cjs +11 -0
- package/dist/BlockNoteSchema-COA0fsXW.cjs.map +1 -0
- package/dist/{BlockNoteSchema-oR047ACf.js → BlockNoteSchema-CYRHak18.js} +681 -581
- package/dist/BlockNoteSchema-CYRHak18.js.map +1 -0
- package/dist/blocknote.cjs +4 -4
- package/dist/blocknote.cjs.map +1 -1
- package/dist/blocknote.js +3663 -2817
- package/dist/blocknote.js.map +1 -1
- package/dist/blocks.cjs +1 -1
- package/dist/blocks.js +51 -49
- package/dist/en-Cl87Uuyf.cjs +2 -0
- package/dist/en-Cl87Uuyf.cjs.map +1 -0
- package/dist/{en-Bq3Es3Np.js → en-njEqD7AG.js} +9 -3
- package/dist/en-njEqD7AG.js.map +1 -0
- package/dist/locales.cjs +1 -1
- package/dist/locales.cjs.map +1 -1
- package/dist/locales.js +122 -2
- package/dist/locales.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +4 -3
- package/src/api/exporters/html/externalHTMLExporter.ts +1 -1
- package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +2 -1
- package/src/api/exporters/markdown/markdownExporter.ts +3 -1
- package/src/api/exporters/markdown/util/convertVideoToMarkdownRehypePlugin.ts +19 -0
- package/src/api/parsers/markdown/parseMarkdown.ts +31 -0
- package/src/blocks/Code/block.ts +14 -14
- package/src/blocks/Divider/block.ts +49 -0
- package/src/blocks/ListItem/BulletListItem/block.ts +9 -1
- package/src/blocks/ListItem/CheckListItem/block.ts +1 -0
- package/src/blocks/ListItem/NumberedListItem/block.ts +9 -1
- package/src/blocks/Table/block.ts +56 -1
- package/src/blocks/ToggleWrapper/createToggleWrapper.ts +1 -1
- package/src/blocks/defaultBlocks.ts +16 -14
- package/src/blocks/index.ts +1 -0
- package/src/editor/Block.css +14 -20
- package/src/editor/BlockNoteEditor.test.ts +40 -0
- package/src/editor/BlockNoteEditor.ts +248 -465
- package/src/editor/BlockNoteExtensions.ts +3 -1
- package/src/editor/managers/BlockManager.ts +251 -0
- package/src/editor/managers/CollaborationManager.ts +212 -0
- package/src/editor/managers/EventManager.ts +134 -0
- package/src/editor/managers/ExportManager.ts +137 -0
- package/src/editor/managers/ExtensionManager.ts +130 -0
- package/src/editor/managers/SelectionManager.ts +114 -0
- package/src/editor/managers/StateManager.ts +238 -0
- package/src/editor/managers/StyleManager.ts +182 -0
- package/src/editor/managers/index.ts +11 -0
- package/src/extensions/Comments/CommentsPlugin.ts +7 -4
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +10 -0
- package/src/i18n/locales/ar.ts +6 -0
- package/src/i18n/locales/de.ts +6 -0
- package/src/i18n/locales/en.ts +6 -0
- package/src/i18n/locales/es.ts +6 -0
- package/src/i18n/locales/fr.ts +6 -0
- package/src/i18n/locales/he.ts +6 -0
- package/src/i18n/locales/hr.ts +6 -0
- package/src/i18n/locales/is.ts +6 -0
- package/src/i18n/locales/it.ts +6 -0
- package/src/i18n/locales/ja.ts +6 -0
- package/src/i18n/locales/ko.ts +6 -0
- package/src/i18n/locales/nl.ts +6 -0
- package/src/i18n/locales/no.ts +6 -0
- package/src/i18n/locales/pl.ts +6 -0
- package/src/i18n/locales/pt.ts +6 -0
- package/src/i18n/locales/ru.ts +6 -0
- package/src/i18n/locales/sk.ts +6 -0
- package/src/i18n/locales/uk.ts +6 -0
- package/src/i18n/locales/vi.ts +6 -0
- package/src/i18n/locales/zh-tw.ts +6 -0
- package/src/i18n/locales/zh.ts +6 -0
- package/src/schema/blocks/createSpec.ts +1 -0
- package/src/util/string.ts +21 -0
- package/types/src/api/exporters/markdown/util/convertVideoToMarkdownRehypePlugin.d.ts +2 -0
- package/types/src/blocks/Divider/block.d.ts +3 -0
- package/types/src/blocks/Heading/block.d.ts +3 -3
- package/types/src/blocks/defaultBlocks.d.ts +2 -1
- package/types/src/blocks/index.d.ts +1 -0
- package/types/src/editor/BlockNoteEditor.d.ts +68 -47
- package/types/src/editor/BlockNoteExtensions.d.ts +2 -1
- package/types/src/editor/managers/BlockManager.d.ts +114 -0
- package/types/src/editor/managers/CollaborationManager.d.ts +115 -0
- package/types/src/editor/managers/EventManager.d.ts +58 -0
- package/types/src/editor/managers/ExportManager.d.ts +64 -0
- package/types/src/editor/managers/ExtensionManager.d.ts +68 -0
- package/types/src/editor/managers/SelectionManager.d.ts +54 -0
- package/types/src/editor/managers/StateManager.d.ts +115 -0
- package/types/src/editor/managers/StyleManager.d.ts +48 -0
- package/types/src/editor/managers/index.d.ts +8 -0
- package/types/src/extensions/Comments/CommentsPlugin.d.ts +4 -3
- package/types/src/i18n/locales/en.d.ts +6 -0
- package/types/src/i18n/locales/sk.d.ts +6 -0
- package/types/src/util/string.d.ts +1 -0
- package/dist/BlockNoteSchema-DmZ6UQfY.cjs +0 -11
- package/dist/BlockNoteSchema-DmZ6UQfY.cjs.map +0 -1
- package/dist/BlockNoteSchema-oR047ACf.js.map +0 -1
- package/dist/en-Bq3Es3Np.js.map +0 -1
- package/dist/en-D3B48eJ7.cjs +0 -2
- package/dist/en-D3B48eJ7.cjs.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/src/api/exporters/markdown/{removeUnderlinesRehypePlugin.ts → util/removeUnderlinesRehypePlugin.ts} +0 -0
- /package/types/src/api/exporters/markdown/{removeUnderlinesRehypePlugin.d.ts → util/removeUnderlinesRehypePlugin.d.ts} +0 -0
|
@@ -6,91 +6,38 @@ import {
|
|
|
6
6
|
FocusPosition,
|
|
7
7
|
getSchema,
|
|
8
8
|
InputRule,
|
|
9
|
-
isNodeSelection,
|
|
10
9
|
Mark,
|
|
11
|
-
posToDOMRect,
|
|
12
10
|
Editor as TiptapEditor,
|
|
13
11
|
Node as TipTapNode,
|
|
14
12
|
} from "@tiptap/core";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
TextSelection,
|
|
18
|
-
type Command,
|
|
19
|
-
type Plugin,
|
|
20
|
-
type Transaction,
|
|
21
|
-
} from "@tiptap/pm/state";
|
|
13
|
+
import { type Command, type Plugin, type Transaction } from "@tiptap/pm/state";
|
|
22
14
|
import { dropCursor } from "prosemirror-dropcursor";
|
|
23
15
|
import { Node, Schema } from "prosemirror-model";
|
|
24
|
-
import { redoCommand, undoCommand, ySyncPluginKey } from "y-prosemirror";
|
|
25
16
|
import * as Y from "yjs";
|
|
26
17
|
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
moveBlocksDown,
|
|
30
|
-
moveBlocksUp,
|
|
31
|
-
} from "../api/blockManipulation/commands/moveBlocks/moveBlocks.js";
|
|
32
|
-
import {
|
|
33
|
-
canNestBlock,
|
|
34
|
-
canUnnestBlock,
|
|
35
|
-
nestBlock,
|
|
36
|
-
unnestBlock,
|
|
37
|
-
} from "../api/blockManipulation/commands/nestBlock/nestBlock.js";
|
|
38
|
-
import { removeAndInsertBlocks } from "../api/blockManipulation/commands/replaceBlocks/replaceBlocks.js";
|
|
39
|
-
import {
|
|
40
|
-
updateBlock,
|
|
41
|
-
updateBlockTr,
|
|
42
|
-
} from "../api/blockManipulation/commands/updateBlock/updateBlock.js";
|
|
43
|
-
import {
|
|
44
|
-
getBlock,
|
|
45
|
-
getNextBlock,
|
|
46
|
-
getParentBlock,
|
|
47
|
-
getPrevBlock,
|
|
48
|
-
} from "../api/blockManipulation/getBlock/getBlock.js";
|
|
49
|
-
import { insertContentAt } from "../api/blockManipulation/insertContentAt.js";
|
|
50
|
-
import {
|
|
51
|
-
getSelection,
|
|
52
|
-
getSelectionCutBlocks,
|
|
53
|
-
setSelection,
|
|
54
|
-
} from "../api/blockManipulation/selections/selection.js";
|
|
55
|
-
import {
|
|
56
|
-
getTextCursorPosition,
|
|
57
|
-
setTextCursorPosition,
|
|
58
|
-
} from "../api/blockManipulation/selections/textCursorPosition.js";
|
|
59
|
-
import { createExternalHTMLExporter } from "../api/exporters/html/externalHTMLExporter.js";
|
|
60
|
-
import { createInternalHTMLSerializer } from "../api/exporters/html/internalHTMLSerializer.js";
|
|
61
|
-
import { blocksToMarkdown } from "../api/exporters/markdown/markdownExporter.js";
|
|
62
|
-
import { getBlockInfoFromTransaction } from "../api/getBlockInfoFromPos.js";
|
|
63
|
-
import {
|
|
64
|
-
BlocksChanged,
|
|
65
|
-
getBlocksChangedByTransaction,
|
|
66
|
-
} from "../api/getBlocksChangedByTransaction.js";
|
|
67
|
-
import {
|
|
68
|
-
blockToNode,
|
|
69
|
-
inlineContentToNodes,
|
|
70
|
-
} from "../api/nodeConversions/blockToNode.js";
|
|
71
|
-
import { docToBlocks } from "../api/nodeConversions/nodeToBlock.js";
|
|
72
|
-
import { HTMLToBlocks } from "../api/parsers/html/parseHTML.js";
|
|
73
|
-
import {
|
|
74
|
-
markdownToBlocks,
|
|
75
|
-
markdownToHTML,
|
|
76
|
-
} from "../api/parsers/markdown/parseMarkdown.js";
|
|
18
|
+
import type { BlocksChanged } from "../api/getBlocksChangedByTransaction.js";
|
|
77
19
|
import { editorHasBlockWithType } from "../blocks/defaultBlockTypeGuards.js";
|
|
20
|
+
import {
|
|
21
|
+
Block,
|
|
22
|
+
BlockNoteSchema,
|
|
23
|
+
DefaultBlockSchema,
|
|
24
|
+
DefaultInlineContentSchema,
|
|
25
|
+
DefaultStyleSchema,
|
|
26
|
+
PartialBlock,
|
|
27
|
+
} from "../blocks/index.js";
|
|
78
28
|
import type { ThreadStore, User } from "../comments/index.js";
|
|
79
|
-
import { BlockChangePlugin } from "../extensions/BlockChange/BlockChangePlugin.js";
|
|
80
|
-
import type { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js";
|
|
81
|
-
import type { ForkYDocPlugin } from "../extensions/Collaboration/ForkYDocPlugin.js";
|
|
82
29
|
import type { CommentsPlugin } from "../extensions/Comments/CommentsPlugin.js";
|
|
83
|
-
import { FilePanelProsemirrorPlugin } from "../extensions/FilePanel/FilePanelPlugin.js";
|
|
84
|
-
import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin.js";
|
|
85
|
-
import { LinkToolbarProsemirrorPlugin } from "../extensions/LinkToolbar/LinkToolbarPlugin.js";
|
|
86
|
-
import { ShowSelectionPlugin } from "../extensions/ShowSelection/ShowSelectionPlugin.js";
|
|
87
|
-
import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin.js";
|
|
88
|
-
import { SuggestionMenuProseMirrorPlugin } from "../extensions/SuggestionMenu/SuggestionPlugin.js";
|
|
89
|
-
import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin.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";
|
|
90
37
|
import { UniqueID } from "../extensions/UniqueID/UniqueID.js";
|
|
91
|
-
import { Dictionary } from "../i18n/dictionary.js";
|
|
38
|
+
import type { Dictionary } from "../i18n/dictionary.js";
|
|
92
39
|
import { en } from "../i18n/locales/index.js";
|
|
93
|
-
import {
|
|
40
|
+
import type {
|
|
94
41
|
BlockIdentifier,
|
|
95
42
|
BlockNoteDOMAttributes,
|
|
96
43
|
BlockSchema,
|
|
@@ -103,26 +50,29 @@ import {
|
|
|
103
50
|
StyleSchema,
|
|
104
51
|
StyleSpecs,
|
|
105
52
|
} from "../schema/index.js";
|
|
106
|
-
import "../style.css";
|
|
107
53
|
import { mergeCSSClasses } from "../util/browser.js";
|
|
108
54
|
import { EventEmitter } from "../util/EventEmitter.js";
|
|
109
|
-
import { NoInfer
|
|
55
|
+
import type { NoInfer } from "../util/typescript.js";
|
|
110
56
|
import { BlockNoteExtension } from "./BlockNoteExtension.js";
|
|
111
57
|
import { getBlockNoteExtensions } from "./BlockNoteExtensions.js";
|
|
112
|
-
import { TextCursorPosition } from "./cursorPositionTypes.js";
|
|
113
|
-
import { Selection } from "./selectionTypes.js";
|
|
114
|
-
import { transformPasted } from "./transformPasted.js";
|
|
115
|
-
|
|
116
|
-
// TODO eventually we will want to de-couple this from the editor instance, for now it provides a default schema to use
|
|
58
|
+
import type { TextCursorPosition } from "./cursorPositionTypes.js";
|
|
117
59
|
import {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
60
|
+
BlockManager,
|
|
61
|
+
CollaborationManager,
|
|
62
|
+
type CollaborationOptions,
|
|
63
|
+
EventManager,
|
|
64
|
+
ExportManager,
|
|
65
|
+
ExtensionManager,
|
|
66
|
+
SelectionManager,
|
|
67
|
+
StateManager,
|
|
68
|
+
StyleManager,
|
|
69
|
+
} from "./managers/index.js";
|
|
70
|
+
import type { Selection } from "./selectionTypes.js";
|
|
71
|
+
import { transformPasted } from "./transformPasted.js";
|
|
125
72
|
|
|
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";
|
|
126
76
|
import "../style.css";
|
|
127
77
|
|
|
128
78
|
/**
|
|
@@ -497,41 +447,62 @@ export class BlockNoteEditor<
|
|
|
497
447
|
/**
|
|
498
448
|
* The schema of the editor. The schema defines which Blocks, InlineContent, and Styles are available in the editor.
|
|
499
449
|
*/
|
|
500
|
-
public readonly schema:
|
|
450
|
+
public readonly schema: BlockNoteSchema<BSchema, ISchema, SSchema>;
|
|
501
451
|
|
|
502
452
|
public readonly blockImplementations: BlockSpecs;
|
|
503
453
|
public readonly inlineContentImplementations: InlineContentSpecs;
|
|
504
454
|
public readonly styleImplementations: StyleSpecs;
|
|
505
455
|
|
|
506
|
-
public
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
>;
|
|
512
|
-
public readonly sideMenu: SideMenuProsemirrorPlugin<
|
|
456
|
+
public get formattingToolbar(): FormattingToolbarProsemirrorPlugin {
|
|
457
|
+
return this._extensionManager.formattingToolbar;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
public get linkToolbar(): LinkToolbarProsemirrorPlugin<
|
|
513
461
|
BSchema,
|
|
514
462
|
ISchema,
|
|
515
463
|
SSchema
|
|
516
|
-
|
|
517
|
-
|
|
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<
|
|
518
473
|
BSchema,
|
|
519
474
|
ISchema,
|
|
520
475
|
SSchema
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
ISchema,
|
|
525
|
-
SSchema
|
|
526
|
-
>;
|
|
527
|
-
public readonly comments?: CommentsPlugin;
|
|
476
|
+
> {
|
|
477
|
+
return this._extensionManager.suggestionMenus;
|
|
478
|
+
}
|
|
528
479
|
|
|
529
|
-
|
|
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
|
+
}
|
|
530
499
|
|
|
531
500
|
/**
|
|
532
501
|
* The plugin for forking a document, only defined if in collaboration mode
|
|
533
502
|
*/
|
|
534
|
-
public
|
|
503
|
+
public get forkYDocPlugin() {
|
|
504
|
+
return this._collaborationManager?.forkYDocPlugin;
|
|
505
|
+
}
|
|
535
506
|
/**
|
|
536
507
|
* The `uploadFile` method is what the editor uses when files need to be uploaded (for example when selecting an image to upload).
|
|
537
508
|
* This method should set when creating the editor as this is application-specific.
|
|
@@ -635,35 +606,59 @@ export class BlockNoteEditor<
|
|
|
635
606
|
},
|
|
636
607
|
};
|
|
637
608
|
|
|
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
|
+
|
|
638
632
|
if (newOptions.comments && !newOptions.resolveUsers) {
|
|
639
633
|
throw new Error("resolveUsers is required when using comments");
|
|
640
634
|
}
|
|
641
635
|
|
|
642
|
-
|
|
643
|
-
|
|
636
|
+
// @ts-ignore
|
|
644
637
|
this.schema = newOptions.schema;
|
|
645
638
|
this.blockImplementations = newOptions.schema.blockSpecs;
|
|
646
639
|
this.inlineContentImplementations = newOptions.schema.inlineContentSpecs;
|
|
647
640
|
this.styleImplementations = newOptions.schema.styleSpecs;
|
|
648
641
|
|
|
649
|
-
this.extensions =
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
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;
|
|
667
662
|
|
|
668
663
|
// add extensions from _tiptapOptions
|
|
669
664
|
(newOptions._tiptapOptions?.extensions || []).forEach((ext) => {
|
|
@@ -716,16 +711,6 @@ export class BlockNoteEditor<
|
|
|
716
711
|
})();
|
|
717
712
|
});
|
|
718
713
|
|
|
719
|
-
this.formattingToolbar = this.extensions["formattingToolbar"] as any;
|
|
720
|
-
this.linkToolbar = this.extensions["linkToolbar"] as any;
|
|
721
|
-
this.sideMenu = this.extensions["sideMenu"] as any;
|
|
722
|
-
this.suggestionMenus = this.extensions["suggestionMenus"] as any;
|
|
723
|
-
this.filePanel = this.extensions["filePanel"] as any;
|
|
724
|
-
this.tableHandles = this.extensions["tableHandles"] as any;
|
|
725
|
-
this.comments = this.extensions["comments"] as any;
|
|
726
|
-
this.showSelectionPlugin = this.extensions["showSelection"] as any;
|
|
727
|
-
this.forkYDocPlugin = this.extensions["forkYDocPlugin"] as any;
|
|
728
|
-
|
|
729
714
|
if (newOptions.uploadFile) {
|
|
730
715
|
const uploadFile = newOptions.uploadFile;
|
|
731
716
|
this.uploadFile = async (file, blockId) => {
|
|
@@ -933,13 +918,37 @@ export class BlockNoteEditor<
|
|
|
933
918
|
}
|
|
934
919
|
|
|
935
920
|
this.pmSchema.cached.blockNoteEditor = this;
|
|
921
|
+
|
|
922
|
+
// Initialize managers
|
|
923
|
+
this._blockManager = new BlockManager(this as any);
|
|
924
|
+
|
|
925
|
+
this._eventManager = new EventManager(this as any);
|
|
926
|
+
this._exportManager = new ExportManager(this as any);
|
|
927
|
+
this._extensionManager = new ExtensionManager(this as any);
|
|
928
|
+
this._selectionManager = new SelectionManager(this as any);
|
|
929
|
+
this._stateManager = new StateManager(
|
|
930
|
+
this as any,
|
|
931
|
+
collaborationEnabled
|
|
932
|
+
? {
|
|
933
|
+
undo: this._collaborationManager?.getUndoCommand(),
|
|
934
|
+
redo: this._collaborationManager?.getRedoCommand(),
|
|
935
|
+
}
|
|
936
|
+
: undefined,
|
|
937
|
+
);
|
|
938
|
+
this._styleManager = new StyleManager(this as any);
|
|
939
|
+
|
|
936
940
|
this.emit("create");
|
|
937
941
|
}
|
|
938
942
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
private
|
|
943
|
+
// Manager instances
|
|
944
|
+
private readonly _blockManager: BlockManager<any, any, any>;
|
|
945
|
+
private readonly _collaborationManager?: CollaborationManager;
|
|
946
|
+
private readonly _eventManager: EventManager<any>;
|
|
947
|
+
private readonly _exportManager: ExportManager<any, any, any>;
|
|
948
|
+
private readonly _extensionManager: ExtensionManager;
|
|
949
|
+
private readonly _selectionManager: SelectionManager<any, any, any>;
|
|
950
|
+
private readonly _stateManager: StateManager;
|
|
951
|
+
private readonly _styleManager: StyleManager<any, any, any>;
|
|
943
952
|
|
|
944
953
|
/**
|
|
945
954
|
* Execute a prosemirror command. This is mostly for backwards compatibility with older code.
|
|
@@ -954,16 +963,7 @@ export class BlockNoteEditor<
|
|
|
954
963
|
* ```
|
|
955
964
|
*/
|
|
956
965
|
public exec(command: Command) {
|
|
957
|
-
|
|
958
|
-
throw new Error(
|
|
959
|
-
"`exec` should not be called within a `transact` call, move the `exec` call outside of the `transact` call",
|
|
960
|
-
);
|
|
961
|
-
}
|
|
962
|
-
const state = this._tiptapEditor.state;
|
|
963
|
-
const view = this._tiptapEditor.view;
|
|
964
|
-
const dispatch = (tr: Transaction) => view.dispatch(tr);
|
|
965
|
-
|
|
966
|
-
return command(state, dispatch, view);
|
|
966
|
+
return this._stateManager.exec(command);
|
|
967
967
|
}
|
|
968
968
|
|
|
969
969
|
/**
|
|
@@ -979,15 +979,7 @@ export class BlockNoteEditor<
|
|
|
979
979
|
* ```
|
|
980
980
|
*/
|
|
981
981
|
public canExec(command: Command): boolean {
|
|
982
|
-
|
|
983
|
-
throw new Error(
|
|
984
|
-
"`canExec` should not be called within a `transact` call, move the `canExec` call outside of the `transact` call",
|
|
985
|
-
);
|
|
986
|
-
}
|
|
987
|
-
const state = this._tiptapEditor.state;
|
|
988
|
-
const view = this._tiptapEditor.view;
|
|
989
|
-
|
|
990
|
-
return command(state, undefined, view);
|
|
982
|
+
return this._stateManager.canExec(command);
|
|
991
983
|
}
|
|
992
984
|
|
|
993
985
|
/**
|
|
@@ -1018,40 +1010,7 @@ export class BlockNoteEditor<
|
|
|
1018
1010
|
tr: Transaction,
|
|
1019
1011
|
) => T,
|
|
1020
1012
|
): T {
|
|
1021
|
-
|
|
1022
|
-
// Already in a transaction, so we can just callback immediately
|
|
1023
|
-
return callback(this.activeTransaction);
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
try {
|
|
1027
|
-
// Enter transaction mode, by setting a starting transaction
|
|
1028
|
-
this.activeTransaction = this._tiptapEditor.state.tr;
|
|
1029
|
-
|
|
1030
|
-
// Capture all dispatch'd transactions
|
|
1031
|
-
const result = callback(this.activeTransaction);
|
|
1032
|
-
|
|
1033
|
-
// Any transactions captured by the `dispatch` call will be stored in `this.activeTransaction`
|
|
1034
|
-
const activeTr = this.activeTransaction;
|
|
1035
|
-
|
|
1036
|
-
this.activeTransaction = null;
|
|
1037
|
-
if (
|
|
1038
|
-
activeTr &&
|
|
1039
|
-
// Only dispatch if the transaction was actually modified in some way
|
|
1040
|
-
(activeTr.docChanged ||
|
|
1041
|
-
activeTr.selectionSet ||
|
|
1042
|
-
activeTr.scrolledIntoView ||
|
|
1043
|
-
activeTr.storedMarksSet ||
|
|
1044
|
-
!activeTr.isGeneric)
|
|
1045
|
-
) {
|
|
1046
|
-
// Dispatch the transaction if it was modified
|
|
1047
|
-
this._tiptapEditor.view.dispatch(activeTr);
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
return result;
|
|
1051
|
-
} finally {
|
|
1052
|
-
// We wrap this in a finally block to ensure we don't disable future transactions just because of an error in the callback
|
|
1053
|
-
this.activeTransaction = null;
|
|
1054
|
-
}
|
|
1013
|
+
return this._stateManager.transact(callback);
|
|
1055
1014
|
}
|
|
1056
1015
|
|
|
1057
1016
|
// TO DISCUSS
|
|
@@ -1067,12 +1026,9 @@ export class BlockNoteEditor<
|
|
|
1067
1026
|
ext: { new (...args: any[]): T } & typeof BlockNoteExtension,
|
|
1068
1027
|
key = ext.key(),
|
|
1069
1028
|
): T {
|
|
1070
|
-
|
|
1071
|
-
if (!extension) {
|
|
1072
|
-
throw new Error(`Extension ${key} not found`);
|
|
1073
|
-
}
|
|
1074
|
-
return extension;
|
|
1029
|
+
return this._extensionManager.extension(ext, key);
|
|
1075
1030
|
}
|
|
1031
|
+
|
|
1076
1032
|
/**
|
|
1077
1033
|
* Mount the editor to a DOM element.
|
|
1078
1034
|
*
|
|
@@ -1096,12 +1052,7 @@ export class BlockNoteEditor<
|
|
|
1096
1052
|
* @see https://prosemirror.net/docs/ref/#state.EditorState
|
|
1097
1053
|
*/
|
|
1098
1054
|
public get prosemirrorState() {
|
|
1099
|
-
|
|
1100
|
-
throw new Error(
|
|
1101
|
-
"`prosemirrorState` should not be called within a `transact` call, move the `prosemirrorState` call outside of the `transact` call or use `editor.transact` to read the current editor state",
|
|
1102
|
-
);
|
|
1103
|
-
}
|
|
1104
|
-
return this._tiptapEditor.state;
|
|
1055
|
+
return this._stateManager.prosemirrorState;
|
|
1105
1056
|
}
|
|
1106
1057
|
|
|
1107
1058
|
/**
|
|
@@ -1109,7 +1060,7 @@ export class BlockNoteEditor<
|
|
|
1109
1060
|
* @see https://prosemirror.net/docs/ref/#view.EditorView
|
|
1110
1061
|
*/
|
|
1111
1062
|
public get prosemirrorView() {
|
|
1112
|
-
return this.
|
|
1063
|
+
return this._stateManager.prosemirrorView;
|
|
1113
1064
|
}
|
|
1114
1065
|
|
|
1115
1066
|
public get domElement() {
|
|
@@ -1165,9 +1116,7 @@ export class BlockNoteEditor<
|
|
|
1165
1116
|
* @returns A snapshot of all top-level (non-nested) blocks in the editor.
|
|
1166
1117
|
*/
|
|
1167
1118
|
public get document(): Block<BSchema, ISchema, SSchema>[] {
|
|
1168
|
-
return this.
|
|
1169
|
-
return docToBlocks(tr.doc, this.pmSchema);
|
|
1170
|
-
});
|
|
1119
|
+
return this._blockManager.document;
|
|
1171
1120
|
}
|
|
1172
1121
|
|
|
1173
1122
|
/**
|
|
@@ -1180,7 +1129,7 @@ export class BlockNoteEditor<
|
|
|
1180
1129
|
public getBlock(
|
|
1181
1130
|
blockIdentifier: BlockIdentifier,
|
|
1182
1131
|
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
1183
|
-
return this.
|
|
1132
|
+
return this._blockManager.getBlock(blockIdentifier);
|
|
1184
1133
|
}
|
|
1185
1134
|
|
|
1186
1135
|
/**
|
|
@@ -1195,7 +1144,7 @@ export class BlockNoteEditor<
|
|
|
1195
1144
|
public getPrevBlock(
|
|
1196
1145
|
blockIdentifier: BlockIdentifier,
|
|
1197
1146
|
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
1198
|
-
return this.
|
|
1147
|
+
return this._blockManager.getPrevBlock(blockIdentifier);
|
|
1199
1148
|
}
|
|
1200
1149
|
|
|
1201
1150
|
/**
|
|
@@ -1209,7 +1158,7 @@ export class BlockNoteEditor<
|
|
|
1209
1158
|
public getNextBlock(
|
|
1210
1159
|
blockIdentifier: BlockIdentifier,
|
|
1211
1160
|
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
1212
|
-
return this.
|
|
1161
|
+
return this._blockManager.getNextBlock(blockIdentifier);
|
|
1213
1162
|
}
|
|
1214
1163
|
|
|
1215
1164
|
/**
|
|
@@ -1222,7 +1171,7 @@ export class BlockNoteEditor<
|
|
|
1222
1171
|
public getParentBlock(
|
|
1223
1172
|
blockIdentifier: BlockIdentifier,
|
|
1224
1173
|
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
1225
|
-
return this.
|
|
1174
|
+
return this._blockManager.getParentBlock(blockIdentifier);
|
|
1226
1175
|
}
|
|
1227
1176
|
|
|
1228
1177
|
/**
|
|
@@ -1234,33 +1183,7 @@ export class BlockNoteEditor<
|
|
|
1234
1183
|
callback: (block: Block<BSchema, ISchema, SSchema>) => boolean,
|
|
1235
1184
|
reverse = false,
|
|
1236
1185
|
): void {
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
if (reverse) {
|
|
1240
|
-
blocks.reverse();
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
function traverseBlockArray(
|
|
1244
|
-
blockArray: Block<BSchema, ISchema, SSchema>[],
|
|
1245
|
-
): boolean {
|
|
1246
|
-
for (const block of blockArray) {
|
|
1247
|
-
if (callback(block) === false) {
|
|
1248
|
-
return false;
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
const children = reverse
|
|
1252
|
-
? block.children.slice().reverse()
|
|
1253
|
-
: block.children;
|
|
1254
|
-
|
|
1255
|
-
if (!traverseBlockArray(children)) {
|
|
1256
|
-
return false;
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
return true;
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
traverseBlockArray(blocks);
|
|
1186
|
+
this._blockManager.forEachBlock(callback, reverse);
|
|
1264
1187
|
}
|
|
1265
1188
|
|
|
1266
1189
|
/**
|
|
@@ -1292,7 +1215,7 @@ export class BlockNoteEditor<
|
|
|
1292
1215
|
ISchema,
|
|
1293
1216
|
SSchema
|
|
1294
1217
|
> {
|
|
1295
|
-
return this.
|
|
1218
|
+
return this._selectionManager.getTextCursorPosition();
|
|
1296
1219
|
}
|
|
1297
1220
|
|
|
1298
1221
|
/**
|
|
@@ -1305,9 +1228,7 @@ export class BlockNoteEditor<
|
|
|
1305
1228
|
targetBlock: BlockIdentifier,
|
|
1306
1229
|
placement: "start" | "end" = "start",
|
|
1307
1230
|
) {
|
|
1308
|
-
return this.
|
|
1309
|
-
setTextCursorPosition(tr, targetBlock, placement),
|
|
1310
|
-
);
|
|
1231
|
+
return this._selectionManager.setTextCursorPosition(targetBlock, placement);
|
|
1311
1232
|
}
|
|
1312
1233
|
|
|
1313
1234
|
/**
|
|
@@ -1317,7 +1238,7 @@ export class BlockNoteEditor<
|
|
|
1317
1238
|
* If the selection starts / ends halfway through a block, the returned data will contain the entire block.
|
|
1318
1239
|
*/
|
|
1319
1240
|
public getSelection(): Selection<BSchema, ISchema, SSchema> | undefined {
|
|
1320
|
-
return this.
|
|
1241
|
+
return this._selectionManager.getSelection();
|
|
1321
1242
|
}
|
|
1322
1243
|
|
|
1323
1244
|
/**
|
|
@@ -1328,7 +1249,7 @@ export class BlockNoteEditor<
|
|
|
1328
1249
|
* only the part of the block that is included in the selection.
|
|
1329
1250
|
*/
|
|
1330
1251
|
public getSelectionCutBlocks() {
|
|
1331
|
-
return this.
|
|
1252
|
+
return this._selectionManager.getSelectionCutBlocks();
|
|
1332
1253
|
}
|
|
1333
1254
|
|
|
1334
1255
|
/**
|
|
@@ -1337,7 +1258,7 @@ export class BlockNoteEditor<
|
|
|
1337
1258
|
* @param endBlock The identifier of the block that should be the end of the selection.
|
|
1338
1259
|
*/
|
|
1339
1260
|
public setSelection(startBlock: BlockIdentifier, endBlock: BlockIdentifier) {
|
|
1340
|
-
return this.
|
|
1261
|
+
return this._selectionManager.setSelection(startBlock, endBlock);
|
|
1341
1262
|
}
|
|
1342
1263
|
|
|
1343
1264
|
/**
|
|
@@ -1345,9 +1266,7 @@ export class BlockNoteEditor<
|
|
|
1345
1266
|
* @returns True if the editor is editable, false otherwise.
|
|
1346
1267
|
*/
|
|
1347
1268
|
public get isEditable(): boolean {
|
|
1348
|
-
return this.
|
|
1349
|
-
? true
|
|
1350
|
-
: this._tiptapEditor.isEditable;
|
|
1269
|
+
return this._stateManager.isEditable;
|
|
1351
1270
|
}
|
|
1352
1271
|
|
|
1353
1272
|
/**
|
|
@@ -1355,9 +1274,7 @@ export class BlockNoteEditor<
|
|
|
1355
1274
|
* @param editable True to make the editor editable, or false to lock it.
|
|
1356
1275
|
*/
|
|
1357
1276
|
public set isEditable(editable: boolean) {
|
|
1358
|
-
|
|
1359
|
-
this._tiptapEditor.setEditable(editable);
|
|
1360
|
-
}
|
|
1277
|
+
this._stateManager.isEditable = editable;
|
|
1361
1278
|
}
|
|
1362
1279
|
|
|
1363
1280
|
/**
|
|
@@ -1373,8 +1290,10 @@ export class BlockNoteEditor<
|
|
|
1373
1290
|
referenceBlock: BlockIdentifier,
|
|
1374
1291
|
placement: "before" | "after" = "before",
|
|
1375
1292
|
) {
|
|
1376
|
-
return this.
|
|
1377
|
-
|
|
1293
|
+
return this._blockManager.insertBlocks(
|
|
1294
|
+
blocksToInsert,
|
|
1295
|
+
referenceBlock,
|
|
1296
|
+
placement,
|
|
1378
1297
|
);
|
|
1379
1298
|
}
|
|
1380
1299
|
|
|
@@ -1389,7 +1308,7 @@ export class BlockNoteEditor<
|
|
|
1389
1308
|
blockToUpdate: BlockIdentifier,
|
|
1390
1309
|
update: PartialBlock<BSchema, ISchema, SSchema>,
|
|
1391
1310
|
) {
|
|
1392
|
-
return this.
|
|
1311
|
+
return this._blockManager.updateBlock(blockToUpdate, update);
|
|
1393
1312
|
}
|
|
1394
1313
|
|
|
1395
1314
|
/**
|
|
@@ -1397,9 +1316,7 @@ export class BlockNoteEditor<
|
|
|
1397
1316
|
* @param blocksToRemove An array of identifiers for existing blocks that should be removed.
|
|
1398
1317
|
*/
|
|
1399
1318
|
public removeBlocks(blocksToRemove: BlockIdentifier[]) {
|
|
1400
|
-
return this.
|
|
1401
|
-
(tr) => removeAndInsertBlocks(tr, blocksToRemove, []).removedBlocks,
|
|
1402
|
-
);
|
|
1319
|
+
return this._blockManager.removeBlocks(blocksToRemove);
|
|
1403
1320
|
}
|
|
1404
1321
|
|
|
1405
1322
|
/**
|
|
@@ -1413,30 +1330,21 @@ export class BlockNoteEditor<
|
|
|
1413
1330
|
blocksToRemove: BlockIdentifier[],
|
|
1414
1331
|
blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[],
|
|
1415
1332
|
) {
|
|
1416
|
-
return this.
|
|
1417
|
-
removeAndInsertBlocks(tr, blocksToRemove, blocksToInsert),
|
|
1418
|
-
);
|
|
1333
|
+
return this._blockManager.replaceBlocks(blocksToRemove, blocksToInsert);
|
|
1419
1334
|
}
|
|
1420
1335
|
|
|
1421
1336
|
/**
|
|
1422
1337
|
* Undo the last action.
|
|
1423
1338
|
*/
|
|
1424
1339
|
public undo() {
|
|
1425
|
-
|
|
1426
|
-
return this.exec(undoCommand);
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
return this.exec(undo);
|
|
1340
|
+
return this._stateManager.undo();
|
|
1430
1341
|
}
|
|
1431
1342
|
|
|
1432
1343
|
/**
|
|
1433
1344
|
* Redo the last action.
|
|
1434
1345
|
*/
|
|
1435
1346
|
public redo() {
|
|
1436
|
-
|
|
1437
|
-
return this.exec(redoCommand);
|
|
1438
|
-
}
|
|
1439
|
-
return this.exec(redo);
|
|
1347
|
+
return this._stateManager.redo();
|
|
1440
1348
|
}
|
|
1441
1349
|
|
|
1442
1350
|
/**
|
|
@@ -1448,55 +1356,14 @@ export class BlockNoteEditor<
|
|
|
1448
1356
|
content: PartialInlineContent<ISchema, SSchema>,
|
|
1449
1357
|
{ updateSelection = false }: { updateSelection?: boolean } = {},
|
|
1450
1358
|
) {
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
this.transact((tr) => {
|
|
1454
|
-
insertContentAt(
|
|
1455
|
-
tr,
|
|
1456
|
-
{
|
|
1457
|
-
from: tr.selection.from,
|
|
1458
|
-
to: tr.selection.to,
|
|
1459
|
-
},
|
|
1460
|
-
nodes,
|
|
1461
|
-
{
|
|
1462
|
-
updateSelection,
|
|
1463
|
-
},
|
|
1464
|
-
);
|
|
1465
|
-
});
|
|
1359
|
+
this._styleManager.insertInlineContent(content, { updateSelection });
|
|
1466
1360
|
}
|
|
1467
1361
|
|
|
1468
1362
|
/**
|
|
1469
1363
|
* Gets the active text styles at the text cursor position or at the end of the current selection if it's active.
|
|
1470
1364
|
*/
|
|
1471
|
-
public getActiveStyles() {
|
|
1472
|
-
return this.
|
|
1473
|
-
const styles: Styles<SSchema> = {};
|
|
1474
|
-
const marks = tr.selection.$to.marks();
|
|
1475
|
-
|
|
1476
|
-
for (const mark of marks) {
|
|
1477
|
-
const config = this.schema.styleSchema[mark.type.name];
|
|
1478
|
-
if (!config) {
|
|
1479
|
-
if (
|
|
1480
|
-
// Links are not considered styles in blocknote
|
|
1481
|
-
mark.type.name !== "link" &&
|
|
1482
|
-
// "blocknoteIgnore" tagged marks (such as comments) are also not considered BlockNote "styles"
|
|
1483
|
-
!mark.type.spec.blocknoteIgnore
|
|
1484
|
-
) {
|
|
1485
|
-
// eslint-disable-next-line no-console
|
|
1486
|
-
console.warn("mark not found in styleschema", mark.type.name);
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
continue;
|
|
1490
|
-
}
|
|
1491
|
-
if (config.propSchema === "boolean") {
|
|
1492
|
-
(styles as any)[config.type] = true;
|
|
1493
|
-
} else {
|
|
1494
|
-
(styles as any)[config.type] = mark.attrs.stringValue;
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
return styles;
|
|
1499
|
-
});
|
|
1365
|
+
public getActiveStyles(): Styles<SSchema> {
|
|
1366
|
+
return this._styleManager.getActiveStyles();
|
|
1500
1367
|
}
|
|
1501
1368
|
|
|
1502
1369
|
/**
|
|
@@ -1504,19 +1371,7 @@ export class BlockNoteEditor<
|
|
|
1504
1371
|
* @param styles The styles to add.
|
|
1505
1372
|
*/
|
|
1506
1373
|
public addStyles(styles: Styles<SSchema>) {
|
|
1507
|
-
|
|
1508
|
-
const config = this.schema.styleSchema[style];
|
|
1509
|
-
if (!config) {
|
|
1510
|
-
throw new Error(`style ${style} not found in styleSchema`);
|
|
1511
|
-
}
|
|
1512
|
-
if (config.propSchema === "boolean") {
|
|
1513
|
-
this._tiptapEditor.commands.setMark(style);
|
|
1514
|
-
} else if (config.propSchema === "string") {
|
|
1515
|
-
this._tiptapEditor.commands.setMark(style, { stringValue: value });
|
|
1516
|
-
} else {
|
|
1517
|
-
throw new UnreachableCaseError(config.propSchema);
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1374
|
+
this._styleManager.addStyles(styles);
|
|
1520
1375
|
}
|
|
1521
1376
|
|
|
1522
1377
|
/**
|
|
@@ -1524,9 +1379,7 @@ export class BlockNoteEditor<
|
|
|
1524
1379
|
* @param styles The styles to remove.
|
|
1525
1380
|
*/
|
|
1526
1381
|
public removeStyles(styles: Styles<SSchema>) {
|
|
1527
|
-
|
|
1528
|
-
this._tiptapEditor.commands.unsetMark(style);
|
|
1529
|
-
}
|
|
1382
|
+
this._styleManager.removeStyles(styles);
|
|
1530
1383
|
}
|
|
1531
1384
|
|
|
1532
1385
|
/**
|
|
@@ -1534,35 +1387,21 @@ export class BlockNoteEditor<
|
|
|
1534
1387
|
* @param styles The styles to toggle.
|
|
1535
1388
|
*/
|
|
1536
1389
|
public toggleStyles(styles: Styles<SSchema>) {
|
|
1537
|
-
|
|
1538
|
-
const config = this.schema.styleSchema[style];
|
|
1539
|
-
if (!config) {
|
|
1540
|
-
throw new Error(`style ${style} not found in styleSchema`);
|
|
1541
|
-
}
|
|
1542
|
-
if (config.propSchema === "boolean") {
|
|
1543
|
-
this._tiptapEditor.commands.toggleMark(style);
|
|
1544
|
-
} else if (config.propSchema === "string") {
|
|
1545
|
-
this._tiptapEditor.commands.toggleMark(style, { stringValue: value });
|
|
1546
|
-
} else {
|
|
1547
|
-
throw new UnreachableCaseError(config.propSchema);
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1390
|
+
this._styleManager.toggleStyles(styles);
|
|
1550
1391
|
}
|
|
1551
1392
|
|
|
1552
1393
|
/**
|
|
1553
1394
|
* Gets the currently selected text.
|
|
1554
1395
|
*/
|
|
1555
1396
|
public getSelectedText() {
|
|
1556
|
-
return this.
|
|
1557
|
-
return tr.doc.textBetween(tr.selection.from, tr.selection.to);
|
|
1558
|
-
});
|
|
1397
|
+
return this._styleManager.getSelectedText();
|
|
1559
1398
|
}
|
|
1560
1399
|
|
|
1561
1400
|
/**
|
|
1562
1401
|
* Gets the URL of the last link in the current selection, or `undefined` if there are no links in the selection.
|
|
1563
1402
|
*/
|
|
1564
1403
|
public getSelectedLinkUrl() {
|
|
1565
|
-
return this.
|
|
1404
|
+
return this._styleManager.getSelectedLinkUrl();
|
|
1566
1405
|
}
|
|
1567
1406
|
|
|
1568
1407
|
/**
|
|
@@ -1571,51 +1410,35 @@ export class BlockNoteEditor<
|
|
|
1571
1410
|
* @param text The text to display the link with.
|
|
1572
1411
|
*/
|
|
1573
1412
|
public createLink(url: string, text?: string) {
|
|
1574
|
-
|
|
1575
|
-
return;
|
|
1576
|
-
}
|
|
1577
|
-
const mark = this.pmSchema.mark("link", { href: url });
|
|
1578
|
-
this.transact((tr) => {
|
|
1579
|
-
const { from, to } = tr.selection;
|
|
1580
|
-
|
|
1581
|
-
if (text) {
|
|
1582
|
-
tr.insertText(text, from, to).addMark(from, from + text.length, mark);
|
|
1583
|
-
} else {
|
|
1584
|
-
tr.setSelection(TextSelection.create(tr.doc, to)).addMark(
|
|
1585
|
-
from,
|
|
1586
|
-
to,
|
|
1587
|
-
mark,
|
|
1588
|
-
);
|
|
1589
|
-
}
|
|
1590
|
-
});
|
|
1413
|
+
this._styleManager.createLink(url, text);
|
|
1591
1414
|
}
|
|
1592
1415
|
|
|
1593
1416
|
/**
|
|
1594
1417
|
* Checks if the block containing the text cursor can be nested.
|
|
1595
1418
|
*/
|
|
1596
1419
|
public canNestBlock() {
|
|
1597
|
-
return canNestBlock(
|
|
1420
|
+
return this._blockManager.canNestBlock();
|
|
1598
1421
|
}
|
|
1599
1422
|
|
|
1600
1423
|
/**
|
|
1601
1424
|
* Nests the block containing the text cursor into the block above it.
|
|
1602
1425
|
*/
|
|
1603
1426
|
public nestBlock() {
|
|
1604
|
-
nestBlock(
|
|
1427
|
+
this._blockManager.nestBlock();
|
|
1605
1428
|
}
|
|
1606
1429
|
|
|
1607
1430
|
/**
|
|
1608
1431
|
* Checks if the block containing the text cursor is nested.
|
|
1609
1432
|
*/
|
|
1610
1433
|
public canUnnestBlock() {
|
|
1611
|
-
return canUnnestBlock(
|
|
1434
|
+
return this._blockManager.canUnnestBlock();
|
|
1612
1435
|
}
|
|
1613
1436
|
|
|
1614
1437
|
/**
|
|
1615
1438
|
* Lifts the block containing the text cursor out of its parent.
|
|
1616
1439
|
*/
|
|
1617
1440
|
public unnestBlock() {
|
|
1618
|
-
unnestBlock(
|
|
1441
|
+
this._blockManager.unnestBlock();
|
|
1619
1442
|
}
|
|
1620
1443
|
|
|
1621
1444
|
/**
|
|
@@ -1624,7 +1447,7 @@ export class BlockNoteEditor<
|
|
|
1624
1447
|
* current blocks share a common parent, moves them out of & before it.
|
|
1625
1448
|
*/
|
|
1626
1449
|
public moveBlocksUp() {
|
|
1627
|
-
return moveBlocksUp(
|
|
1450
|
+
return this._blockManager.moveBlocksUp();
|
|
1628
1451
|
}
|
|
1629
1452
|
|
|
1630
1453
|
/**
|
|
@@ -1633,7 +1456,7 @@ export class BlockNoteEditor<
|
|
|
1633
1456
|
* current blocks share a common parent, moves them out of & after it.
|
|
1634
1457
|
*/
|
|
1635
1458
|
public moveBlocksDown() {
|
|
1636
|
-
return moveBlocksDown(
|
|
1459
|
+
return this._blockManager.moveBlocksDown();
|
|
1637
1460
|
}
|
|
1638
1461
|
|
|
1639
1462
|
/**
|
|
@@ -1646,8 +1469,7 @@ export class BlockNoteEditor<
|
|
|
1646
1469
|
public blocksToHTMLLossy(
|
|
1647
1470
|
blocks: PartialBlock<BSchema, ISchema, SSchema>[] = this.document,
|
|
1648
1471
|
): string {
|
|
1649
|
-
|
|
1650
|
-
return exporter.exportBlocks(blocks, {});
|
|
1472
|
+
return this._exportManager.blocksToHTMLLossy(blocks);
|
|
1651
1473
|
}
|
|
1652
1474
|
|
|
1653
1475
|
/**
|
|
@@ -1662,8 +1484,7 @@ export class BlockNoteEditor<
|
|
|
1662
1484
|
public blocksToFullHTML(
|
|
1663
1485
|
blocks: PartialBlock<BSchema, ISchema, SSchema>[],
|
|
1664
1486
|
): string {
|
|
1665
|
-
|
|
1666
|
-
return exporter.serializeBlocks(blocks, {});
|
|
1487
|
+
return this._exportManager.blocksToFullHTML(blocks);
|
|
1667
1488
|
}
|
|
1668
1489
|
/**
|
|
1669
1490
|
* Parses blocks from an HTML string. Tries to create `Block` objects out of any HTML block-level elements, and
|
|
@@ -1675,7 +1496,7 @@ export class BlockNoteEditor<
|
|
|
1675
1496
|
public tryParseHTMLToBlocks(
|
|
1676
1497
|
html: string,
|
|
1677
1498
|
): Block<BSchema, ISchema, SSchema>[] {
|
|
1678
|
-
return
|
|
1499
|
+
return this._exportManager.tryParseHTMLToBlocks(html);
|
|
1679
1500
|
}
|
|
1680
1501
|
|
|
1681
1502
|
/**
|
|
@@ -1687,7 +1508,7 @@ export class BlockNoteEditor<
|
|
|
1687
1508
|
public blocksToMarkdownLossy(
|
|
1688
1509
|
blocks: PartialBlock<BSchema, ISchema, SSchema>[] = this.document,
|
|
1689
1510
|
): string {
|
|
1690
|
-
return
|
|
1511
|
+
return this._exportManager.blocksToMarkdownLossy(blocks);
|
|
1691
1512
|
}
|
|
1692
1513
|
|
|
1693
1514
|
/**
|
|
@@ -1697,43 +1518,23 @@ export class BlockNoteEditor<
|
|
|
1697
1518
|
* @param markdown The Markdown string to parse blocks from.
|
|
1698
1519
|
* @returns The blocks parsed from the Markdown string.
|
|
1699
1520
|
*/
|
|
1700
|
-
public
|
|
1521
|
+
public tryParseMarkdownToBlocks(
|
|
1701
1522
|
markdown: string,
|
|
1702
|
-
):
|
|
1703
|
-
return
|
|
1523
|
+
): Block<BSchema, ISchema, SSchema>[] {
|
|
1524
|
+
return this._exportManager.tryParseMarkdownToBlocks(markdown);
|
|
1704
1525
|
}
|
|
1705
1526
|
|
|
1706
1527
|
/**
|
|
1707
1528
|
* Updates the user info for the current user that's shown to other collaborators.
|
|
1708
1529
|
*/
|
|
1709
1530
|
public updateCollaborationUserInfo(user: { name: string; color: string }) {
|
|
1710
|
-
if (!this.
|
|
1531
|
+
if (!this._collaborationManager) {
|
|
1711
1532
|
throw new Error(
|
|
1712
1533
|
"Cannot update collaboration user info when collaboration is disabled.",
|
|
1713
1534
|
);
|
|
1714
1535
|
}
|
|
1715
1536
|
|
|
1716
|
-
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
/**
|
|
1720
|
-
* Registers a callback which will be called before any change is applied to the editor, allowing you to cancel the change.
|
|
1721
|
-
*/
|
|
1722
|
-
public onBeforeChange(
|
|
1723
|
-
/**
|
|
1724
|
-
* If the callback returns `false`, the change will be canceled & not applied to the editor.
|
|
1725
|
-
*/
|
|
1726
|
-
callback: (
|
|
1727
|
-
editor: BlockNoteEditor<BSchema, ISchema, SSchema>,
|
|
1728
|
-
context: {
|
|
1729
|
-
getChanges: () => BlocksChanged<BSchema, ISchema, SSchema>;
|
|
1730
|
-
tr: Transaction;
|
|
1731
|
-
},
|
|
1732
|
-
) => boolean | void,
|
|
1733
|
-
): () => void {
|
|
1734
|
-
return (this.extensions["blockChange"] as BlockChangePlugin).subscribe(
|
|
1735
|
-
(context) => callback(this, context),
|
|
1736
|
-
);
|
|
1537
|
+
this._collaborationManager.updateUserInfo(user);
|
|
1737
1538
|
}
|
|
1738
1539
|
|
|
1739
1540
|
/**
|
|
@@ -1753,24 +1554,7 @@ export class BlockNoteEditor<
|
|
|
1753
1554
|
},
|
|
1754
1555
|
) => void,
|
|
1755
1556
|
) {
|
|
1756
|
-
|
|
1757
|
-
transaction,
|
|
1758
|
-
appendedTransactions,
|
|
1759
|
-
}: {
|
|
1760
|
-
transaction: Transaction;
|
|
1761
|
-
appendedTransactions: Transaction[];
|
|
1762
|
-
}) => {
|
|
1763
|
-
callback(this, {
|
|
1764
|
-
getChanges: () =>
|
|
1765
|
-
getBlocksChangedByTransaction(transaction, appendedTransactions),
|
|
1766
|
-
});
|
|
1767
|
-
};
|
|
1768
|
-
|
|
1769
|
-
this._tiptapEditor.on("update", cb);
|
|
1770
|
-
|
|
1771
|
-
return () => {
|
|
1772
|
-
this._tiptapEditor.off("update", cb);
|
|
1773
|
-
};
|
|
1557
|
+
return this._eventManager.onChange(callback);
|
|
1774
1558
|
}
|
|
1775
1559
|
|
|
1776
1560
|
/**
|
|
@@ -1783,29 +1567,19 @@ export class BlockNoteEditor<
|
|
|
1783
1567
|
callback: (editor: BlockNoteEditor<BSchema, ISchema, SSchema>) => void,
|
|
1784
1568
|
includeSelectionChangedByRemote?: boolean,
|
|
1785
1569
|
) {
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
) {
|
|
1791
|
-
// selection changed because of a yjs sync (i.e.: other user was typing)
|
|
1792
|
-
// we don't want to trigger the callback in this case
|
|
1793
|
-
return;
|
|
1794
|
-
}
|
|
1795
|
-
callback(this);
|
|
1796
|
-
};
|
|
1797
|
-
|
|
1798
|
-
this._tiptapEditor.on("selectionUpdate", cb);
|
|
1799
|
-
|
|
1800
|
-
return () => {
|
|
1801
|
-
this._tiptapEditor.off("selectionUpdate", cb);
|
|
1802
|
-
};
|
|
1570
|
+
return this._eventManager.onSelectionChange(
|
|
1571
|
+
callback,
|
|
1572
|
+
includeSelectionChangedByRemote,
|
|
1573
|
+
);
|
|
1803
1574
|
}
|
|
1804
1575
|
|
|
1805
1576
|
/**
|
|
1806
1577
|
* A callback function that runs when the editor has been initialized.
|
|
1807
1578
|
*
|
|
1808
1579
|
* This can be useful for plugins to initialize themselves after the editor has been initialized.
|
|
1580
|
+
*
|
|
1581
|
+
* @param callback The callback to execute.
|
|
1582
|
+
* @returns A function to remove the callback.
|
|
1809
1583
|
*/
|
|
1810
1584
|
public onCreate(callback: () => void) {
|
|
1811
1585
|
this.on("create", callback);
|
|
@@ -1815,26 +1589,44 @@ export class BlockNoteEditor<
|
|
|
1815
1589
|
};
|
|
1816
1590
|
}
|
|
1817
1591
|
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1592
|
+
/**
|
|
1593
|
+
* A callback function that runs when the editor has been mounted.
|
|
1594
|
+
*
|
|
1595
|
+
* This can be useful for plugins to initialize themselves after the editor has been mounted.
|
|
1596
|
+
*
|
|
1597
|
+
* @param callback The callback to execute.
|
|
1598
|
+
* @returns A function to remove the callback.
|
|
1599
|
+
*/
|
|
1600
|
+
public onMount(
|
|
1601
|
+
callback: (ctx: {
|
|
1602
|
+
editor: BlockNoteEditor<BSchema, ISchema, SSchema>;
|
|
1603
|
+
}) => void,
|
|
1604
|
+
) {
|
|
1605
|
+
this._eventManager.onMount(callback);
|
|
1606
|
+
}
|
|
1829
1607
|
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1608
|
+
/**
|
|
1609
|
+
* A callback function that runs when the editor has been unmounted.
|
|
1610
|
+
*
|
|
1611
|
+
* This can be useful for plugins to clean up themselves after the editor has been unmounted.
|
|
1612
|
+
*
|
|
1613
|
+
* @param callback The callback to execute.
|
|
1614
|
+
* @returns A function to remove the callback.
|
|
1615
|
+
*/
|
|
1616
|
+
public onUnmount(
|
|
1617
|
+
callback: (ctx: {
|
|
1618
|
+
editor: BlockNoteEditor<BSchema, ISchema, SSchema>;
|
|
1619
|
+
}) => void,
|
|
1620
|
+
) {
|
|
1621
|
+
this._eventManager.onUnmount(callback);
|
|
1622
|
+
}
|
|
1836
1623
|
|
|
1837
|
-
|
|
1624
|
+
/**
|
|
1625
|
+
* Gets the bounding box of the current selection.
|
|
1626
|
+
* @returns The bounding box of the current selection.
|
|
1627
|
+
*/
|
|
1628
|
+
public getSelectionBoundingBox() {
|
|
1629
|
+
return this._selectionManager.getSelectionBoundingBox();
|
|
1838
1630
|
}
|
|
1839
1631
|
|
|
1840
1632
|
public get isEmpty() {
|
|
@@ -1892,15 +1684,7 @@ export class BlockNoteEditor<
|
|
|
1892
1684
|
* @param raw Whether to paste the HTML as is, or to convert it to BlockNote HTML.
|
|
1893
1685
|
*/
|
|
1894
1686
|
public pasteHTML(html: string, raw = false) {
|
|
1895
|
-
|
|
1896
|
-
if (!raw) {
|
|
1897
|
-
const blocks = this.tryParseHTMLToBlocks(html);
|
|
1898
|
-
htmlToPaste = this.blocksToFullHTML(blocks);
|
|
1899
|
-
}
|
|
1900
|
-
if (!htmlToPaste) {
|
|
1901
|
-
return;
|
|
1902
|
-
}
|
|
1903
|
-
this.prosemirrorView?.pasteHTML(htmlToPaste);
|
|
1687
|
+
this._exportManager.pasteHTML(html, raw);
|
|
1904
1688
|
}
|
|
1905
1689
|
|
|
1906
1690
|
/**
|
|
@@ -1908,7 +1692,7 @@ export class BlockNoteEditor<
|
|
|
1908
1692
|
* @param text The text to paste.
|
|
1909
1693
|
*/
|
|
1910
1694
|
public pasteText(text: string) {
|
|
1911
|
-
return this.
|
|
1695
|
+
return this._exportManager.pasteText(text);
|
|
1912
1696
|
}
|
|
1913
1697
|
|
|
1914
1698
|
/**
|
|
@@ -1916,7 +1700,6 @@ export class BlockNoteEditor<
|
|
|
1916
1700
|
* @param markdown The markdown to paste.
|
|
1917
1701
|
*/
|
|
1918
1702
|
public pasteMarkdown(markdown: string) {
|
|
1919
|
-
|
|
1920
|
-
return this.pasteHTML(html);
|
|
1703
|
+
return this._exportManager.pasteMarkdown(markdown);
|
|
1921
1704
|
}
|
|
1922
1705
|
}
|