@blocknote/core 0.16.0 → 0.17.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/blocknote.js +3292 -2755
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -6
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +5 -2
- package/src/api/blockManipulation/commands/insertBlocks/__snapshots__/insertBlocks.test.ts.snap +3087 -0
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.ts +132 -0
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +71 -0
- package/src/api/blockManipulation/commands/mergeBlocks/__snapshots__/mergeBlocks.test.ts.snap +2276 -0
- package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +131 -0
- package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +103 -0
- package/src/api/blockManipulation/commands/moveBlock/__snapshots__/moveBlock.test.ts.snap +3767 -0
- package/src/api/blockManipulation/commands/moveBlock/moveBlock.test.ts +192 -0
- package/src/api/blockManipulation/commands/moveBlock/moveBlock.ts +178 -0
- package/src/api/blockManipulation/commands/removeBlocks/__snapshots__/removeBlocks.test.ts.snap +1136 -0
- package/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.ts +34 -0
- package/src/api/blockManipulation/commands/removeBlocks/removeBlocks.ts +100 -0
- package/src/api/blockManipulation/commands/replaceBlocks/__snapshots__/replaceBlocks.test.ts.snap +4931 -0
- package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.ts +222 -0
- package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +70 -0
- package/src/api/blockManipulation/commands/splitBlock/__snapshots__/splitBlock.test.ts.snap +2924 -0
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +136 -0
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +48 -0
- package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +8376 -0
- package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +300 -0
- package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +199 -0
- package/src/api/blockManipulation/insertContentAt.ts +96 -0
- package/src/api/blockManipulation/selections/textCursorPosition/__snapshots__/textCursorPosition.test.ts.snap +316 -0
- package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.ts +53 -0
- package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts +130 -0
- package/src/api/blockManipulation/setupTestEnv.ts +179 -0
- package/src/api/clipboard/__snapshots__/tableAllCells.html +1 -1
- package/src/api/clipboard/clipboard.test.ts +5 -6
- package/src/api/clipboard/fromClipboard/fileDropExtension.ts +8 -4
- package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +11 -6
- package/src/api/clipboard/fromClipboard/pasteExtension.ts +8 -4
- package/src/api/clipboard/toClipboard/copyExtension.ts +113 -61
- package/src/api/exporters/html/__snapshots__/complex/misc/external.html +1 -1
- package/src/api/exporters/html/__snapshots__/lists/basic/external.html +1 -1
- package/src/api/exporters/html/__snapshots__/lists/nested/external.html +1 -1
- package/src/api/exporters/html/externalHTMLExporter.ts +42 -94
- package/src/api/exporters/html/htmlConversion.test.ts +19 -13
- package/src/api/exporters/html/internalHTMLSerializer.ts +21 -72
- package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +263 -0
- package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +158 -0
- package/src/api/exporters/markdown/markdownExporter.test.ts +10 -10
- package/src/api/exporters/markdown/markdownExporter.ts +11 -7
- package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +2 -2
- package/src/api/getBlockInfoFromPos.ts +172 -90
- package/src/api/nodeConversions/blockToNode.ts +257 -0
- package/src/api/nodeConversions/fragmentToBlocks.ts +60 -0
- package/src/api/nodeConversions/nodeConversions.test.ts +9 -8
- package/src/api/nodeConversions/{nodeConversions.ts → nodeToBlock.ts} +20 -262
- package/src/api/parsers/html/parseHTML.test.ts +2 -2
- package/src/api/parsers/html/parseHTML.ts +8 -4
- package/src/api/parsers/html/util/nestedLists.test.ts +2 -2
- package/src/api/parsers/markdown/parseMarkdown.test.ts +2 -2
- package/src/api/parsers/markdown/parseMarkdown.ts +8 -4
- package/src/api/testUtil/cases/customBlocks.ts +11 -11
- package/src/api/testUtil/cases/customInlineContent.ts +6 -6
- package/src/api/testUtil/cases/customStyles.ts +6 -6
- package/src/api/testUtil/cases/defaultSchema.ts +4 -4
- package/src/api/testUtil/index.ts +6 -6
- package/src/api/testUtil/partialBlockTestUtil.ts +5 -5
- package/src/blocks/AudioBlockContent/AudioBlockContent.ts +5 -5
- package/src/blocks/FileBlockContent/FileBlockContent.ts +4 -4
- package/src/blocks/FileBlockContent/fileBlockHelpers.ts +2 -2
- package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +61 -39
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +5 -5
- package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +30 -18
- package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +67 -33
- package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +23 -19
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +22 -24
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +31 -19
- package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +16 -11
- package/src/blocks/TableBlockContent/TableBlockContent.ts +4 -4
- package/src/blocks/VideoBlockContent/VideoBlockContent.ts +5 -5
- package/src/blocks/defaultBlockHelpers.ts +4 -4
- package/src/blocks/defaultBlockTypeGuards.ts +5 -5
- package/src/blocks/defaultBlocks.ts +13 -13
- package/src/blocks/defaultProps.ts +1 -1
- package/src/editor/BlockNoteEditor.test.ts +14 -7
- package/src/editor/BlockNoteEditor.ts +82 -149
- package/src/editor/BlockNoteExtensions.ts +15 -11
- package/src/editor/BlockNoteSchema.ts +7 -7
- package/src/editor/BlockNoteTipTapEditor.ts +5 -3
- package/src/editor/cursorPositionTypes.ts +7 -2
- package/src/editor/selectionTypes.ts +6 -2
- package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +1 -1
- package/src/extensions/BackgroundColor/BackgroundColorMark.ts +1 -1
- package/src/extensions/FilePanel/FilePanelPlugin.ts +4 -4
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +8 -4
- package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +334 -0
- package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +9 -4
- package/src/extensions/{NonEditableBlocks/NonEditableBlockPlugin.ts → NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts} +2 -2
- package/src/extensions/Placeholder/PlaceholderPlugin.ts +1 -1
- package/src/extensions/SideMenu/SideMenuPlugin.ts +72 -401
- package/src/extensions/SideMenu/dragging.ts +251 -0
- package/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +1 -1
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +8 -4
- package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +8 -4
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +19 -15
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +11 -7
- package/src/extensions/TextColor/TextColorExtension.ts +1 -1
- package/src/extensions/TextColor/TextColorMark.ts +1 -1
- package/src/i18n/dictionary.ts +1 -1
- package/src/i18n/locales/ar.ts +1 -1
- package/src/i18n/locales/fr.ts +1 -1
- package/src/i18n/locales/hr.ts +308 -0
- package/src/i18n/locales/index.ts +15 -14
- package/src/i18n/locales/is.ts +1 -1
- package/src/i18n/locales/ja.ts +1 -1
- package/src/i18n/locales/ko.ts +1 -1
- package/src/i18n/locales/nl.ts +1 -1
- package/src/i18n/locales/pl.ts +1 -1
- package/src/i18n/locales/pt.ts +1 -1
- package/src/i18n/locales/ru.ts +1 -1
- package/src/i18n/locales/vi.ts +1 -1
- package/src/i18n/locales/zh.ts +1 -1
- package/src/index.ts +45 -44
- package/src/pm-nodes/BlockContainer.ts +3 -647
- package/src/pm-nodes/BlockGroup.ts +2 -2
- package/src/pm-nodes/index.ts +3 -3
- package/src/schema/blocks/createSpec.ts +8 -7
- package/src/schema/blocks/internal.ts +9 -9
- package/src/schema/blocks/types.ts +4 -4
- package/src/schema/index.ts +10 -10
- package/src/schema/inlineContent/createSpec.ts +9 -10
- package/src/schema/inlineContent/internal.ts +3 -3
- package/src/schema/inlineContent/types.ts +2 -2
- package/src/schema/styles/createSpec.ts +4 -3
- package/src/schema/styles/internal.ts +1 -1
- package/types/src/api/blockManipulation/commands/insertBlocks/insertBlocks.d.ts +4 -0
- package/types/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.d.ts +7 -0
- package/types/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.d.ts +1 -0
- package/types/src/api/blockManipulation/commands/moveBlock/moveBlock.d.ts +5 -0
- package/types/src/api/blockManipulation/commands/moveBlock/moveBlock.test.d.ts +1 -0
- package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.d.ts +7 -0
- package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.d.ts +1 -0
- package/types/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.d.ts +7 -0
- package/types/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.d.ts +1 -0
- package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +5 -0
- package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.test.d.ts +1 -0
- package/types/src/api/blockManipulation/commands/updateBlock/updateBlock.d.ts +11 -0
- package/types/src/api/blockManipulation/commands/updateBlock/updateBlock.test.d.ts +1 -0
- package/types/src/api/blockManipulation/insertContentAt.d.ts +6 -0
- package/types/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.d.ts +5 -0
- package/types/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.d.ts +1 -0
- package/types/src/api/blockManipulation/setupTestEnv.d.ts +492 -0
- package/types/src/api/clipboard/fromClipboard/fileDropExtension.d.ts +3 -3
- package/types/src/api/clipboard/fromClipboard/handleFileInsertion.d.ts +1 -1
- package/types/src/api/clipboard/fromClipboard/pasteExtension.d.ts +2 -2
- package/types/src/api/clipboard/toClipboard/copyExtension.d.ts +5 -5
- package/types/src/api/exporters/html/externalHTMLExporter.d.ts +7 -9
- package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +6 -10
- package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +10 -0
- package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +11 -0
- package/types/src/api/exporters/markdown/markdownExporter.d.ts +3 -3
- package/types/src/api/getBlockInfoFromPos.d.ts +63 -20
- package/types/src/api/nodeConversions/blockToNode.d.ts +15 -0
- package/types/src/api/nodeConversions/fragmentToBlocks.d.ts +7 -0
- package/types/src/api/nodeConversions/nodeToBlock.d.ts +16 -0
- package/types/src/api/parsers/html/parseHTML.d.ts +2 -2
- package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -2
- package/types/src/api/testUtil/cases/customBlocks.d.ts +39 -39
- package/types/src/api/testUtil/cases/customInlineContent.d.ts +35 -35
- package/types/src/api/testUtil/cases/customStyles.d.ts +35 -35
- package/types/src/api/testUtil/cases/defaultSchema.d.ts +2 -2
- package/types/src/api/testUtil/index.d.ts +6 -6
- package/types/src/api/testUtil/partialBlockTestUtil.d.ts +4 -4
- package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +4 -4
- package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +4 -4
- package/types/src/blocks/FileBlockContent/fileBlockHelpers.d.ts +2 -2
- package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +2 -2
- package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +4 -4
- package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +2 -2
- package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +2 -2
- package/types/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.d.ts +2 -2
- package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +2 -2
- package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +2 -2
- package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +2 -2
- package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +4 -4
- package/types/src/blocks/defaultBlockHelpers.d.ts +3 -3
- package/types/src/blocks/defaultBlockTypeGuards.d.ts +4 -4
- package/types/src/blocks/defaultBlocks.d.ts +38 -38
- package/types/src/blocks/defaultProps.d.ts +1 -1
- package/types/src/editor/BlockNoteEditor.d.ts +28 -16
- package/types/src/editor/BlockNoteExtensions.d.ts +3 -3
- package/types/src/editor/BlockNoteSchema.d.ts +4 -4
- package/types/src/editor/BlockNoteTipTapEditor.d.ts +2 -2
- package/types/src/editor/cursorPositionTypes.d.ts +3 -2
- package/types/src/editor/selectionTypes.d.ts +2 -2
- package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +1 -1
- package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +4 -4
- package/types/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.d.ts +5 -0
- package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +4 -4
- package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +2 -0
- package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +1 -1
- package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +12 -28
- package/types/src/extensions/SideMenu/dragging.d.ts +17 -0
- package/types/src/extensions/SuggestionMenu/DefaultSuggestionItem.d.ts +1 -1
- package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +4 -4
- package/types/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.d.ts +3 -3
- package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +4 -4
- package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +4 -4
- package/types/src/extensions/TextColor/TextColorMark.d.ts +1 -1
- package/types/src/i18n/dictionary.d.ts +1 -1
- package/types/src/i18n/locales/ar.d.ts +1 -1
- package/types/src/i18n/locales/fr.d.ts +1 -1
- package/types/src/i18n/locales/hr.d.ts +239 -0
- package/types/src/i18n/locales/index.d.ts +15 -14
- package/types/src/i18n/locales/is.d.ts +1 -1
- package/types/src/i18n/locales/ja.d.ts +1 -1
- package/types/src/i18n/locales/ko.d.ts +1 -1
- package/types/src/i18n/locales/nl.d.ts +1 -1
- package/types/src/i18n/locales/pl.d.ts +1 -1
- package/types/src/i18n/locales/pt.d.ts +1 -1
- package/types/src/i18n/locales/ru.d.ts +1 -1
- package/types/src/i18n/locales/vi.d.ts +1 -1
- package/types/src/i18n/locales/zh.d.ts +1 -1
- package/types/src/index.d.ts +45 -44
- package/types/src/pm-nodes/BlockContainer.d.ts +2 -16
- package/types/src/pm-nodes/BlockGroup.d.ts +1 -1
- package/types/src/pm-nodes/index.d.ts +3 -3
- package/types/src/schema/blocks/createSpec.d.ts +5 -5
- package/types/src/schema/blocks/internal.d.ts +5 -5
- package/types/src/schema/blocks/types.d.ts +4 -4
- package/types/src/schema/index.d.ts +10 -10
- package/types/src/schema/inlineContent/createSpec.d.ts +3 -3
- package/types/src/schema/inlineContent/internal.d.ts +2 -2
- package/types/src/schema/inlineContent/types.d.ts +2 -2
- package/types/src/schema/styles/createSpec.d.ts +1 -1
- package/types/src/schema/styles/internal.d.ts +1 -1
- package/src/api/blockManipulation/__snapshots__/blockManipulation.test.ts.snap +0 -714
- package/src/api/blockManipulation/blockManipulation.test.ts +0 -292
- package/src/api/blockManipulation/blockManipulation.ts +0 -350
- package/src/api/exporters/html/util/sharedHTMLConversion.ts +0 -130
- package/src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts +0 -218
- package/src/api/getCurrentBlockContentType.ts +0 -14
- package/types/src/api/blockManipulation/blockManipulation.d.ts +0 -14
- package/types/src/api/exporters/html/util/sharedHTMLConversion.d.ts +0 -9
- package/types/src/api/exporters/html/util/simplifyBlocksRehypePlugin.d.ts +0 -16
- package/types/src/api/getCurrentBlockContentType.d.ts +0 -2
- package/types/src/api/nodeConversions/nodeConversions.d.ts +0 -24
- package/types/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.d.ts +0 -2
- /package/types/src/api/blockManipulation/{blockManipulation.test.d.ts → commands/insertBlocks/insertBlocks.test.d.ts} +0 -0
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { PluginView } from "@tiptap/pm/state";
|
|
2
|
-
import {
|
|
3
|
-
import { NodeSelection, Plugin, PluginKey, Selection } from "prosemirror-state";
|
|
2
|
+
import { EditorState, Plugin, PluginKey } from "prosemirror-state";
|
|
4
3
|
import { EditorView } from "prosemirror-view";
|
|
5
|
-
import * as pmView from "prosemirror-view";
|
|
6
4
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
import { Block } from "../../blocks/defaultBlocks.js";
|
|
6
|
+
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
|
|
7
|
+
import { UiElementPosition } from "../../extensions-shared/UiElementPosition.js";
|
|
8
|
+
import {
|
|
9
|
+
BlockSchema,
|
|
10
|
+
InlineContentSchema,
|
|
11
|
+
StyleSchema,
|
|
12
|
+
} from "../../schema/index.js";
|
|
13
|
+
import { EventEmitter } from "../../util/EventEmitter.js";
|
|
14
|
+
import { initializeESMDependencies } from "../../util/esmDependencies.js";
|
|
15
|
+
import {
|
|
16
|
+
dragStart,
|
|
17
|
+
getDraggableBlockFromElement,
|
|
18
|
+
unsetDragImage,
|
|
19
|
+
} from "./dragging.js";
|
|
19
20
|
|
|
20
21
|
export type SideMenuState<
|
|
21
22
|
BSchema extends BlockSchema,
|
|
@@ -26,230 +27,49 @@ export type SideMenuState<
|
|
|
26
27
|
block: Block<BSchema, I, S>;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const getBlockFromMousePos = (
|
|
31
|
+
mousePos: {
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
},
|
|
31
35
|
view: EditorView
|
|
32
|
-
) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
) {
|
|
39
|
-
element = element.parentElement;
|
|
40
|
-
}
|
|
41
|
-
if (element.getAttribute?.("data-node-type") !== "blockContainer") {
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
return { node: element as HTMLElement, id: element.getAttribute("data-id")! };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function blockPositionFromElement(element: Element, view: EditorView) {
|
|
48
|
-
const block = getDraggableBlockFromElement(element, view);
|
|
49
|
-
|
|
50
|
-
if (block && block.node.nodeType === 1) {
|
|
51
|
-
// TODO: this uses undocumented PM APIs? do we need this / let's add docs?
|
|
52
|
-
const docView = (view as any).docView;
|
|
53
|
-
const desc = docView.nearestDesc(block.node, true);
|
|
54
|
-
if (!desc || desc === docView) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
return desc.posBefore;
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function blockPositionsFromSelection(selection: Selection, doc: Node) {
|
|
63
|
-
// Absolute positions just before the first block spanned by the selection, and just after the last block. Having the
|
|
64
|
-
// selection start and end just before and just after the target blocks ensures no whitespace/line breaks are left
|
|
65
|
-
// behind after dragging & dropping them.
|
|
66
|
-
let beforeFirstBlockPos: number;
|
|
67
|
-
let afterLastBlockPos: number;
|
|
68
|
-
|
|
69
|
-
// Even the user starts dragging blocks but drops them in the same place, the selection will still be moved just
|
|
70
|
-
// before & just after the blocks spanned by the selection, and therefore doesn't need to change if they try to drag
|
|
71
|
-
// the same blocks again. If this happens, the anchor & head move out of the block content node they were originally
|
|
72
|
-
// in. If the anchor should update but the head shouldn't and vice versa, it means the user selection is outside a
|
|
73
|
-
// block content node, which should never happen.
|
|
74
|
-
const selectionStartInBlockContent =
|
|
75
|
-
doc.resolve(selection.from).node().type.spec.group === "blockContent";
|
|
76
|
-
const selectionEndInBlockContent =
|
|
77
|
-
doc.resolve(selection.to).node().type.spec.group === "blockContent";
|
|
78
|
-
|
|
79
|
-
// Ensures that entire outermost nodes are selected if the selection spans multiple nesting levels.
|
|
80
|
-
const minDepth = Math.min(selection.$anchor.depth, selection.$head.depth);
|
|
81
|
-
|
|
82
|
-
if (selectionStartInBlockContent && selectionEndInBlockContent) {
|
|
83
|
-
// Absolute positions at the start of the first block in the selection and at the end of the last block. User
|
|
84
|
-
// selections will always start and end in block content nodes, but we want the start and end positions of their
|
|
85
|
-
// parent block nodes, which is why minDepth - 1 is used.
|
|
86
|
-
const startFirstBlockPos = selection.$from.start(minDepth - 1);
|
|
87
|
-
const endLastBlockPos = selection.$to.end(minDepth - 1);
|
|
88
|
-
|
|
89
|
-
// Shifting start and end positions by one moves them just outside the first and last selected blocks.
|
|
90
|
-
beforeFirstBlockPos = doc.resolve(startFirstBlockPos - 1).pos;
|
|
91
|
-
afterLastBlockPos = doc.resolve(endLastBlockPos + 1).pos;
|
|
92
|
-
} else {
|
|
93
|
-
beforeFirstBlockPos = selection.from;
|
|
94
|
-
afterLastBlockPos = selection.to;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return { from: beforeFirstBlockPos, to: afterLastBlockPos };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function setDragImage(view: EditorView, from: number, to = from) {
|
|
101
|
-
if (from === to) {
|
|
102
|
-
// Moves to position to be just after the first (and only) selected block.
|
|
103
|
-
to += view.state.doc.resolve(from + 1).node().nodeSize;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Parent element is cloned to remove all unselected children without affecting the editor content.
|
|
107
|
-
const parentClone = view.domAtPos(from).node.cloneNode(true) as Element;
|
|
108
|
-
const parent = view.domAtPos(from).node as Element;
|
|
109
|
-
|
|
110
|
-
const getElementIndex = (parentElement: Element, targetElement: Element) =>
|
|
111
|
-
Array.prototype.indexOf.call(parentElement.children, targetElement);
|
|
112
|
-
|
|
113
|
-
const firstSelectedBlockIndex = getElementIndex(
|
|
114
|
-
parent,
|
|
115
|
-
// Expects from position to be just before the first selected block.
|
|
116
|
-
view.domAtPos(from + 1).node.parentElement!
|
|
117
|
-
);
|
|
118
|
-
const lastSelectedBlockIndex = getElementIndex(
|
|
119
|
-
parent,
|
|
120
|
-
// Expects to position to be just after the last selected block.
|
|
121
|
-
view.domAtPos(to - 1).node.parentElement!
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
for (let i = parent.childElementCount - 1; i >= 0; i--) {
|
|
125
|
-
if (i > lastSelectedBlockIndex || i < firstSelectedBlockIndex) {
|
|
126
|
-
parentClone.removeChild(parentClone.children[i]);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// dataTransfer.setDragImage(element) only works if element is attached to the DOM.
|
|
131
|
-
unsetDragImage(view.root);
|
|
132
|
-
dragImageElement = parentClone;
|
|
133
|
-
|
|
134
|
-
// TODO: This is hacky, need a better way of assigning classes to the editor so that they can also be applied to the
|
|
135
|
-
// drag preview.
|
|
136
|
-
const classes = view.dom.className.split(" ");
|
|
137
|
-
const inheritedClasses = classes
|
|
138
|
-
.filter(
|
|
139
|
-
(className) =>
|
|
140
|
-
className !== "ProseMirror" &&
|
|
141
|
-
className !== "bn-root" &&
|
|
142
|
-
className !== "bn-editor"
|
|
143
|
-
)
|
|
144
|
-
.join(" ");
|
|
145
|
-
|
|
146
|
-
dragImageElement.className =
|
|
147
|
-
dragImageElement.className + " bn-drag-preview " + inheritedClasses;
|
|
148
|
-
|
|
149
|
-
if (view.root instanceof ShadowRoot) {
|
|
150
|
-
view.root.appendChild(dragImageElement);
|
|
151
|
-
} else {
|
|
152
|
-
view.root.body.appendChild(dragImageElement);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function unsetDragImage(rootEl: Document | ShadowRoot) {
|
|
157
|
-
if (dragImageElement !== undefined) {
|
|
158
|
-
if (rootEl instanceof ShadowRoot) {
|
|
159
|
-
rootEl.removeChild(dragImageElement);
|
|
160
|
-
} else {
|
|
161
|
-
rootEl.body.removeChild(dragImageElement);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
dragImageElement = undefined;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function dragStart<
|
|
169
|
-
BSchema extends BlockSchema,
|
|
170
|
-
I extends InlineContentSchema,
|
|
171
|
-
S extends StyleSchema
|
|
172
|
-
>(
|
|
173
|
-
e: { dataTransfer: DataTransfer | null; clientY: number },
|
|
174
|
-
editor: BlockNoteEditor<BSchema, I, S>
|
|
175
|
-
) {
|
|
176
|
-
if (!e.dataTransfer) {
|
|
36
|
+
): { node: HTMLElement; id: string } | undefined => {
|
|
37
|
+
// Editor itself may have padding or other styling which affects
|
|
38
|
+
// size/position, so we get the boundingRect of the first child (i.e. the
|
|
39
|
+
// blockGroup that wraps all blocks in the editor) for more accurate side
|
|
40
|
+
// menu placement.
|
|
41
|
+
if (!view.dom.firstChild) {
|
|
177
42
|
return;
|
|
178
43
|
}
|
|
179
44
|
|
|
180
|
-
const
|
|
45
|
+
const editorBoundingBox = (
|
|
46
|
+
view.dom.firstChild as HTMLElement
|
|
47
|
+
).getBoundingClientRect();
|
|
181
48
|
|
|
182
|
-
|
|
49
|
+
// this.horizontalPosAnchor = editorBoundingBox.x;
|
|
183
50
|
|
|
51
|
+
// Gets block at mouse cursor's vertical position.
|
|
184
52
|
const coords = {
|
|
185
53
|
left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor
|
|
186
|
-
top:
|
|
54
|
+
top: mousePos.y,
|
|
187
55
|
};
|
|
188
56
|
|
|
189
57
|
const elements = view.root.elementsFromPoint(coords.left, coords.top);
|
|
190
|
-
let
|
|
58
|
+
let block = undefined;
|
|
191
59
|
|
|
192
60
|
for (const element of elements) {
|
|
193
61
|
if (view.dom.contains(element)) {
|
|
194
|
-
|
|
62
|
+
block = getDraggableBlockFromElement(element, view);
|
|
195
63
|
break;
|
|
196
64
|
}
|
|
197
65
|
}
|
|
198
66
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const pos = blockPositionFromElement(blockEl.node, view);
|
|
204
|
-
if (pos != null) {
|
|
205
|
-
const selection = view.state.selection;
|
|
206
|
-
const doc = view.state.doc;
|
|
207
|
-
|
|
208
|
-
const { from, to } = blockPositionsFromSelection(selection, doc);
|
|
209
|
-
|
|
210
|
-
const draggedBlockInSelection = from <= pos && pos < to;
|
|
211
|
-
const multipleBlocksSelected =
|
|
212
|
-
selection.$anchor.node() !== selection.$head.node() ||
|
|
213
|
-
selection instanceof MultipleNodeSelection;
|
|
214
|
-
|
|
215
|
-
if (draggedBlockInSelection && multipleBlocksSelected) {
|
|
216
|
-
view.dispatch(
|
|
217
|
-
view.state.tr.setSelection(MultipleNodeSelection.create(doc, from, to))
|
|
218
|
-
);
|
|
219
|
-
setDragImage(view, from, to);
|
|
220
|
-
} else {
|
|
221
|
-
view.dispatch(
|
|
222
|
-
view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos))
|
|
223
|
-
);
|
|
224
|
-
setDragImage(view, pos);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const selectedSlice = view.state.selection.content();
|
|
228
|
-
const schema = editor.pmSchema;
|
|
229
|
-
|
|
230
|
-
const clipboardHML = (pmView as any).__serializeForClipboard(
|
|
231
|
-
view,
|
|
232
|
-
selectedSlice
|
|
233
|
-
).dom.innerHTML;
|
|
234
|
-
|
|
235
|
-
const externalHTMLExporter = createExternalHTMLExporter(schema, editor);
|
|
236
|
-
const externalHTML = externalHTMLExporter.exportProseMirrorFragment(
|
|
237
|
-
selectedSlice.content,
|
|
238
|
-
{}
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
const plainText = cleanHTMLToMarkdown(externalHTML);
|
|
242
|
-
|
|
243
|
-
e.dataTransfer.clearData();
|
|
244
|
-
e.dataTransfer.setData("blocknote/html", clipboardHML);
|
|
245
|
-
e.dataTransfer.setData("text/html", externalHTML);
|
|
246
|
-
e.dataTransfer.setData("text/plain", plainText);
|
|
247
|
-
e.dataTransfer.effectAllowed = "move";
|
|
248
|
-
e.dataTransfer.setDragImage(dragImageElement!, 0, 0);
|
|
249
|
-
view.dragging = { slice: selectedSlice, move: true };
|
|
250
|
-
}
|
|
251
|
-
}
|
|
67
|
+
return block;
|
|
68
|
+
};
|
|
252
69
|
|
|
70
|
+
/**
|
|
71
|
+
* With the sidemenu plugin we can position a menu next to a hovered block.
|
|
72
|
+
*/
|
|
253
73
|
export class SideMenuView<
|
|
254
74
|
BSchema extends BlockSchema,
|
|
255
75
|
I extends InlineContentSchema,
|
|
@@ -259,20 +79,10 @@ export class SideMenuView<
|
|
|
259
79
|
public state?: SideMenuState<BSchema, I, S>;
|
|
260
80
|
public readonly emitUpdate: (state: SideMenuState<BSchema, I, S>) => void;
|
|
261
81
|
|
|
262
|
-
private needUpdate = false;
|
|
263
82
|
private mousePos: { x: number; y: number } | undefined;
|
|
264
83
|
|
|
265
|
-
// When true, the drag handle with be anchored at the same level as root elements
|
|
266
|
-
// When false, the drag handle with be just to the left of the element
|
|
267
|
-
// TODO: Is there any case where we want this to be false?
|
|
268
|
-
private horizontalPosAnchoredAtRoot: boolean;
|
|
269
|
-
private horizontalPosAnchor: number | undefined;
|
|
270
|
-
|
|
271
84
|
private hoveredBlock: HTMLElement | undefined;
|
|
272
85
|
|
|
273
|
-
// Used to check if currently dragged content comes from this editor instance.
|
|
274
|
-
public isDragging = false;
|
|
275
|
-
|
|
276
86
|
public menuFrozen = false;
|
|
277
87
|
|
|
278
88
|
constructor(
|
|
@@ -288,14 +98,6 @@ export class SideMenuView<
|
|
|
288
98
|
emitUpdate(this.state);
|
|
289
99
|
};
|
|
290
100
|
|
|
291
|
-
this.horizontalPosAnchoredAtRoot = true;
|
|
292
|
-
|
|
293
|
-
if (this.pmView.dom.firstChild) {
|
|
294
|
-
this.horizontalPosAnchor = (
|
|
295
|
-
this.pmView.dom.firstChild as HTMLElement
|
|
296
|
-
).getBoundingClientRect().x;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
101
|
this.pmView.root.addEventListener(
|
|
300
102
|
"drop",
|
|
301
103
|
this.onDrop as EventListener,
|
|
@@ -306,7 +108,6 @@ export class SideMenuView<
|
|
|
306
108
|
this.onDragOver as EventListener
|
|
307
109
|
);
|
|
308
110
|
initializeESMDependencies();
|
|
309
|
-
this.pmView.dom.addEventListener("dragstart", this.onDragStart);
|
|
310
111
|
|
|
311
112
|
// Shows or updates menu position whenever the cursor moves, if the menu isn't frozen.
|
|
312
113
|
this.pmView.root.addEventListener(
|
|
@@ -315,64 +116,31 @@ export class SideMenuView<
|
|
|
315
116
|
true
|
|
316
117
|
);
|
|
317
118
|
|
|
318
|
-
// Unfreezes the menu whenever the user clicks.
|
|
319
|
-
this.pmView.dom.addEventListener("mousedown", this.onMouseDown);
|
|
320
119
|
// Hides and unfreezes the menu whenever the user presses a key.
|
|
321
120
|
this.pmView.root.addEventListener(
|
|
322
121
|
"keydown",
|
|
323
122
|
this.onKeyDown as EventListener,
|
|
324
123
|
true
|
|
325
124
|
);
|
|
326
|
-
|
|
327
|
-
// Setting capture=true ensures that any parent container of the editor that
|
|
328
|
-
// gets scrolled will trigger the scroll event. Scroll events do not bubble
|
|
329
|
-
// and so won't propagate to the document by default.
|
|
330
|
-
this.pmView.root.addEventListener("scroll", this.onScroll, true);
|
|
331
125
|
}
|
|
332
126
|
|
|
333
|
-
updateState = () => {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
127
|
+
updateState = (state: SideMenuState<BSchema, I, S>) => {
|
|
128
|
+
this.state = state;
|
|
129
|
+
this.emitUpdate(this.state);
|
|
130
|
+
};
|
|
337
131
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
// blockGroup that wraps all blocks in the editor) for more accurate side
|
|
341
|
-
// menu placement.
|
|
342
|
-
if (!this.pmView.dom.firstChild) {
|
|
132
|
+
updateStateFromMousePos = () => {
|
|
133
|
+
if (this.menuFrozen || !this.mousePos) {
|
|
343
134
|
return;
|
|
344
135
|
}
|
|
345
136
|
|
|
346
|
-
const
|
|
347
|
-
this.pmView.dom.firstChild as HTMLElement
|
|
348
|
-
).getBoundingClientRect();
|
|
349
|
-
|
|
350
|
-
this.horizontalPosAnchor = editorBoundingBox.x;
|
|
351
|
-
|
|
352
|
-
// Gets block at mouse cursor's vertical position.
|
|
353
|
-
const coords = {
|
|
354
|
-
left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor
|
|
355
|
-
top: this.mousePos.y,
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
const elements = this.pmView.root.elementsFromPoint(
|
|
359
|
-
coords.left,
|
|
360
|
-
coords.top
|
|
361
|
-
);
|
|
362
|
-
let block = undefined;
|
|
363
|
-
|
|
364
|
-
for (const element of elements) {
|
|
365
|
-
if (this.pmView.dom.contains(element)) {
|
|
366
|
-
block = getDraggableBlockFromElement(element, this.pmView);
|
|
367
|
-
break;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
137
|
+
const block = getBlockFromMousePos(this.mousePos, this.pmView);
|
|
370
138
|
|
|
371
139
|
// Closes the menu if the mouse cursor is beyond the editor vertically.
|
|
372
140
|
if (!block || !this.editor.isEditable) {
|
|
373
141
|
if (this.state?.show) {
|
|
374
142
|
this.state.show = false;
|
|
375
|
-
this.
|
|
143
|
+
this.updateState(this.state);
|
|
376
144
|
}
|
|
377
145
|
|
|
378
146
|
return;
|
|
@@ -396,16 +164,19 @@ export class SideMenuView<
|
|
|
396
164
|
return;
|
|
397
165
|
}
|
|
398
166
|
|
|
167
|
+
// TODO: needed?
|
|
168
|
+
|
|
399
169
|
// Shows or updates elements.
|
|
400
170
|
if (this.editor.isEditable) {
|
|
171
|
+
const editorBoundingBox = (
|
|
172
|
+
this.pmView.dom.firstChild as HTMLElement
|
|
173
|
+
).getBoundingClientRect();
|
|
401
174
|
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
402
175
|
|
|
403
|
-
this.
|
|
176
|
+
this.updateState({
|
|
404
177
|
show: true,
|
|
405
178
|
referencePos: new DOMRect(
|
|
406
|
-
|
|
407
|
-
? this.horizontalPosAnchor
|
|
408
|
-
: blockContentBoundingBox.x,
|
|
179
|
+
editorBoundingBox.x,
|
|
409
180
|
blockContentBoundingBox.y,
|
|
410
181
|
blockContentBoundingBox.width,
|
|
411
182
|
blockContentBoundingBox.height
|
|
@@ -413,18 +184,10 @@ export class SideMenuView<
|
|
|
413
184
|
block: this.editor.getBlock(
|
|
414
185
|
this.hoveredBlock!.getAttribute("data-id")!
|
|
415
186
|
)!,
|
|
416
|
-
};
|
|
417
|
-
this.needUpdate = true;
|
|
187
|
+
});
|
|
418
188
|
}
|
|
419
189
|
};
|
|
420
190
|
|
|
421
|
-
/**
|
|
422
|
-
* Sets isDragging when dragging text.
|
|
423
|
-
*/
|
|
424
|
-
onDragStart = () => {
|
|
425
|
-
this.isDragging = true;
|
|
426
|
-
};
|
|
427
|
-
|
|
428
191
|
/**
|
|
429
192
|
* If the event is outside the editor contents,
|
|
430
193
|
* we dispatch a fake event, so that we can still drop the content
|
|
@@ -433,7 +196,10 @@ export class SideMenuView<
|
|
|
433
196
|
onDrop = (event: DragEvent) => {
|
|
434
197
|
this.editor._tiptapEditor.commands.blur();
|
|
435
198
|
|
|
436
|
-
if (
|
|
199
|
+
if (
|
|
200
|
+
(event as any).synthetic ||
|
|
201
|
+
!event.dataTransfer?.types.includes("blocknote/html")
|
|
202
|
+
) {
|
|
437
203
|
return;
|
|
438
204
|
}
|
|
439
205
|
|
|
@@ -442,8 +208,6 @@ export class SideMenuView<
|
|
|
442
208
|
top: event.clientY,
|
|
443
209
|
});
|
|
444
210
|
|
|
445
|
-
this.isDragging = false;
|
|
446
|
-
|
|
447
211
|
if (!pos || pos.inside === -1) {
|
|
448
212
|
const evt = new Event("drop", event) as any;
|
|
449
213
|
const editorBoundingBox = (
|
|
@@ -472,7 +236,10 @@ export class SideMenuView<
|
|
|
472
236
|
* when dragging / dropping to the side of the editor
|
|
473
237
|
*/
|
|
474
238
|
onDragOver = (event: DragEvent) => {
|
|
475
|
-
if (
|
|
239
|
+
if (
|
|
240
|
+
(event as any).synthetic ||
|
|
241
|
+
!event.dataTransfer?.types.includes("blocknote/html")
|
|
242
|
+
) {
|
|
476
243
|
return;
|
|
477
244
|
}
|
|
478
245
|
const pos = this.pmView.posAtCoords({
|
|
@@ -500,15 +267,6 @@ export class SideMenuView<
|
|
|
500
267
|
// Typing in editor should hide side menu
|
|
501
268
|
this.state.show = false;
|
|
502
269
|
this.emitUpdate(this.state);
|
|
503
|
-
this.menuFrozen = false;
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
onMouseDown = () => {
|
|
508
|
-
if (this.state && this.state.show && this.menuFrozen) {
|
|
509
|
-
this.menuFrozen = false;
|
|
510
|
-
this.state.show = false;
|
|
511
|
-
this.emitUpdate(this.state);
|
|
512
270
|
}
|
|
513
271
|
};
|
|
514
272
|
|
|
@@ -528,7 +286,8 @@ export class SideMenuView<
|
|
|
528
286
|
this.mousePos.y > editorOuterBoundingBox.top &&
|
|
529
287
|
this.mousePos.y < editorOuterBoundingBox.bottom;
|
|
530
288
|
|
|
531
|
-
|
|
289
|
+
// TODO: remove parentElement, but then we need to remove padding from boundingbox or find a different solution
|
|
290
|
+
const editorWrapper = this.pmView.dom!.parentElement!;
|
|
532
291
|
|
|
533
292
|
// Doesn't update if the mouse hovers an element that's over the editor but
|
|
534
293
|
// isn't a part of it or the side menu.
|
|
@@ -552,29 +311,7 @@ export class SideMenuView<
|
|
|
552
311
|
return;
|
|
553
312
|
}
|
|
554
313
|
|
|
555
|
-
this.
|
|
556
|
-
|
|
557
|
-
if (this.needUpdate) {
|
|
558
|
-
this.emitUpdate(this.state!);
|
|
559
|
-
this.needUpdate = false;
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
onScroll = () => {
|
|
564
|
-
if (this.state?.show && this.hoveredBlock?.firstChild) {
|
|
565
|
-
const blockContent = this.hoveredBlock.firstChild as HTMLElement;
|
|
566
|
-
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
567
|
-
|
|
568
|
-
this.state.referencePos = new DOMRect(
|
|
569
|
-
this.horizontalPosAnchoredAtRoot
|
|
570
|
-
? this.horizontalPosAnchor
|
|
571
|
-
: blockContentBoundingBox.x,
|
|
572
|
-
blockContentBoundingBox.y,
|
|
573
|
-
blockContentBoundingBox.width,
|
|
574
|
-
blockContentBoundingBox.height
|
|
575
|
-
);
|
|
576
|
-
this.emitUpdate(this.state);
|
|
577
|
-
}
|
|
314
|
+
this.updateStateFromMousePos();
|
|
578
315
|
};
|
|
579
316
|
|
|
580
317
|
// Needed in cases where the editor state updates without the mouse cursor
|
|
@@ -584,14 +321,10 @@ export class SideMenuView<
|
|
|
584
321
|
// allowing the user to click the button again without moving the cursor. This
|
|
585
322
|
// would otherwise not update the side menu, and so clicking the button again
|
|
586
323
|
// would attempt to remove the same block again, causing an error.
|
|
587
|
-
update() {
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (this.needUpdate && this.state && prevBlockId !== this.state.block.id) {
|
|
593
|
-
this.emitUpdate(this.state);
|
|
594
|
-
this.needUpdate = false;
|
|
324
|
+
update(_view: EditorView, prevState: EditorState) {
|
|
325
|
+
const docChanged = !prevState.doc.eq(this.pmView.state.doc);
|
|
326
|
+
if (docChanged && this.state?.show) {
|
|
327
|
+
this.updateStateFromMousePos();
|
|
595
328
|
}
|
|
596
329
|
}
|
|
597
330
|
|
|
@@ -609,73 +342,18 @@ export class SideMenuView<
|
|
|
609
342
|
"dragover",
|
|
610
343
|
this.onDragOver as EventListener
|
|
611
344
|
);
|
|
612
|
-
|
|
345
|
+
|
|
613
346
|
this.pmView.root.removeEventListener(
|
|
614
347
|
"drop",
|
|
615
348
|
this.onDrop as EventListener,
|
|
616
349
|
true
|
|
617
350
|
);
|
|
618
|
-
this.pmView.root.removeEventListener("scroll", this.onScroll, true);
|
|
619
|
-
this.pmView.dom.removeEventListener("mousedown", this.onMouseDown);
|
|
620
351
|
this.pmView.root.removeEventListener(
|
|
621
352
|
"keydown",
|
|
622
353
|
this.onKeyDown as EventListener,
|
|
623
354
|
true
|
|
624
355
|
);
|
|
625
356
|
}
|
|
626
|
-
|
|
627
|
-
addBlock() {
|
|
628
|
-
if (this.state?.show) {
|
|
629
|
-
this.state.show = false;
|
|
630
|
-
this.emitUpdate(this.state);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
if (!this.hoveredBlock?.firstChild) {
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
const blockContent = this.hoveredBlock.firstChild as HTMLElement;
|
|
638
|
-
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
639
|
-
|
|
640
|
-
const pos = this.pmView.posAtCoords({
|
|
641
|
-
left: blockContentBoundingBox.left + blockContentBoundingBox.width / 2,
|
|
642
|
-
top: blockContentBoundingBox.top + blockContentBoundingBox.height / 2,
|
|
643
|
-
});
|
|
644
|
-
if (!pos) {
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
const blockInfo = getBlockInfoFromPos(
|
|
649
|
-
this.editor._tiptapEditor.state.doc,
|
|
650
|
-
pos.pos
|
|
651
|
-
);
|
|
652
|
-
if (blockInfo === undefined) {
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
const { contentNode, startPos, endPos } = blockInfo;
|
|
657
|
-
|
|
658
|
-
// Creates a new block if current one is not empty for the suggestion menu to open in.
|
|
659
|
-
if (
|
|
660
|
-
contentNode.type.spec.content !== "inline*" ||
|
|
661
|
-
contentNode.textContent.length !== 0
|
|
662
|
-
) {
|
|
663
|
-
const newBlockInsertionPos = endPos + 1;
|
|
664
|
-
const newBlockContentPos = newBlockInsertionPos + 2;
|
|
665
|
-
|
|
666
|
-
this.editor._tiptapEditor
|
|
667
|
-
.chain()
|
|
668
|
-
.BNCreateBlock(newBlockInsertionPos)
|
|
669
|
-
// .BNUpdateBlock(newBlockContentPos, { type: "paragraph", props: {} })
|
|
670
|
-
.setTextSelection(newBlockContentPos)
|
|
671
|
-
.run();
|
|
672
|
-
} else {
|
|
673
|
-
this.editor._tiptapEditor.commands.setTextSelection(startPos + 1);
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
// Focuses and activates the slash menu.
|
|
677
|
-
this.editor.openSuggestionMenu("/");
|
|
678
|
-
}
|
|
679
357
|
}
|
|
680
358
|
|
|
681
359
|
export const sideMenuPluginKey = new PluginKey("SideMenuPlugin");
|
|
@@ -705,12 +383,6 @@ export class SideMenuProsemirrorPlugin<
|
|
|
705
383
|
return this.on("update", callback);
|
|
706
384
|
}
|
|
707
385
|
|
|
708
|
-
/**
|
|
709
|
-
* If the block is empty, opens the slash menu. If the block has content,
|
|
710
|
-
* creates a new block below and opens the slash menu in it.
|
|
711
|
-
*/
|
|
712
|
-
addBlock = () => this.view!.addBlock();
|
|
713
|
-
|
|
714
386
|
/**
|
|
715
387
|
* Handles drag & drop events for blocks.
|
|
716
388
|
*/
|
|
@@ -718,7 +390,6 @@ export class SideMenuProsemirrorPlugin<
|
|
|
718
390
|
dataTransfer: DataTransfer | null;
|
|
719
391
|
clientY: number;
|
|
720
392
|
}) => {
|
|
721
|
-
this.view!.isDragging = true;
|
|
722
393
|
dragStart(event, this.editor);
|
|
723
394
|
};
|
|
724
395
|
|