@blocknote/core 0.27.2 → 0.28.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.
@@ -1 +1 @@
1
- {"builtAt":1743885337120,"assets":[{"name":"blocknote.cjs","size":179331},{"name":"comments.cjs","size":11826},{"name":"locales.cjs","size":111456},{"name":"en-D4taoCs4.cjs","size":5539},{"name":"en-D4taoCs4.cjs.map","size":12801},{"name":"comments.cjs.map","size":47589},{"name":"locales.cjs.map","size":233666},{"name":"blocknote.cjs.map","size":844054}],"chunks":[{"id":"a1ee98a","entry":true,"initial":true,"files":["blocknote.cjs"],"names":["blocknote"]},{"id":"1627b02","entry":true,"initial":true,"files":["comments.cjs"],"names":["comments"]},{"id":"9eaffe2","entry":true,"initial":true,"files":["locales.cjs"],"names":["locales"]},{"id":"a1e239a","entry":false,"initial":true,"files":["en-D4taoCs4.cjs"],"names":["en"]}],"modules":[{"name":"./src/util/typescript.ts","size":331,"chunks":["a1ee98a"]},{"name":"./src/api/getBlockInfoFromPos.ts","size":3648,"chunks":["a1ee98a"]},{"name":"./src/extensions/UniqueID/UniqueID.ts","size":9054,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/types.ts","size":302,"chunks":["a1ee98a"]},{"name":"./src/util/table.ts","size":1212,"chunks":["a1ee98a"]},{"name":"./src/util/browser.ts","size":536,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockHelpers.ts","size":1755,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultProps.ts","size":269,"chunks":["a1ee98a"]},{"name":"./src/util/string.ts","size":299,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/internal.ts","size":4130,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/createSpec.ts","size":3609,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/nodeToBlock.ts","size":9521,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/internal.ts","size":1398,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/createSpec.ts","size":2739,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/internal.ts","size":1162,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/createSpec.ts","size":1263,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/tables/tables.ts","size":10346,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/blockToNode.ts","size":6874,"chunks":["a1ee98a"]},{"name":"./src/api/nodeUtil.ts","size":490,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/updateBlock/updateBlock.ts","size":4754,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/serializeBlocksExternalHTML.ts","size":5160,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/externalHTMLExporter.ts","size":886,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/serializeBlocksInternalHTML.ts","size":3264,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/internalHTMLSerializer.ts","size":288,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/parse/parseFigureElement.ts","size":342,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createAddFileButton.ts","size":1725,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createFileNameWithIcon.ts","size":753,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.ts","size":1428,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.ts","size":307,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.ts","size":294,"chunks":["a1ee98a"]},{"name":"./src/blocks/AudioBlockContent/parseAudioElement.ts","size":108,"chunks":["a1ee98a"]},{"name":"./src/blocks/AudioBlockContent/AudioBlockContent.ts","size":3155,"chunks":["a1ee98a"]},{"name":"./src/blocks/CodeBlockContent/CodeBlockContent.ts","size":9013,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/parse/parseEmbedElement.ts","size":108,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/FileBlockContent.ts","size":1460,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.ts","size":4637,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts","size":316,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/parseImageElement.ts","size":175,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/ImageBlockContent.ts","size":3243,"chunks":["a1ee98a"]},{"name":"./src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts","size":854,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorMark.ts","size":946,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorMark.ts","size":866,"chunks":["a1ee98a"]},{"name":"./src/blocks/HeadingBlockContent/HeadingBlockContent.ts","size":3418,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/splitBlock/splitBlock.ts","size":868,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts","size":1429,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts","size":3415,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts","size":7148,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts","size":2207,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts","size":4427,"chunks":["a1ee98a"]},{"name":"./src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts","size":1434,"chunks":["a1ee98a"]},{"name":"./src/blocks/QuoteBlockContent/QuoteBlockContent.ts","size":1927,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableExtension.ts","size":2297,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableBlockContent.ts","size":4708,"chunks":["a1ee98a"]},{"name":"./src/blocks/VideoBlockContent/parseVideoElement.ts","size":175,"chunks":["a1ee98a"]},{"name":"./src/blocks/VideoBlockContent/VideoBlockContent.ts","size":3162,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlocks.ts","size":1163,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockTypeGuards.ts","size":1688,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts","size":7072,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteSchema.ts","size":1044,"chunks":["a1ee98a"]},{"name":"./src/blocks/PageBreakBlockContent/schema.ts","size":350,"chunks":["a1ee98a"]},{"name":"./src/blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.ts","size":536,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts","size":1141,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts","size":5693,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/nestBlock/nestBlock.ts","size":2324,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts","size":2533,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/removeBlocks/removeBlocks.ts","size":123,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/getBlock/getBlock.ts","size":2452,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/insertContentAt.ts","size":1120,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/selections/selection.ts","size":4698,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts","size":2880,"chunks":["a1ee98a"]},{"name":"./src/util/esmDependencies.ts","size":820,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/removeUnderlinesRehypePlugin.ts","size":752,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts","size":969,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/markdownExporter.ts","size":837,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/html/util/nestedLists.ts","size":2174,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/html/parseHTML.ts","size":503,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/markdown/parseMarkdown.ts","size":1201,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/acceptedMIMETypes.ts","size":134,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/handleFileInsertion.ts","size":3917,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/fileDropExtension.ts","size":884,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/handleVSCodePaste.ts","size":661,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/markdown/detectMarkdown.ts","size":1112,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/pasteExtension.ts","size":2109,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/fragmentToBlocks.ts","size":859,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/toClipboard/copyExtension.ts","size":5228,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorExtension.ts","size":819,"chunks":["a1ee98a"]},{"name":"./src/extensions/Collaboration/createCollaborationExtensions.ts","size":3553,"chunks":["a1ee98a"]},{"name":"./src/extensions/Comments/CommentMark.ts","size":1428,"chunks":["a1ee98a"]},{"name":"./src/util/EventEmitter.ts","size":744,"chunks":["a1ee98a"]},{"name":"./src/extensions/Comments/userstore/UserStore.ts","size":1354,"chunks":["a1ee98a"]},{"name":"./src/extensions/Comments/CommentsPlugin.ts","size":7656,"chunks":["a1ee98a"]},{"name":"./src/extensions/FilePanel/FilePanelPlugin.ts","size":3584,"chunks":["a1ee98a"]},{"name":"./src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts","size":5323,"chunks":["a1ee98a"]},{"name":"./src/extensions/HardBreak/HardBreak.ts","size":376,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts","size":3228,"chunks":["a1ee98a"]},{"name":"./src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts","size":18010,"chunks":["a1ee98a"]},{"name":"./src/extensions/LinkToolbar/LinkToolbarPlugin.ts","size":7611,"chunks":["a1ee98a"]},{"name":"./src/extensions/LinkToolbar/protocols.ts","size":172,"chunks":["a1ee98a"]},{"name":"./src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts","size":1195,"chunks":["a1ee98a"]},{"name":"./src/extensions/Placeholder/PlaceholderPlugin.ts","size":3609,"chunks":["a1ee98a"]},{"name":"./src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts","size":4826,"chunks":["a1ee98a"]},{"name":"./src/extensions/ShowSelection/ShowSelectionPlugin.ts","size":967,"chunks":["a1ee98a"]},{"name":"./src/extensions/getDraggableBlockFromElement.ts","size":404,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/MultipleNodeSelection.ts","size":1616,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/dragging.ts","size":4733,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/SideMenuPlugin.ts","size":14087,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/SuggestionPlugin.ts","size":8104,"chunks":["a1ee98a"]},{"name":"./src/extensions/TableHandles/TableHandlesPlugin.ts","size":26718,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextAlignment/TextAlignmentExtension.ts","size":976,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorExtension.ts","size":753,"chunks":["a1ee98a"]},{"name":"./src/extensions/TrailingNode/TrailingNodeExtension.ts","size":1563,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockContainer.ts","size":2038,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockGroup.ts","size":1102,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/Doc.ts","size":90,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteExtensions.ts","size":4928,"chunks":["a1ee98a"]},{"name":"./src/editor/transformPasted.ts","size":2604,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteTipTapEditor.ts","size":3938,"chunks":["a1ee98a"]},{"name":"./src/style.css","size":0,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteEditor.ts","size":31088,"chunks":["a1ee98a"]},{"name":"./src/editor/defaultColors.ts","size":1193,"chunks":["a1ee98a"]},{"name":"./src/exporter/Exporter.ts","size":1075,"chunks":["a1ee98a"]},{"name":"./src/exporter/mapping.ts","size":197,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts","size":1204,"chunks":["a1ee98a"]},{"name":"./src/util/combineByGroup.ts","size":550,"chunks":["a1ee98a"]},{"name":"./src/api/testUtil/partialBlockTestUtil.ts","size":3860,"chunks":["a1ee98a"]},{"name":"./src/index.ts","size":0,"chunks":["a1ee98a"]},{"name":"./src/comments/threadstore/ThreadStoreAuth.ts","size":25,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/DefaultThreadStoreAuth.ts","size":2014,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/ThreadStore.ts","size":77,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/TipTapThreadStore.ts","size":5321,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/yjsHelpers.ts","size":3002,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/YjsThreadStoreBase.ts","size":790,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/RESTYjsThreadStore.ts","size":2069,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/YjsThreadStore.ts","size":7267,"chunks":["1627b02"]},{"name":"./src/comments/index.ts","size":0,"chunks":["1627b02"]},{"name":"./src/i18n/locales/ar.ts","size":7904,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/de.ts","size":8626,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/es.ts","size":8483,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/fr.ts","size":9256,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/hr.ts","size":8518,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/is.ts","size":8246,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/it.ts","size":8582,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/ja.ts","size":7506,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/ko.ts","size":7283,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/nl.ts","size":8481,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/no.ts","size":8357,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/pl.ts","size":8172,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/pt.ts","size":8419,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/ru.ts","size":9103,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/uk.ts","size":9034,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/vi.ts","size":8281,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/zh.ts","size":7200,"chunks":["9eaffe2"]},{"name":"./src/i18n/index.ts","size":0,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/en.ts","size":8004,"chunks":["a1e239a"]}]}
1
+ {"builtAt":1744025813960,"assets":[{"name":"blocknote.cjs","size":180166},{"name":"comments.cjs","size":11826},{"name":"locales.cjs","size":111460},{"name":"en-D4taoCs4.cjs","size":5539},{"name":"en-D4taoCs4.cjs.map","size":12801},{"name":"comments.cjs.map","size":47589},{"name":"locales.cjs.map","size":233670},{"name":"blocknote.cjs.map","size":849985}],"chunks":[{"id":"a1ee98a","entry":true,"initial":true,"files":["blocknote.cjs"],"names":["blocknote"]},{"id":"1627b02","entry":true,"initial":true,"files":["comments.cjs"],"names":["comments"]},{"id":"9eaffe2","entry":true,"initial":true,"files":["locales.cjs"],"names":["locales"]},{"id":"a1e239a","entry":false,"initial":true,"files":["en-D4taoCs4.cjs"],"names":["en"]}],"modules":[{"name":"./src/util/typescript.ts","size":331,"chunks":["a1ee98a"]},{"name":"./src/api/getBlockInfoFromPos.ts","size":3648,"chunks":["a1ee98a"]},{"name":"./src/extensions/UniqueID/UniqueID.ts","size":9054,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/types.ts","size":302,"chunks":["a1ee98a"]},{"name":"./src/util/table.ts","size":1212,"chunks":["a1ee98a"]},{"name":"./src/util/browser.ts","size":536,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockHelpers.ts","size":1755,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultProps.ts","size":269,"chunks":["a1ee98a"]},{"name":"./src/util/string.ts","size":299,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/internal.ts","size":4130,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/createSpec.ts","size":3609,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/nodeToBlock.ts","size":9521,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/internal.ts","size":1398,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/createSpec.ts","size":2739,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/internal.ts","size":1162,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/createSpec.ts","size":1263,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/tables/tables.ts","size":10346,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/blockToNode.ts","size":6874,"chunks":["a1ee98a"]},{"name":"./src/api/nodeUtil.ts","size":490,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/updateBlock/updateBlock.ts","size":4754,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/serializeBlocksExternalHTML.ts","size":5160,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/externalHTMLExporter.ts","size":886,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/serializeBlocksInternalHTML.ts","size":3264,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/internalHTMLSerializer.ts","size":288,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/parse/parseFigureElement.ts","size":342,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createAddFileButton.ts","size":1725,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createFileNameWithIcon.ts","size":753,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.ts","size":1428,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.ts","size":307,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.ts","size":294,"chunks":["a1ee98a"]},{"name":"./src/blocks/AudioBlockContent/parseAudioElement.ts","size":108,"chunks":["a1ee98a"]},{"name":"./src/blocks/AudioBlockContent/AudioBlockContent.ts","size":3155,"chunks":["a1ee98a"]},{"name":"./src/blocks/CodeBlockContent/CodeBlockContent.ts","size":9013,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/parse/parseEmbedElement.ts","size":108,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/FileBlockContent.ts","size":1460,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.ts","size":4637,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts","size":316,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/parseImageElement.ts","size":175,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/ImageBlockContent.ts","size":3243,"chunks":["a1ee98a"]},{"name":"./src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts","size":854,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorMark.ts","size":946,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorMark.ts","size":866,"chunks":["a1ee98a"]},{"name":"./src/blocks/HeadingBlockContent/HeadingBlockContent.ts","size":3418,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/splitBlock/splitBlock.ts","size":868,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts","size":1429,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts","size":3415,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts","size":7148,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts","size":2207,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts","size":4427,"chunks":["a1ee98a"]},{"name":"./src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts","size":1434,"chunks":["a1ee98a"]},{"name":"./src/blocks/QuoteBlockContent/QuoteBlockContent.ts","size":1927,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableExtension.ts","size":2297,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableBlockContent.ts","size":4708,"chunks":["a1ee98a"]},{"name":"./src/blocks/VideoBlockContent/parseVideoElement.ts","size":175,"chunks":["a1ee98a"]},{"name":"./src/blocks/VideoBlockContent/VideoBlockContent.ts","size":3162,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlocks.ts","size":1163,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockTypeGuards.ts","size":1688,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts","size":7072,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteSchema.ts","size":1044,"chunks":["a1ee98a"]},{"name":"./src/blocks/PageBreakBlockContent/schema.ts","size":350,"chunks":["a1ee98a"]},{"name":"./src/blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.ts","size":536,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts","size":1141,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts","size":5693,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/nestBlock/nestBlock.ts","size":2324,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts","size":2533,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/removeBlocks/removeBlocks.ts","size":123,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/getBlock/getBlock.ts","size":2452,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/insertContentAt.ts","size":1120,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/selections/selection.ts","size":4698,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts","size":2880,"chunks":["a1ee98a"]},{"name":"./src/util/esmDependencies.ts","size":820,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/removeUnderlinesRehypePlugin.ts","size":752,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts","size":969,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/markdownExporter.ts","size":837,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/html/util/nestedLists.ts","size":2174,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/html/parseHTML.ts","size":503,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/markdown/parseMarkdown.ts","size":1201,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/acceptedMIMETypes.ts","size":134,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/handleFileInsertion.ts","size":3917,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/fileDropExtension.ts","size":884,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/handleVSCodePaste.ts","size":661,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/markdown/detectMarkdown.ts","size":1112,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/fromClipboard/pasteExtension.ts","size":2109,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/fragmentToBlocks.ts","size":859,"chunks":["a1ee98a"]},{"name":"./src/api/clipboard/toClipboard/copyExtension.ts","size":5228,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorExtension.ts","size":819,"chunks":["a1ee98a"]},{"name":"./src/extensions/Collaboration/createCollaborationExtensions.ts","size":3553,"chunks":["a1ee98a"]},{"name":"./src/extensions/Comments/CommentMark.ts","size":1428,"chunks":["a1ee98a"]},{"name":"./src/util/EventEmitter.ts","size":744,"chunks":["a1ee98a"]},{"name":"./src/extensions/Comments/userstore/UserStore.ts","size":1354,"chunks":["a1ee98a"]},{"name":"./src/extensions/Comments/CommentsPlugin.ts","size":7656,"chunks":["a1ee98a"]},{"name":"./src/extensions/FilePanel/FilePanelPlugin.ts","size":3584,"chunks":["a1ee98a"]},{"name":"./src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts","size":5323,"chunks":["a1ee98a"]},{"name":"./src/extensions/HardBreak/HardBreak.ts","size":376,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts","size":3228,"chunks":["a1ee98a"]},{"name":"./src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts","size":18010,"chunks":["a1ee98a"]},{"name":"./src/extensions/LinkToolbar/LinkToolbarPlugin.ts","size":7611,"chunks":["a1ee98a"]},{"name":"./src/extensions/LinkToolbar/protocols.ts","size":172,"chunks":["a1ee98a"]},{"name":"./src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts","size":1195,"chunks":["a1ee98a"]},{"name":"./src/extensions/Placeholder/PlaceholderPlugin.ts","size":3609,"chunks":["a1ee98a"]},{"name":"./src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts","size":4826,"chunks":["a1ee98a"]},{"name":"./src/extensions/ShowSelection/ShowSelectionPlugin.ts","size":967,"chunks":["a1ee98a"]},{"name":"./src/extensions/getDraggableBlockFromElement.ts","size":404,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/MultipleNodeSelection.ts","size":1616,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/dragging.ts","size":4733,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/SideMenuPlugin.ts","size":14087,"chunks":["a1ee98a"]},{"name":"./src/api/positionMapping.ts","size":1638,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/SuggestionPlugin.ts","size":8635,"chunks":["a1ee98a"]},{"name":"./src/extensions/TableHandles/TableHandlesPlugin.ts","size":26718,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextAlignment/TextAlignmentExtension.ts","size":976,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorExtension.ts","size":753,"chunks":["a1ee98a"]},{"name":"./src/extensions/TrailingNode/TrailingNodeExtension.ts","size":1563,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockContainer.ts","size":2038,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockGroup.ts","size":1102,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/Doc.ts","size":90,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteExtensions.ts","size":4928,"chunks":["a1ee98a"]},{"name":"./src/editor/transformPasted.ts","size":2604,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteTipTapEditor.ts","size":3938,"chunks":["a1ee98a"]},{"name":"./src/style.css","size":0,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteEditor.ts","size":31088,"chunks":["a1ee98a"]},{"name":"./src/editor/defaultColors.ts","size":1193,"chunks":["a1ee98a"]},{"name":"./src/exporter/Exporter.ts","size":1075,"chunks":["a1ee98a"]},{"name":"./src/exporter/mapping.ts","size":197,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts","size":1204,"chunks":["a1ee98a"]},{"name":"./src/util/combineByGroup.ts","size":550,"chunks":["a1ee98a"]},{"name":"./src/api/testUtil/partialBlockTestUtil.ts","size":3860,"chunks":["a1ee98a"]},{"name":"./src/index.ts","size":0,"chunks":["a1ee98a"]},{"name":"./src/comments/threadstore/ThreadStoreAuth.ts","size":25,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/DefaultThreadStoreAuth.ts","size":2014,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/ThreadStore.ts","size":77,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/TipTapThreadStore.ts","size":5321,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/yjsHelpers.ts","size":3002,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/YjsThreadStoreBase.ts","size":790,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/RESTYjsThreadStore.ts","size":2069,"chunks":["1627b02"]},{"name":"./src/comments/threadstore/yjs/YjsThreadStore.ts","size":7267,"chunks":["1627b02"]},{"name":"./src/comments/index.ts","size":0,"chunks":["1627b02"]},{"name":"./src/i18n/locales/ar.ts","size":7904,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/de.ts","size":8624,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/es.ts","size":8483,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/fr.ts","size":9256,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/hr.ts","size":8518,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/is.ts","size":8246,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/it.ts","size":8582,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/ja.ts","size":7506,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/ko.ts","size":7283,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/nl.ts","size":8481,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/no.ts","size":8357,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/pl.ts","size":8172,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/pt.ts","size":8419,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/ru.ts","size":9103,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/uk.ts","size":9034,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/vi.ts","size":8281,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/zh.ts","size":7200,"chunks":["9eaffe2"]},{"name":"./src/i18n/index.ts","size":0,"chunks":["9eaffe2"]},{"name":"./src/i18n/locales/en.ts","size":8004,"chunks":["a1e239a"]}]}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/core"
12
12
  },
13
13
  "license": "MPL-2.0",
14
- "version": "0.27.2",
14
+ "version": "0.28.0",
15
15
  "files": [
16
16
  "dist",
17
17
  "types",
@@ -0,0 +1,370 @@
1
+ import { beforeEach, afterEach, describe, expect, it, vi } from "vitest";
2
+ import * as Y from "yjs";
3
+ import { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
4
+ import { trackPosition } from "./positionMapping.js";
5
+
6
+ describe("PositionStorage with local editor", () => {
7
+ let editor: BlockNoteEditor;
8
+
9
+ beforeEach(() => {
10
+ editor = BlockNoteEditor.create();
11
+ editor.mount(document.createElement("div"));
12
+ });
13
+
14
+ afterEach(() => {
15
+ editor.mount(undefined);
16
+ editor._tiptapEditor.destroy();
17
+ });
18
+
19
+ describe("mount and unmount", () => {
20
+ it("should register transaction handler on creation", () => {
21
+ editor._tiptapEditor.on = vi.fn();
22
+ trackPosition(editor, 0);
23
+
24
+ expect(editor._tiptapEditor.on).toHaveBeenCalledWith(
25
+ "transaction",
26
+ expect.any(Function)
27
+ );
28
+ });
29
+ });
30
+
31
+ describe("set and get positions", () => {
32
+ it("should store and retrieve positions without Y.js", () => {
33
+ const getPos = trackPosition(editor, 10);
34
+
35
+ expect(getPos()).toBe(10);
36
+ });
37
+
38
+ it("should handle right side positions", () => {
39
+ const getPos = trackPosition(editor, 10, "right");
40
+
41
+ expect(getPos()).toBe(10);
42
+ });
43
+ });
44
+
45
+ it("should update mapping for local transactions before the position", () => {
46
+ // Set initial content
47
+ editor.insertBlocks(
48
+ [
49
+ {
50
+ id: "1",
51
+ type: "paragraph",
52
+ content: [
53
+ {
54
+ type: "text",
55
+ text: "Hello World",
56
+ styles: {},
57
+ },
58
+ ],
59
+ },
60
+ ],
61
+ editor.document[0],
62
+ "before"
63
+ );
64
+
65
+ // Start tracking
66
+ const getPos = trackPosition(editor, 10);
67
+
68
+ // Move the cursor to the start of the document
69
+ editor.setTextCursorPosition(editor.document[0], "start");
70
+
71
+ // Insert text at the start of the document
72
+ editor.insertInlineContent([
73
+ {
74
+ type: "text",
75
+ text: "Test",
76
+ styles: {},
77
+ },
78
+ ]);
79
+
80
+ // Position should be updated according to mapping
81
+ expect(getPos()).toBe(14);
82
+ });
83
+
84
+ it("should not update mapping for local transactions after the position", () => {
85
+ // Set initial content
86
+ editor.insertBlocks(
87
+ [
88
+ {
89
+ id: "1",
90
+ type: "paragraph",
91
+ content: [
92
+ {
93
+ type: "text",
94
+ text: "Hello World",
95
+ styles: {},
96
+ },
97
+ ],
98
+ },
99
+ ],
100
+ editor.document[0],
101
+ "before"
102
+ );
103
+ // Start tracking
104
+ const getPos = trackPosition(editor, 10);
105
+
106
+ // Move the cursor to the end of the document
107
+ editor.setTextCursorPosition(editor.document[0], "end");
108
+
109
+ // Insert text at the end of the document
110
+ editor.insertInlineContent([
111
+ {
112
+ type: "text",
113
+ text: "Test",
114
+ styles: {},
115
+ },
116
+ ]);
117
+
118
+ // Position should not be updated
119
+ expect(getPos()).toBe(10);
120
+ });
121
+
122
+ it("should track positions on each side", () => {
123
+ editor.replaceBlocks(editor.document, [
124
+ {
125
+ type: "paragraph",
126
+ content: "Hello World",
127
+ },
128
+ ]);
129
+
130
+ // Store position at "Hello| World"
131
+ const getCursorPos = trackPosition(editor, 6);
132
+ const getStartPos = trackPosition(editor, 3);
133
+ const getStartRightPos = trackPosition(editor, 3, "right");
134
+ const getPosAfterPos = trackPosition(editor, 4);
135
+ const getPosAfterRightPos = trackPosition(editor, 4, "right");
136
+ // Insert text at the beginning
137
+ editor._tiptapEditor.commands.insertContentAt(3, "Test ");
138
+
139
+ // Position should be updated
140
+ expect(getCursorPos()).toBe(11); // 6 + 5 ("Test " length)
141
+ expect(getStartPos()).toBe(3); // 3
142
+ expect(getStartRightPos()).toBe(8); // 3 + 5 ("Test " length)
143
+ expect(getPosAfterPos()).toBe(9); // 4 + 5 ("Test " length)
144
+ expect(getPosAfterRightPos()).toBe(9); // 4 + 5 ("Test " length)
145
+ });
146
+
147
+ it("should handle multiple transactions", () => {
148
+ editor.replaceBlocks(editor.document, [
149
+ {
150
+ type: "paragraph",
151
+ content: "Hello World",
152
+ },
153
+ ]);
154
+
155
+ // Store position at "Hello| World"
156
+ const getCursorPos = trackPosition(editor, 6);
157
+ const getStartPos = trackPosition(editor, 3);
158
+ const getStartRightPos = trackPosition(editor, 3, "right");
159
+ const getPosAfterPos = trackPosition(editor, 4);
160
+ const getPosAfterRightPos = trackPosition(editor, 4, "right");
161
+
162
+ // Insert text at the beginning
163
+ editor._tiptapEditor.commands.insertContentAt(3, "T");
164
+ editor._tiptapEditor.commands.insertContentAt(4, "e");
165
+ editor._tiptapEditor.commands.insertContentAt(5, "s");
166
+ editor._tiptapEditor.commands.insertContentAt(6, "t");
167
+ editor._tiptapEditor.commands.insertContentAt(7, " ");
168
+
169
+ // Position should be updated
170
+ expect(getCursorPos()).toBe(11); // 6 + 5 ("Test " length)
171
+ expect(getStartPos()).toBe(3); // 3
172
+ expect(getStartRightPos()).toBe(8); // 3 + 5 ("Test " length)
173
+ expect(getPosAfterPos()).toBe(9); // 4 + 5 ("Test " length)
174
+ expect(getPosAfterRightPos()).toBe(9); // 4 + 5 ("Test " length)
175
+ });
176
+ });
177
+
178
+ describe("PositionStorage with remote editor", () => {
179
+ // Function to sync two documents
180
+ function syncDocs(sourceDoc: Y.Doc, targetDoc: Y.Doc) {
181
+ // Create update message from source
182
+ const update = Y.encodeStateAsUpdate(sourceDoc);
183
+
184
+ // Apply update to target
185
+ Y.applyUpdate(targetDoc, update);
186
+ }
187
+
188
+ // Set up two-way sync
189
+ function setupTwoWaySync(doc1: Y.Doc, doc2: Y.Doc) {
190
+ // Sync initial states
191
+ syncDocs(doc1, doc2);
192
+ syncDocs(doc2, doc1);
193
+
194
+ // Set up observers for future changes
195
+ doc1.on("update", (update: Uint8Array) => {
196
+ Y.applyUpdate(doc2, update);
197
+ });
198
+
199
+ doc2.on("update", (update: Uint8Array) => {
200
+ Y.applyUpdate(doc1, update);
201
+ });
202
+ }
203
+
204
+ describe("remote editor", () => {
205
+ let localEditor: BlockNoteEditor;
206
+ let remoteEditor: BlockNoteEditor;
207
+ let ydoc: Y.Doc;
208
+ let remoteYdoc: Y.Doc;
209
+
210
+ beforeEach(() => {
211
+ ydoc = new Y.Doc();
212
+ remoteYdoc = new Y.Doc();
213
+ // Create a mock editor
214
+ localEditor = BlockNoteEditor.create({
215
+ collaboration: {
216
+ fragment: ydoc.getXmlFragment("doc"),
217
+ user: { color: "#ff0000", name: "Local User" },
218
+ provider: undefined,
219
+ },
220
+ });
221
+ const div = document.createElement("div");
222
+ localEditor.mount(div);
223
+
224
+ remoteEditor = BlockNoteEditor.create({
225
+ collaboration: {
226
+ fragment: remoteYdoc.getXmlFragment("doc"),
227
+ user: { color: "#ff0000", name: "Remote User" },
228
+ provider: undefined,
229
+ },
230
+ });
231
+
232
+ const remoteDiv = document.createElement("div");
233
+ remoteEditor.mount(remoteDiv);
234
+ setupTwoWaySync(ydoc, remoteYdoc);
235
+ });
236
+
237
+ afterEach(() => {
238
+ ydoc.destroy();
239
+ remoteYdoc.destroy();
240
+ localEditor.mount(undefined);
241
+ localEditor._tiptapEditor.destroy();
242
+ remoteEditor.mount(undefined);
243
+ remoteEditor._tiptapEditor.destroy();
244
+ });
245
+
246
+ it("should update the local position when collaborating", () => {
247
+ localEditor.replaceBlocks(localEditor.document, [
248
+ {
249
+ type: "paragraph",
250
+ content: "Hello World",
251
+ },
252
+ ]);
253
+
254
+ // Store position at "Hello| World"
255
+ const getCursorPos = trackPosition(localEditor, 6);
256
+ // Store position at "|Hello World"
257
+ const getStartPos = trackPosition(localEditor, 3);
258
+ // Store position at "|Hello World" (but on the right side)
259
+ const getStartRightPos = trackPosition(localEditor, 3, "right");
260
+ // Store position at "H|ello World"
261
+ const getPosAfterPos = trackPosition(localEditor, 4);
262
+ // Store position at "H|ello World" (but on the right side)
263
+ const getPosAfterRightPos = trackPosition(localEditor, 4, "right");
264
+
265
+ // Insert text at the beginning
266
+ localEditor._tiptapEditor.commands.insertContentAt(3, "Test ");
267
+
268
+ // Position should be updated
269
+ expect(getCursorPos()).toBe(11); // 6 + 5 ("Test " length)
270
+ expect(getStartPos()).toBe(3); // 3
271
+ expect(getStartRightPos()).toBe(8); // 3 + 5 ("Test " length)
272
+ expect(getPosAfterPos()).toBe(9); // 4 + 5 ("Test " length)
273
+ expect(getPosAfterRightPos()).toBe(9); // 4 + 5 ("Test " length)
274
+ });
275
+
276
+ it("should handle multiple transactions when collaborating", () => {
277
+ localEditor.replaceBlocks(localEditor.document, [
278
+ {
279
+ type: "paragraph",
280
+ content: "Hello World",
281
+ },
282
+ ]);
283
+
284
+ // Store position at "Hello| World"
285
+ const getCursorPos = trackPosition(localEditor, 6);
286
+ // Store position at "|Hello World"
287
+ const getStartPos = trackPosition(localEditor, 3);
288
+ // Store position at "|Hello World" (but on the right side)
289
+ const getStartRightPos = trackPosition(localEditor, 3, "right");
290
+ // Store position at "H|ello World"
291
+ const getPosAfterPos = trackPosition(localEditor, 4);
292
+ // Store position at "H|ello World" (but on the right side)
293
+ const getPosAfterRightPos = trackPosition(localEditor, 4, "right");
294
+
295
+ // Insert text at the beginning
296
+ localEditor._tiptapEditor.commands.insertContentAt(3, "T");
297
+ localEditor._tiptapEditor.commands.insertContentAt(4, "e");
298
+ localEditor._tiptapEditor.commands.insertContentAt(5, "s");
299
+ localEditor._tiptapEditor.commands.insertContentAt(6, "t");
300
+ localEditor._tiptapEditor.commands.insertContentAt(7, " ");
301
+
302
+ // Position should be updated
303
+ expect(getCursorPos()).toBe(11); // 6 + 5 ("Test " length)
304
+ expect(getStartPos()).toBe(3); // 3
305
+ expect(getStartRightPos()).toBe(8); // 3 + 5 ("Test " length)
306
+ expect(getPosAfterPos()).toBe(9); // 4 + 5 ("Test " length)
307
+ expect(getPosAfterRightPos()).toBe(9); // 4 + 5 ("Test " length)
308
+ });
309
+
310
+ it("should update the local position from a remote transaction", () => {
311
+ remoteEditor.replaceBlocks(remoteEditor.document, [
312
+ {
313
+ type: "paragraph",
314
+ content: "Hello World",
315
+ },
316
+ ]);
317
+
318
+ // Store position at "Hello| World"
319
+ const getCursorPos = trackPosition(localEditor, 6);
320
+ // Store position at "|Hello World"
321
+ const getStartPos = trackPosition(localEditor, 3);
322
+ // Store position at "|Hello World" (but on the right side)
323
+ const getStartRightPos = trackPosition(localEditor, 3, "right");
324
+ // Store position at "H|ello World"
325
+ const getPosAfterPos = trackPosition(localEditor, 4);
326
+ // Store position at "H|ello World" (but on the right side)
327
+ const getPosAfterRightPos = trackPosition(localEditor, 4, "right");
328
+
329
+ // Insert text at the beginning
330
+ localEditor._tiptapEditor.commands.insertContentAt(3, "Test ");
331
+
332
+ // Position should be updated
333
+ expect(getCursorPos()).toBe(11); // 6 + 5 ("Test " length)
334
+ expect(getStartPos()).toBe(3); // 3
335
+ expect(getStartRightPos()).toBe(8); // 3 + 5 ("Test " length)
336
+ expect(getPosAfterPos()).toBe(9); // 4 + 5 ("Test " length)
337
+ expect(getPosAfterRightPos()).toBe(9); // 4 + 5 ("Test " length)
338
+ });
339
+
340
+ it("should update the remote position from a remote transaction", () => {
341
+ remoteEditor.replaceBlocks(remoteEditor.document, [
342
+ {
343
+ type: "paragraph",
344
+ content: "Hello World",
345
+ },
346
+ ]);
347
+
348
+ // Store position at "Hello| World"
349
+ const getCursorPos = trackPosition(remoteEditor, 6);
350
+ // Store position at "|Hello World"
351
+ const getStartPos = trackPosition(remoteEditor, 3);
352
+ // Store position at "|Hello World" (but on the right side)
353
+ const getStartRightPos = trackPosition(remoteEditor, 3, "right");
354
+ // Store position at "H|ello World"
355
+ const getPosAfterPos = trackPosition(remoteEditor, 4);
356
+ // Store position at "H|ello World" (but on the right side)
357
+ const getPosAfterRightPos = trackPosition(remoteEditor, 4, "right");
358
+
359
+ // Insert text at the beginning
360
+ localEditor._tiptapEditor.commands.insertContentAt(3, "Test ");
361
+
362
+ // Position should be updated
363
+ expect(getCursorPos()).toBe(11); // 6 + 5 ("Test " length)
364
+ expect(getStartPos()).toBe(3); // 3
365
+ expect(getStartRightPos()).toBe(8); // 3 + 5 ("Test " length)
366
+ expect(getPosAfterPos()).toBe(9); // 4 + 5 ("Test " length)
367
+ expect(getPosAfterRightPos()).toBe(9); // 4 + 5 ("Test " length)
368
+ });
369
+ });
370
+ });
@@ -0,0 +1,112 @@
1
+ import { Mapping } from "prosemirror-transform";
2
+ import {
3
+ absolutePositionToRelativePosition,
4
+ relativePositionToAbsolutePosition,
5
+ ySyncPluginKey,
6
+ } from "y-prosemirror";
7
+ import type { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
8
+ import * as Y from "yjs";
9
+ import type { ProsemirrorBinding } from "y-prosemirror";
10
+
11
+ /**
12
+ * This is used to track a mapping for each editor. The mapping stores the mappings for each transaction since the first transaction that was tracked.
13
+ */
14
+ const editorToMapping = new Map<BlockNoteEditor<any, any, any>, Mapping>();
15
+
16
+ /**
17
+ * This initializes a single mapping for an editor instance.
18
+ */
19
+ function getMapping(editor: BlockNoteEditor<any, any, any>) {
20
+ if (editorToMapping.has(editor)) {
21
+ // Mapping already initialized, so we don't need to do anything
22
+ return editorToMapping.get(editor)!;
23
+ }
24
+ const mapping = new Mapping();
25
+ editor._tiptapEditor.on("transaction", ({ transaction }) => {
26
+ mapping.appendMapping(transaction.mapping);
27
+ });
28
+ editor._tiptapEditor.on("destroy", () => {
29
+ // Cleanup the mapping when the editor is destroyed
30
+ editorToMapping.delete(editor);
31
+ });
32
+
33
+ // There only is one mapping per editor, so we can just set it
34
+ editorToMapping.set(editor, mapping);
35
+
36
+ return mapping;
37
+ }
38
+
39
+ /**
40
+ * This is used to keep track of positions of elements in the editor.
41
+ * It is needed because y-prosemirror's sync plugin can disrupt normal prosemirror position mapping.
42
+ *
43
+ * It is specifically made to be able to be used whether the editor is being used in a collaboratively, or single user, providing the same API.
44
+ *
45
+ * @param editor The editor to track the position of.
46
+ * @param position The position to track.
47
+ * @param side The side of the position to track. "left" is the default. "right" would move with the change if the change is in the right direction.
48
+ * @returns A function that returns the position of the element.
49
+ */
50
+ export function trackPosition(
51
+ /**
52
+ * The editor to track the position of.
53
+ */
54
+ editor: BlockNoteEditor<any, any, any>,
55
+ /**
56
+ * The position to track.
57
+ */
58
+ position: number,
59
+ /**
60
+ * This is the side of the position to track. "left" is the default. "right" would move with the change if the change is in the right direction.
61
+ */
62
+ side: "left" | "right" = "left"
63
+ ): () => number {
64
+ const ySyncPluginState = ySyncPluginKey.getState(editor.prosemirrorState) as {
65
+ doc: Y.Doc;
66
+ binding: ProsemirrorBinding;
67
+ };
68
+
69
+ if (!ySyncPluginState) {
70
+ // No y-prosemirror sync plugin, so we need to track the mapping manually
71
+ // This will initialize the mapping for this editor, if needed
72
+ const mapping = getMapping(editor);
73
+
74
+ // This is the start point of tracking the mapping
75
+ const trackedMapLength = mapping.maps.length;
76
+
77
+ return () => {
78
+ const pos = mapping
79
+ // Only read the history of the mapping that we care about
80
+ .slice(trackedMapLength)
81
+ .map(position, side === "left" ? -1 : 1);
82
+
83
+ return pos;
84
+ };
85
+ }
86
+
87
+ const relativePosition = absolutePositionToRelativePosition(
88
+ // Track the position after the position if we are on the right side
89
+ position + (side === "right" ? 1 : 0),
90
+ ySyncPluginState.binding.type,
91
+ ySyncPluginState.binding.mapping
92
+ );
93
+
94
+ return () => {
95
+ const curYSyncPluginState = ySyncPluginKey.getState(
96
+ editor.prosemirrorState
97
+ ) as typeof ySyncPluginState;
98
+ const pos = relativePositionToAbsolutePosition(
99
+ curYSyncPluginState.doc,
100
+ curYSyncPluginState.binding.type,
101
+ relativePosition,
102
+ curYSyncPluginState.binding.mapping
103
+ );
104
+
105
+ // This can happen if the element is garbage collected
106
+ if (pos === null) {
107
+ throw new Error("Position not found, cannot track positions");
108
+ }
109
+
110
+ return pos + (side === "right" ? -1 : 0);
111
+ };
112
+ }
@@ -723,6 +723,7 @@ export class BlockNoteEditor<
723
723
  // but we still need the schema
724
724
  this.pmSchema = getSchema(tiptapOptions.extensions!);
725
725
  }
726
+
726
727
  this.emit("create");
727
728
  }
728
729