@blocknote/core 0.15.11 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocknote.js +3349 -2773
- 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__/childToParent.html +1 -0
- package/src/api/clipboard/__snapshots__/childrenToNextParent.html +1 -0
- package/src/api/clipboard/__snapshots__/childrenToNextParentsChildren.html +1 -0
- package/src/api/clipboard/__snapshots__/image.html +1 -0
- package/src/api/clipboard/__snapshots__/multipleStyledText.html +1 -0
- package/src/api/clipboard/__snapshots__/nestedImage.html +1 -0
- package/src/api/clipboard/__snapshots__/partialChildToParent.html +1 -0
- package/src/api/clipboard/__snapshots__/styledText.html +1 -0
- package/src/api/clipboard/__snapshots__/tableAllCells.html +1 -0
- package/src/api/clipboard/__snapshots__/tableCell.html +1 -0
- package/src/api/clipboard/__snapshots__/tableCellText.html +1 -0
- package/src/api/clipboard/__snapshots__/tableRow.html +1 -0
- package/src/api/clipboard/__snapshots__/unstyledText.html +1 -0
- package/src/api/clipboard/clipboard.test.ts +283 -0
- package/src/api/{parsers → clipboard/fromClipboard}/fileDropExtension.ts +8 -4
- package/src/api/{parsers → clipboard/fromClipboard}/handleFileInsertion.ts +12 -7
- package/src/api/{parsers → clipboard/fromClipboard}/pasteExtension.ts +19 -8
- package/src/api/clipboard/toClipboard/copyExtension.ts +243 -0
- 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 -87
- package/src/api/exporters/html/htmlConversion.test.ts +19 -156
- package/src/api/exporters/html/internalHTMLSerializer.ts +21 -69
- 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 +5 -8
- 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/__snapshots__/pasted/complex.json +319 -0
- package/src/api/parsers/markdown/__snapshots__/pasted/issue-226-1.json +81 -0
- package/src/api/parsers/{html/__snapshots__/paste/parse-deep-nested-content.json → markdown/__snapshots__/pasted/issue-226-2.json} +35 -110
- package/src/api/parsers/markdown/__snapshots__/pasted/nested.json +81 -0
- package/src/api/parsers/markdown/__snapshots__/pasted/non-nested.json +81 -0
- package/src/api/parsers/markdown/__snapshots__/pasted/styled.json +61 -0
- package/src/api/parsers/markdown/parseMarkdown.test.ts +16 -1
- 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/api/testUtil/paste.ts +46 -0
- 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 -5
- 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/editor/transformPasted.ts +34 -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 +333 -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 -402
- 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 +24 -14
- 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/clipboard.test.d.ts +1 -0
- package/types/src/api/clipboard/fromClipboard/fileDropExtension.d.ts +6 -0
- package/types/src/api/{parsers → clipboard/fromClipboard}/handleFileInsertion.d.ts +2 -2
- package/types/src/api/clipboard/fromClipboard/pasteExtension.d.ts +6 -0
- package/types/src/api/clipboard/toClipboard/copyExtension.d.ts +12 -0
- package/types/src/api/exporters/html/externalHTMLExporter.d.ts +7 -8
- 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/api/testUtil/paste.d.ts +2 -0
- 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/editor/transformPasted.d.ts +8 -1
- 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/copyExtension.ts +0 -164
- package/src/api/exporters/html/__snapshots_fragment_edge_cases__/selectionLeavesBlockChildren.html +0 -1
- package/src/api/exporters/html/__snapshots_fragment_edge_cases__/selectionSpansBlocksChildren.html +0 -1
- 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/src/api/parsers/html/__snapshots__/paste/parse-google-docs-html.json +0 -476
- package/types/src/api/blockManipulation/blockManipulation.d.ts +0 -14
- package/types/src/api/exporters/copyExtension.d.ts +0 -6
- 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/api/parsers/fileDropExtension.d.ts +0 -6
- package/types/src/api/parsers/pasteExtension.d.ts +0 -6
- package/types/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.d.ts +0 -2
- /package/src/api/{exporters/html/__snapshots_fragment_edge_cases__/selectionWithinBlockChildren.html → clipboard/__snapshots__/multipleChildren.html} +0 -0
- /package/src/api/{parsers → clipboard/fromClipboard}/acceptedMIMETypes.ts +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/list-test.json → list-test.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-basic-block-types.json → parse-basic-block-types.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-div-with-inline-content.json → parse-div-with-inline-content.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-divs.json → parse-divs.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-fake-image-caption.json → parse-fake-image-caption.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-image-in-paragraph.json → parse-image-in-paragraph.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-mixed-nested-lists.json → parse-mixed-nested-lists.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-nested-lists-with-paragraphs.json → parse-nested-lists-with-paragraphs.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-nested-lists.json → parse-nested-lists.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-notion-html.json → parse-notion-html.json} +0 -0
- /package/src/api/parsers/html/__snapshots__/{paste/parse-two-divs.json → parse-two-divs.json} +0 -0
- /package/types/src/api/blockManipulation/{blockManipulation.test.d.ts → commands/insertBlocks/insertBlocks.test.d.ts} +0 -0
- /package/types/src/api/{parsers → clipboard/fromClipboard}/acceptedMIMETypes.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
4
|
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import { EventEmitter } from "../../util/EventEmitter";
|
|
15
|
-
import { initializeESMDependencies } from "../../util/esmDependencies";
|
|
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,231 +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 internalHTMLSerializer = createInternalHTMLSerializer(schema, editor);
|
|
231
|
-
const internalHTML = internalHTMLSerializer.serializeProseMirrorFragment(
|
|
232
|
-
selectedSlice.content,
|
|
233
|
-
{}
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
const externalHTMLExporter = createExternalHTMLExporter(schema, editor);
|
|
237
|
-
const externalHTML = externalHTMLExporter.exportProseMirrorFragment(
|
|
238
|
-
selectedSlice.content,
|
|
239
|
-
{}
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
const plainText = cleanHTMLToMarkdown(externalHTML);
|
|
243
|
-
|
|
244
|
-
e.dataTransfer.clearData();
|
|
245
|
-
e.dataTransfer.setData("blocknote/html", internalHTML);
|
|
246
|
-
e.dataTransfer.setData("text/html", externalHTML);
|
|
247
|
-
e.dataTransfer.setData("text/plain", plainText);
|
|
248
|
-
e.dataTransfer.effectAllowed = "move";
|
|
249
|
-
e.dataTransfer.setDragImage(dragImageElement!, 0, 0);
|
|
250
|
-
view.dragging = { slice: selectedSlice, move: true };
|
|
251
|
-
}
|
|
252
|
-
}
|
|
67
|
+
return block;
|
|
68
|
+
};
|
|
253
69
|
|
|
70
|
+
/**
|
|
71
|
+
* With the sidemenu plugin we can position a menu next to a hovered block.
|
|
72
|
+
*/
|
|
254
73
|
export class SideMenuView<
|
|
255
74
|
BSchema extends BlockSchema,
|
|
256
75
|
I extends InlineContentSchema,
|
|
@@ -260,20 +79,10 @@ export class SideMenuView<
|
|
|
260
79
|
public state?: SideMenuState<BSchema, I, S>;
|
|
261
80
|
public readonly emitUpdate: (state: SideMenuState<BSchema, I, S>) => void;
|
|
262
81
|
|
|
263
|
-
private needUpdate = false;
|
|
264
82
|
private mousePos: { x: number; y: number } | undefined;
|
|
265
83
|
|
|
266
|
-
// When true, the drag handle with be anchored at the same level as root elements
|
|
267
|
-
// When false, the drag handle with be just to the left of the element
|
|
268
|
-
// TODO: Is there any case where we want this to be false?
|
|
269
|
-
private horizontalPosAnchoredAtRoot: boolean;
|
|
270
|
-
private horizontalPosAnchor: number | undefined;
|
|
271
|
-
|
|
272
84
|
private hoveredBlock: HTMLElement | undefined;
|
|
273
85
|
|
|
274
|
-
// Used to check if currently dragged content comes from this editor instance.
|
|
275
|
-
public isDragging = false;
|
|
276
|
-
|
|
277
86
|
public menuFrozen = false;
|
|
278
87
|
|
|
279
88
|
constructor(
|
|
@@ -289,14 +98,6 @@ export class SideMenuView<
|
|
|
289
98
|
emitUpdate(this.state);
|
|
290
99
|
};
|
|
291
100
|
|
|
292
|
-
this.horizontalPosAnchoredAtRoot = true;
|
|
293
|
-
|
|
294
|
-
if (this.pmView.dom.firstChild) {
|
|
295
|
-
this.horizontalPosAnchor = (
|
|
296
|
-
this.pmView.dom.firstChild as HTMLElement
|
|
297
|
-
).getBoundingClientRect().x;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
101
|
this.pmView.root.addEventListener(
|
|
301
102
|
"drop",
|
|
302
103
|
this.onDrop as EventListener,
|
|
@@ -307,7 +108,6 @@ export class SideMenuView<
|
|
|
307
108
|
this.onDragOver as EventListener
|
|
308
109
|
);
|
|
309
110
|
initializeESMDependencies();
|
|
310
|
-
this.pmView.dom.addEventListener("dragstart", this.onDragStart);
|
|
311
111
|
|
|
312
112
|
// Shows or updates menu position whenever the cursor moves, if the menu isn't frozen.
|
|
313
113
|
this.pmView.root.addEventListener(
|
|
@@ -316,64 +116,31 @@ export class SideMenuView<
|
|
|
316
116
|
true
|
|
317
117
|
);
|
|
318
118
|
|
|
319
|
-
// Unfreezes the menu whenever the user clicks.
|
|
320
|
-
this.pmView.dom.addEventListener("mousedown", this.onMouseDown);
|
|
321
119
|
// Hides and unfreezes the menu whenever the user presses a key.
|
|
322
120
|
this.pmView.root.addEventListener(
|
|
323
121
|
"keydown",
|
|
324
122
|
this.onKeyDown as EventListener,
|
|
325
123
|
true
|
|
326
124
|
);
|
|
327
|
-
|
|
328
|
-
// Setting capture=true ensures that any parent container of the editor that
|
|
329
|
-
// gets scrolled will trigger the scroll event. Scroll events do not bubble
|
|
330
|
-
// and so won't propagate to the document by default.
|
|
331
|
-
this.pmView.root.addEventListener("scroll", this.onScroll, true);
|
|
332
125
|
}
|
|
333
126
|
|
|
334
|
-
updateState = () => {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
127
|
+
updateState = (state: SideMenuState<BSchema, I, S>) => {
|
|
128
|
+
this.state = state;
|
|
129
|
+
this.emitUpdate(this.state);
|
|
130
|
+
};
|
|
338
131
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
// blockGroup that wraps all blocks in the editor) for more accurate side
|
|
342
|
-
// menu placement.
|
|
343
|
-
if (!this.pmView.dom.firstChild) {
|
|
132
|
+
updateStateFromMousePos = () => {
|
|
133
|
+
if (this.menuFrozen || !this.mousePos) {
|
|
344
134
|
return;
|
|
345
135
|
}
|
|
346
136
|
|
|
347
|
-
const
|
|
348
|
-
this.pmView.dom.firstChild as HTMLElement
|
|
349
|
-
).getBoundingClientRect();
|
|
350
|
-
|
|
351
|
-
this.horizontalPosAnchor = editorBoundingBox.x;
|
|
352
|
-
|
|
353
|
-
// Gets block at mouse cursor's vertical position.
|
|
354
|
-
const coords = {
|
|
355
|
-
left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor
|
|
356
|
-
top: this.mousePos.y,
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
const elements = this.pmView.root.elementsFromPoint(
|
|
360
|
-
coords.left,
|
|
361
|
-
coords.top
|
|
362
|
-
);
|
|
363
|
-
let block = undefined;
|
|
364
|
-
|
|
365
|
-
for (const element of elements) {
|
|
366
|
-
if (this.pmView.dom.contains(element)) {
|
|
367
|
-
block = getDraggableBlockFromElement(element, this.pmView);
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
137
|
+
const block = getBlockFromMousePos(this.mousePos, this.pmView);
|
|
371
138
|
|
|
372
139
|
// Closes the menu if the mouse cursor is beyond the editor vertically.
|
|
373
140
|
if (!block || !this.editor.isEditable) {
|
|
374
141
|
if (this.state?.show) {
|
|
375
142
|
this.state.show = false;
|
|
376
|
-
this.
|
|
143
|
+
this.updateState(this.state);
|
|
377
144
|
}
|
|
378
145
|
|
|
379
146
|
return;
|
|
@@ -397,16 +164,19 @@ export class SideMenuView<
|
|
|
397
164
|
return;
|
|
398
165
|
}
|
|
399
166
|
|
|
167
|
+
// TODO: needed?
|
|
168
|
+
|
|
400
169
|
// Shows or updates elements.
|
|
401
170
|
if (this.editor.isEditable) {
|
|
171
|
+
const editorBoundingBox = (
|
|
172
|
+
this.pmView.dom.firstChild as HTMLElement
|
|
173
|
+
).getBoundingClientRect();
|
|
402
174
|
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
403
175
|
|
|
404
|
-
this.
|
|
176
|
+
this.updateState({
|
|
405
177
|
show: true,
|
|
406
178
|
referencePos: new DOMRect(
|
|
407
|
-
|
|
408
|
-
? this.horizontalPosAnchor
|
|
409
|
-
: blockContentBoundingBox.x,
|
|
179
|
+
editorBoundingBox.x,
|
|
410
180
|
blockContentBoundingBox.y,
|
|
411
181
|
blockContentBoundingBox.width,
|
|
412
182
|
blockContentBoundingBox.height
|
|
@@ -414,18 +184,10 @@ export class SideMenuView<
|
|
|
414
184
|
block: this.editor.getBlock(
|
|
415
185
|
this.hoveredBlock!.getAttribute("data-id")!
|
|
416
186
|
)!,
|
|
417
|
-
};
|
|
418
|
-
this.needUpdate = true;
|
|
187
|
+
});
|
|
419
188
|
}
|
|
420
189
|
};
|
|
421
190
|
|
|
422
|
-
/**
|
|
423
|
-
* Sets isDragging when dragging text.
|
|
424
|
-
*/
|
|
425
|
-
onDragStart = () => {
|
|
426
|
-
this.isDragging = true;
|
|
427
|
-
};
|
|
428
|
-
|
|
429
191
|
/**
|
|
430
192
|
* If the event is outside the editor contents,
|
|
431
193
|
* we dispatch a fake event, so that we can still drop the content
|
|
@@ -434,7 +196,10 @@ export class SideMenuView<
|
|
|
434
196
|
onDrop = (event: DragEvent) => {
|
|
435
197
|
this.editor._tiptapEditor.commands.blur();
|
|
436
198
|
|
|
437
|
-
if (
|
|
199
|
+
if (
|
|
200
|
+
(event as any).synthetic ||
|
|
201
|
+
!event.dataTransfer?.types.includes("blocknote/html")
|
|
202
|
+
) {
|
|
438
203
|
return;
|
|
439
204
|
}
|
|
440
205
|
|
|
@@ -443,8 +208,6 @@ export class SideMenuView<
|
|
|
443
208
|
top: event.clientY,
|
|
444
209
|
});
|
|
445
210
|
|
|
446
|
-
this.isDragging = false;
|
|
447
|
-
|
|
448
211
|
if (!pos || pos.inside === -1) {
|
|
449
212
|
const evt = new Event("drop", event) as any;
|
|
450
213
|
const editorBoundingBox = (
|
|
@@ -473,7 +236,10 @@ export class SideMenuView<
|
|
|
473
236
|
* when dragging / dropping to the side of the editor
|
|
474
237
|
*/
|
|
475
238
|
onDragOver = (event: DragEvent) => {
|
|
476
|
-
if (
|
|
239
|
+
if (
|
|
240
|
+
(event as any).synthetic ||
|
|
241
|
+
!event.dataTransfer?.types.includes("blocknote/html")
|
|
242
|
+
) {
|
|
477
243
|
return;
|
|
478
244
|
}
|
|
479
245
|
const pos = this.pmView.posAtCoords({
|
|
@@ -501,15 +267,6 @@ export class SideMenuView<
|
|
|
501
267
|
// Typing in editor should hide side menu
|
|
502
268
|
this.state.show = false;
|
|
503
269
|
this.emitUpdate(this.state);
|
|
504
|
-
this.menuFrozen = false;
|
|
505
|
-
}
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
onMouseDown = () => {
|
|
509
|
-
if (this.state && this.state.show && this.menuFrozen) {
|
|
510
|
-
this.menuFrozen = false;
|
|
511
|
-
this.state.show = false;
|
|
512
|
-
this.emitUpdate(this.state);
|
|
513
270
|
}
|
|
514
271
|
};
|
|
515
272
|
|
|
@@ -529,7 +286,8 @@ export class SideMenuView<
|
|
|
529
286
|
this.mousePos.y > editorOuterBoundingBox.top &&
|
|
530
287
|
this.mousePos.y < editorOuterBoundingBox.bottom;
|
|
531
288
|
|
|
532
|
-
|
|
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!;
|
|
533
291
|
|
|
534
292
|
// Doesn't update if the mouse hovers an element that's over the editor but
|
|
535
293
|
// isn't a part of it or the side menu.
|
|
@@ -553,29 +311,7 @@ export class SideMenuView<
|
|
|
553
311
|
return;
|
|
554
312
|
}
|
|
555
313
|
|
|
556
|
-
this.
|
|
557
|
-
|
|
558
|
-
if (this.needUpdate) {
|
|
559
|
-
this.emitUpdate(this.state!);
|
|
560
|
-
this.needUpdate = false;
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
onScroll = () => {
|
|
565
|
-
if (this.state?.show && this.hoveredBlock?.firstChild) {
|
|
566
|
-
const blockContent = this.hoveredBlock.firstChild as HTMLElement;
|
|
567
|
-
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
568
|
-
|
|
569
|
-
this.state.referencePos = new DOMRect(
|
|
570
|
-
this.horizontalPosAnchoredAtRoot
|
|
571
|
-
? this.horizontalPosAnchor
|
|
572
|
-
: blockContentBoundingBox.x,
|
|
573
|
-
blockContentBoundingBox.y,
|
|
574
|
-
blockContentBoundingBox.width,
|
|
575
|
-
blockContentBoundingBox.height
|
|
576
|
-
);
|
|
577
|
-
this.emitUpdate(this.state);
|
|
578
|
-
}
|
|
314
|
+
this.updateStateFromMousePos();
|
|
579
315
|
};
|
|
580
316
|
|
|
581
317
|
// Needed in cases where the editor state updates without the mouse cursor
|
|
@@ -585,14 +321,10 @@ export class SideMenuView<
|
|
|
585
321
|
// allowing the user to click the button again without moving the cursor. This
|
|
586
322
|
// would otherwise not update the side menu, and so clicking the button again
|
|
587
323
|
// would attempt to remove the same block again, causing an error.
|
|
588
|
-
update() {
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
if (this.needUpdate && this.state && prevBlockId !== this.state.block.id) {
|
|
594
|
-
this.emitUpdate(this.state);
|
|
595
|
-
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();
|
|
596
328
|
}
|
|
597
329
|
}
|
|
598
330
|
|
|
@@ -610,73 +342,18 @@ export class SideMenuView<
|
|
|
610
342
|
"dragover",
|
|
611
343
|
this.onDragOver as EventListener
|
|
612
344
|
);
|
|
613
|
-
|
|
345
|
+
|
|
614
346
|
this.pmView.root.removeEventListener(
|
|
615
347
|
"drop",
|
|
616
348
|
this.onDrop as EventListener,
|
|
617
349
|
true
|
|
618
350
|
);
|
|
619
|
-
this.pmView.root.removeEventListener("scroll", this.onScroll, true);
|
|
620
|
-
this.pmView.dom.removeEventListener("mousedown", this.onMouseDown);
|
|
621
351
|
this.pmView.root.removeEventListener(
|
|
622
352
|
"keydown",
|
|
623
353
|
this.onKeyDown as EventListener,
|
|
624
354
|
true
|
|
625
355
|
);
|
|
626
356
|
}
|
|
627
|
-
|
|
628
|
-
addBlock() {
|
|
629
|
-
if (this.state?.show) {
|
|
630
|
-
this.state.show = false;
|
|
631
|
-
this.emitUpdate(this.state);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
if (!this.hoveredBlock?.firstChild) {
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
const blockContent = this.hoveredBlock.firstChild as HTMLElement;
|
|
639
|
-
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
640
|
-
|
|
641
|
-
const pos = this.pmView.posAtCoords({
|
|
642
|
-
left: blockContentBoundingBox.left + blockContentBoundingBox.width / 2,
|
|
643
|
-
top: blockContentBoundingBox.top + blockContentBoundingBox.height / 2,
|
|
644
|
-
});
|
|
645
|
-
if (!pos) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const blockInfo = getBlockInfoFromPos(
|
|
650
|
-
this.editor._tiptapEditor.state.doc,
|
|
651
|
-
pos.pos
|
|
652
|
-
);
|
|
653
|
-
if (blockInfo === undefined) {
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
const { contentNode, startPos, endPos } = blockInfo;
|
|
658
|
-
|
|
659
|
-
// Creates a new block if current one is not empty for the suggestion menu to open in.
|
|
660
|
-
if (
|
|
661
|
-
contentNode.type.spec.content !== "inline*" ||
|
|
662
|
-
contentNode.textContent.length !== 0
|
|
663
|
-
) {
|
|
664
|
-
const newBlockInsertionPos = endPos + 1;
|
|
665
|
-
const newBlockContentPos = newBlockInsertionPos + 2;
|
|
666
|
-
|
|
667
|
-
this.editor._tiptapEditor
|
|
668
|
-
.chain()
|
|
669
|
-
.BNCreateBlock(newBlockInsertionPos)
|
|
670
|
-
// .BNUpdateBlock(newBlockContentPos, { type: "paragraph", props: {} })
|
|
671
|
-
.setTextSelection(newBlockContentPos)
|
|
672
|
-
.run();
|
|
673
|
-
} else {
|
|
674
|
-
this.editor._tiptapEditor.commands.setTextSelection(startPos + 1);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
// Focuses and activates the slash menu.
|
|
678
|
-
this.editor.openSuggestionMenu("/");
|
|
679
|
-
}
|
|
680
357
|
}
|
|
681
358
|
|
|
682
359
|
export const sideMenuPluginKey = new PluginKey("SideMenuPlugin");
|
|
@@ -706,12 +383,6 @@ export class SideMenuProsemirrorPlugin<
|
|
|
706
383
|
return this.on("update", callback);
|
|
707
384
|
}
|
|
708
385
|
|
|
709
|
-
/**
|
|
710
|
-
* If the block is empty, opens the slash menu. If the block has content,
|
|
711
|
-
* creates a new block below and opens the slash menu in it.
|
|
712
|
-
*/
|
|
713
|
-
addBlock = () => this.view!.addBlock();
|
|
714
|
-
|
|
715
386
|
/**
|
|
716
387
|
* Handles drag & drop events for blocks.
|
|
717
388
|
*/
|
|
@@ -719,7 +390,6 @@ export class SideMenuProsemirrorPlugin<
|
|
|
719
390
|
dataTransfer: DataTransfer | null;
|
|
720
391
|
clientY: number;
|
|
721
392
|
}) => {
|
|
722
|
-
this.view!.isDragging = true;
|
|
723
393
|
dragStart(event, this.editor);
|
|
724
394
|
};
|
|
725
395
|
|