@blocknote/core 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/dist/blocknote.cjs +9 -9
  2. package/dist/blocknote.cjs.map +1 -1
  3. package/dist/blocknote.js +2771 -2245
  4. package/dist/blocknote.js.map +1 -1
  5. package/dist/comments.cjs.map +1 -1
  6. package/dist/comments.js.map +1 -1
  7. package/dist/{en-D4taoCs4.cjs → en-BXVKCwYt.cjs} +2 -2
  8. package/dist/en-BXVKCwYt.cjs.map +1 -0
  9. package/dist/{en-B7ycW7c8.js → en-qGo6sk9V.js} +2 -3
  10. package/dist/en-qGo6sk9V.js.map +1 -0
  11. package/dist/locales.cjs +1 -1
  12. package/dist/locales.cjs.map +1 -1
  13. package/dist/locales.js +20 -39
  14. package/dist/locales.js.map +1 -1
  15. package/dist/style.css +1 -1
  16. package/dist/webpack-stats.json +1 -1
  17. package/package.json +8 -7
  18. package/src/api/README.md +1 -1
  19. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.ts +19 -14
  20. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +7 -8
  21. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +3 -3
  22. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +12 -12
  23. package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.ts +14 -14
  24. package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts +16 -16
  25. package/src/api/blockManipulation/commands/nestBlock/nestBlock.ts +8 -8
  26. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.ts +12 -12
  27. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +8 -8
  28. package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +10 -10
  29. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +2 -2
  30. package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +2816 -0
  31. package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +200 -42
  32. package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +104 -34
  33. package/src/api/blockManipulation/getBlock/getBlock.ts +9 -9
  34. package/src/api/blockManipulation/insertContentAt.ts +1 -1
  35. package/src/api/blockManipulation/selections/selection.ts +59 -12
  36. package/src/api/blockManipulation/selections/{textCursorPosition/textCursorPosition.ts → textCursorPosition.ts} +13 -13
  37. package/src/api/blockManipulation/tables/tables.test.ts +106 -106
  38. package/src/api/blockManipulation/tables/tables.ts +35 -35
  39. package/src/api/clipboard/fromClipboard/fileDropExtension.ts +2 -2
  40. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +9 -9
  41. package/src/api/clipboard/fromClipboard/handleVSCodePaste.ts +3 -3
  42. package/src/api/clipboard/fromClipboard/pasteExtension.ts +3 -3
  43. package/src/api/clipboard/toClipboard/copyExtension.ts +22 -22
  44. package/src/api/exporters/html/externalHTMLExporter.ts +6 -6
  45. package/src/api/exporters/html/internalHTMLSerializer.ts +3 -3
  46. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +16 -16
  47. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +14 -14
  48. package/src/api/exporters/markdown/markdownExporter.ts +3 -3
  49. package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +3 -3
  50. package/src/api/getBlockInfoFromPos.ts +6 -6
  51. package/src/api/nodeConversions/blockToNode.ts +31 -28
  52. package/src/api/nodeConversions/fragmentToBlocks.ts +1 -1
  53. package/src/api/nodeConversions/nodeToBlock.ts +240 -41
  54. package/src/api/nodeUtil.test.ts +16 -16
  55. package/src/api/nodeUtil.ts +10 -10
  56. package/src/api/parsers/html/parseHTML.ts +1 -1
  57. package/src/api/parsers/html/util/nestedLists.ts +2 -2
  58. package/src/api/parsers/markdown/parseMarkdown.ts +1 -1
  59. package/src/api/pmUtil.ts +7 -7
  60. package/src/api/positionMapping.test.ts +3 -3
  61. package/src/api/positionMapping.ts +5 -5
  62. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +4 -4
  63. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +18 -18
  64. package/src/blocks/FileBlockContent/FileBlockContent.ts +2 -2
  65. package/src/blocks/FileBlockContent/helpers/parse/parseFigureElement.ts +2 -2
  66. package/src/blocks/FileBlockContent/helpers/render/createAddFileButton.ts +6 -6
  67. package/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.ts +2 -2
  68. package/src/blocks/FileBlockContent/helpers/render/createFileNameWithIcon.ts +1 -1
  69. package/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.ts +7 -7
  70. package/src/blocks/FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.ts +1 -1
  71. package/src/blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.ts +1 -1
  72. package/src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +2 -2
  73. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +6 -6
  74. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +4 -4
  75. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +4 -4
  76. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +10 -10
  77. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  78. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
  79. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +4 -4
  80. package/src/blocks/ListItemBlockContent/getListItemContent.ts +5 -5
  81. package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +1 -1
  82. package/src/blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.ts +3 -3
  83. package/src/blocks/PageBreakBlockContent/schema.ts +2 -2
  84. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +3 -3
  85. package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +4 -4
  86. package/src/blocks/README.md +1 -1
  87. package/src/blocks/TableBlockContent/TableBlockContent.ts +37 -7
  88. package/src/blocks/TableBlockContent/TableExtension.ts +3 -3
  89. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +4 -4
  90. package/src/blocks/defaultBlockHelpers.ts +8 -8
  91. package/src/blocks/defaultBlockTypeGuards.ts +16 -16
  92. package/src/blocks/defaultBlocks.ts +3 -3
  93. package/src/comments/threadstore/DefaultThreadStoreAuth.ts +3 -3
  94. package/src/comments/threadstore/ThreadStore.ts +1 -1
  95. package/src/comments/threadstore/TipTapThreadStore.ts +10 -10
  96. package/src/comments/threadstore/yjs/RESTYjsThreadStore.ts +4 -4
  97. package/src/comments/threadstore/yjs/YjsThreadStore.test.ts +2 -2
  98. package/src/comments/threadstore/yjs/YjsThreadStore.ts +14 -14
  99. package/src/comments/threadstore/yjs/YjsThreadStoreBase.ts +1 -1
  100. package/src/comments/threadstore/yjs/yjsHelpers.ts +6 -6
  101. package/src/editor/Block.css +35 -1
  102. package/src/editor/BlockNoteEditor.test.ts +10 -3
  103. package/src/editor/BlockNoteEditor.ts +95 -38
  104. package/src/editor/BlockNoteExtension.ts +26 -0
  105. package/src/editor/BlockNoteExtensions.ts +38 -22
  106. package/src/editor/BlockNoteSchema.ts +4 -4
  107. package/src/editor/BlockNoteTipTapEditor.ts +33 -12
  108. package/src/editor/README.md +1 -1
  109. package/src/editor/cursorPositionTypes.ts +1 -1
  110. package/src/editor/editor.css +15 -3
  111. package/src/editor/selectionTypes.ts +1 -1
  112. package/src/editor/transformPasted.ts +2 -2
  113. package/src/exporter/Exporter.ts +5 -5
  114. package/src/exporter/mapping.ts +7 -7
  115. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +1 -1
  116. package/src/extensions/Collaboration/CursorPlugin.ts +15 -9
  117. package/src/extensions/Collaboration/ForkYDocPlugin.test.ts +166 -0
  118. package/src/extensions/Collaboration/ForkYDocPlugin.ts +174 -0
  119. package/src/extensions/Collaboration/SyncPlugin.ts +7 -4
  120. package/src/extensions/Collaboration/UndoPlugin.ts +7 -4
  121. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +30 -0
  122. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +30 -0
  123. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -0
  124. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -0
  125. package/src/extensions/Comments/CommentsPlugin.ts +80 -75
  126. package/src/extensions/Comments/userstore/UserStore.ts +2 -2
  127. package/src/extensions/FilePanel/FilePanelPlugin.ts +56 -55
  128. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +60 -30
  129. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +26 -26
  130. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +33 -32
  131. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +45 -42
  132. package/src/extensions/Placeholder/PlaceholderPlugin.ts +113 -110
  133. package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +179 -170
  134. package/src/extensions/README.md +1 -1
  135. package/src/extensions/ShowSelection/ShowSelectionPlugin.ts +22 -19
  136. package/src/extensions/SideMenu/MultipleNodeSelection.ts +1 -1
  137. package/src/extensions/SideMenu/SideMenuPlugin.ts +49 -48
  138. package/src/extensions/SideMenu/dragging.ts +8 -8
  139. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +176 -176
  140. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +2 -2
  141. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +16 -16
  142. package/src/extensions/Suggestions/SuggestionMarks.ts +175 -0
  143. package/src/extensions/TableHandles/TableHandlesPlugin.ts +199 -195
  144. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +1 -1
  145. package/src/extensions/UniqueID/UniqueID.ts +6 -6
  146. package/src/extensions/getDraggableBlockFromElement.ts +1 -1
  147. package/src/fonts/inter.css +18 -9
  148. package/src/i18n/locales/ar.ts +0 -1
  149. package/src/i18n/locales/de.ts +0 -1
  150. package/src/i18n/locales/en.ts +0 -1
  151. package/src/i18n/locales/es.ts +0 -1
  152. package/src/i18n/locales/fr.ts +0 -1
  153. package/src/i18n/locales/hr.ts +0 -1
  154. package/src/i18n/locales/is.ts +0 -1
  155. package/src/i18n/locales/it.ts +0 -1
  156. package/src/i18n/locales/ja.ts +0 -1
  157. package/src/i18n/locales/ko.ts +0 -1
  158. package/src/i18n/locales/nl.ts +0 -1
  159. package/src/i18n/locales/no.ts +0 -1
  160. package/src/i18n/locales/pl.ts +0 -1
  161. package/src/i18n/locales/pt.ts +0 -1
  162. package/src/i18n/locales/ru.ts +0 -1
  163. package/src/i18n/locales/sk.ts +0 -1
  164. package/src/i18n/locales/uk.ts +0 -1
  165. package/src/i18n/locales/vi.ts +0 -1
  166. package/src/i18n/locales/zh-tw.ts +0 -1
  167. package/src/i18n/locales/zh.ts +0 -1
  168. package/src/index.ts +18 -8
  169. package/src/locales.ts +1 -1
  170. package/src/pm-nodes/BlockContainer.ts +1 -1
  171. package/src/pm-nodes/BlockGroup.ts +2 -2
  172. package/src/pm-nodes/Doc.ts +5 -4
  173. package/src/schema/README.md +1 -1
  174. package/src/schema/blocks/createSpec.ts +14 -14
  175. package/src/schema/blocks/internal.ts +17 -17
  176. package/src/schema/blocks/types.ts +25 -25
  177. package/src/schema/inlineContent/createSpec.ts +16 -20
  178. package/src/schema/inlineContent/internal.ts +9 -9
  179. package/src/schema/inlineContent/types.ts +26 -26
  180. package/src/schema/propTypes.ts +8 -8
  181. package/src/schema/styles/createSpec.ts +2 -2
  182. package/src/schema/styles/internal.ts +7 -7
  183. package/src/schema/styles/types.ts +2 -2
  184. package/src/util/EventEmitter.ts +4 -4
  185. package/src/util/README.md +1 -1
  186. package/src/util/combineByGroup.ts +1 -1
  187. package/src/util/table.ts +33 -30
  188. package/types/src/api/blockManipulation/commands/insertBlocks/insertBlocks.d.ts +1 -1
  189. package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.d.ts +4 -0
  190. package/types/src/api/blockManipulation/commands/removeBlocks/removeBlocks.test.d.ts +1 -0
  191. package/types/src/api/blockManipulation/commands/updateBlock/updateBlock.d.ts +3 -1
  192. package/types/src/api/blockManipulation/selections/selection.d.ts +10 -0
  193. package/types/src/api/blockManipulation/selections/textCursorPosition.d.ts +5 -0
  194. package/types/src/api/blockManipulation/transactions.test.d.ts +0 -0
  195. package/types/src/api/clipboard/clipboardExternal.test.d.ts +1 -0
  196. package/types/src/api/clipboard/clipboardInternal.test.d.ts +1 -0
  197. package/types/src/api/clipboard/testUtil.d.ts +541 -0
  198. package/types/src/api/exporters/html/htmlConversion.test.d.ts +1 -0
  199. package/types/src/api/exporters/markdown/markdownExporter.test.d.ts +1 -0
  200. package/types/src/api/nodeConversions/nodeConversions.test.d.ts +1 -0
  201. package/types/src/api/nodeConversions/nodeToBlock.d.ts +39 -2
  202. package/types/src/api/parsers/html/parseHTML.test.d.ts +1 -0
  203. package/types/src/api/parsers/markdown/parseMarkdown.test.d.ts +1 -0
  204. package/types/src/api/pmUtil.d.ts +3 -3
  205. package/types/src/api/testUtil/cases/customBlocks.d.ts +670 -0
  206. package/types/src/api/testUtil/cases/customInlineContent.d.ts +558 -0
  207. package/types/src/api/testUtil/cases/customStyles.d.ts +552 -0
  208. package/types/src/api/testUtil/cases/defaultSchema.d.ts +4 -0
  209. package/types/src/api/testUtil/index.d.ts +14 -0
  210. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +9 -0
  211. package/types/src/api/testUtil/paste.d.ts +2 -0
  212. package/types/src/blocks/CodeBlockContent/defaultSupportedLanguages.d.ts +6 -0
  213. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +9 -1
  214. package/types/src/editor/BlockNoteEditor.d.ts +58 -10
  215. package/types/src/editor/BlockNoteExtension.d.ts +9 -0
  216. package/types/src/editor/BlockNoteExtensions.d.ts +2 -2
  217. package/types/src/editor/BlockNoteTipTapEditor.d.ts +2 -2
  218. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +3 -3
  219. package/types/src/extensions/Collaboration/ForkYDocPlugin.d.ts +41 -0
  220. package/types/src/extensions/Collaboration/ForkYDocPlugin.test.d.ts +1 -0
  221. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +3 -3
  222. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +3 -3
  223. package/types/src/extensions/Collaboration/createCollaborationExtensions.d.ts +17 -0
  224. package/types/src/extensions/Comments/CommentsPlugin.d.ts +2 -4
  225. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +3 -4
  226. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +5 -5
  227. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +3 -4
  228. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +2 -3
  229. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +2 -3
  230. package/types/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.d.ts +2 -3
  231. package/types/src/extensions/ShowSelection/ShowSelectionPlugin.d.ts +2 -3
  232. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +3 -4
  233. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +2 -4
  234. package/types/src/extensions/Suggestions/SuggestionMarks.d.ts +4 -0
  235. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +5 -6
  236. package/types/src/i18n/locales/en.d.ts +0 -1
  237. package/types/src/i18n/locales/sk.d.ts +0 -1
  238. package/types/src/index.d.ts +15 -8
  239. package/dist/en-B7ycW7c8.js.map +0 -1
  240. package/dist/en-D4taoCs4.cjs.map +0 -1
  241. package/dist/tsconfig.tsbuildinfo +0 -1
  242. package/src/api/blockManipulation/selections/__snapshots__/selection.test.ts.snap +0 -844
  243. package/src/api/blockManipulation/selections/selection.test.ts +0 -72
  244. package/src/api/blockManipulation/selections/textCursorPosition/__snapshots__/textCursorPosition.test.ts.snap +0 -316
  245. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.ts +0 -74
@@ -1,6 +1,7 @@
1
1
  import { findChildren } from "@tiptap/core";
2
2
  import { Plugin, PluginKey } from "prosemirror-state";
3
3
  import { Decoration, DecorationSet } from "prosemirror-view";
4
+ import { BlockNoteExtension } from "../../editor/BlockNoteExtension.js";
4
5
 
5
6
  const PLUGIN_KEY = new PluginKey(`previous-blocks`);
6
7
 
@@ -23,199 +24,207 @@ const nodeAttributes: Record<string, string> = {
23
24
  *
24
25
  * Solution: When attributes change on a node, this plugin sets a data-* attribute with the "previous" value. This way we can still use CSS transitions. (See block.module.css)
25
26
  */
26
- export class PreviousBlockTypePlugin {
27
- public readonly plugin: Plugin;
27
+ export class PreviousBlockTypePlugin extends BlockNoteExtension {
28
28
  constructor() {
29
+ super();
29
30
  let timeout: ReturnType<typeof setTimeout>;
30
- this.plugin = new Plugin({
31
- key: PLUGIN_KEY,
32
- view(_editorView) {
33
- return {
34
- update: async (view, _prevState) => {
35
- if (this.key?.getState(view.state).updatedBlocks.size > 0) {
36
- // use setTimeout 0 to clear the decorations so that at least
37
- // for one DOM-render the decorations have been applied
38
- timeout = setTimeout(() => {
39
- view.dispatch(
40
- view.state.tr.setMeta(PLUGIN_KEY, { clearUpdate: true })
41
- );
42
- }, 0);
43
- }
44
- },
45
- destroy: () => {
46
- if (timeout) {
47
- clearTimeout(timeout);
48
- }
49
- },
50
- };
51
- },
52
- state: {
53
- init() {
31
+ this.addProsemirrorPlugin(
32
+ new Plugin({
33
+ key: PLUGIN_KEY,
34
+ view(_editorView) {
54
35
  return {
55
- // Block attributes, by block ID, from just before the previous transaction.
56
- prevTransactionOldBlockAttrs: {} as any,
57
- // Block attributes, by block ID, from just before the current transaction.
58
- currentTransactionOldBlockAttrs: {} as any,
59
- // Set of IDs of blocks whose attributes changed from the current transaction.
60
- updatedBlocks: new Set<string>(),
36
+ update: async (view, _prevState) => {
37
+ if (this.key?.getState(view.state).updatedBlocks.size > 0) {
38
+ // use setTimeout 0 to clear the decorations so that at least
39
+ // for one DOM-render the decorations have been applied
40
+ timeout = setTimeout(() => {
41
+ view.dispatch(
42
+ view.state.tr.setMeta(PLUGIN_KEY, { clearUpdate: true }),
43
+ );
44
+ }, 0);
45
+ }
46
+ },
47
+ destroy: () => {
48
+ if (timeout) {
49
+ clearTimeout(timeout);
50
+ }
51
+ },
61
52
  };
62
53
  },
54
+ state: {
55
+ init() {
56
+ return {
57
+ // Block attributes, by block ID, from just before the previous transaction.
58
+ prevTransactionOldBlockAttrs: {} as any,
59
+ // Block attributes, by block ID, from just before the current transaction.
60
+ currentTransactionOldBlockAttrs: {} as any,
61
+ // Set of IDs of blocks whose attributes changed from the current transaction.
62
+ updatedBlocks: new Set<string>(),
63
+ };
64
+ },
63
65
 
64
- apply(transaction, prev, oldState, newState) {
65
- prev.currentTransactionOldBlockAttrs = {};
66
- prev.updatedBlocks.clear();
66
+ apply(transaction, prev, oldState, newState) {
67
+ prev.currentTransactionOldBlockAttrs = {};
68
+ prev.updatedBlocks.clear();
67
69
 
68
- if (!transaction.docChanged || oldState.doc.eq(newState.doc)) {
69
- return prev;
70
- }
71
-
72
- // TODO: Instead of iterating through the entire document, only check nodes affected by the transactions. Will
73
- // also probably require checking nodes affected by the previous transaction too.
74
- // We didn't get this to work yet:
75
- // const transform = combineTransactionSteps(oldState.doc, [transaction]);
76
- // // const { mapping } = transform;
77
- // const changes = getChangedRanges(transform);
78
- //
79
- // changes.forEach(({ oldRange, newRange }) => {
80
- // const oldNodes = findChildrenInRange(
81
- // oldState.doc,
82
- // oldRange,
83
- // (node) => node.attrs.id
84
- // );
85
- //
86
- // const newNodes = findChildrenInRange(
87
- // newState.doc,
88
- // newRange,
89
- // (node) => node.attrs.id
90
- // );
91
-
92
- const currentTransactionOriginalOldBlockAttrs = {} as any;
93
-
94
- const oldNodes = findChildren(oldState.doc, (node) => node.attrs.id);
95
- const oldNodesById = new Map(
96
- oldNodes.map((node) => [node.node.attrs.id, node])
97
- );
98
- const newNodes = findChildren(newState.doc, (node) => node.attrs.id);
99
-
100
- // Traverses all block containers in the new editor state.
101
- for (const node of newNodes) {
102
- const oldNode = oldNodesById.get(node.node.attrs.id);
103
-
104
- const oldContentNode = oldNode?.node.firstChild;
105
- const newContentNode = node.node.firstChild;
106
-
107
- if (oldNode && oldContentNode && newContentNode) {
108
- const newAttrs = {
109
- index: newContentNode.attrs.index,
110
- level: newContentNode.attrs.level,
111
- type: newContentNode.type.name,
112
- depth: newState.doc.resolve(node.pos).depth,
113
- };
114
-
115
- let oldAttrs = {
116
- index: oldContentNode.attrs.index,
117
- level: oldContentNode.attrs.level,
118
- type: oldContentNode.type.name,
119
- depth: oldState.doc.resolve(oldNode.pos).depth,
120
- };
121
-
122
- currentTransactionOriginalOldBlockAttrs[node.node.attrs.id] =
123
- oldAttrs;
124
-
125
- // Whenever a transaction is appended by the OrderedListItemIndexPlugin, it's given the metadata:
126
- // { "orderedListIndexing": true }
127
- // These appended transactions happen immediately after any transaction which causes ordered list item
128
- // indices to require updating, including those which trigger animations. Therefore, these animations are
129
- // immediately overridden when the PreviousBlockTypePlugin processes the appended transaction, despite only
130
- // the listItemIndex attribute changing. To solve this, oldAttrs must be edited for transactions with the
131
- // "orderedListIndexing" metadata, so the correct animation can be re-triggered.
132
- if (transaction.getMeta("numberedListIndexing")) {
133
- // If the block existed before the transaction, gets the attributes from before the previous transaction
134
- // (i.e. the transaction that caused list item indices to need updating).
135
- if (node.node.attrs.id in prev.prevTransactionOldBlockAttrs) {
136
- oldAttrs =
137
- prev.prevTransactionOldBlockAttrs[node.node.attrs.id];
138
- }
70
+ if (!transaction.docChanged || oldState.doc.eq(newState.doc)) {
71
+ return prev;
72
+ }
139
73
 
140
- // Stops list item indices themselves being animated (looks smoother), unless the block's content type is
141
- // changing from a numbered list item to something else.
142
- if (newAttrs.type === "numberedListItem") {
143
- oldAttrs.index = newAttrs.index;
74
+ // TODO: Instead of iterating through the entire document, only check nodes affected by the transactions. Will
75
+ // also probably require checking nodes affected by the previous transaction too.
76
+ // We didn't get this to work yet:
77
+ // const transform = combineTransactionSteps(oldState.doc, [transaction]);
78
+ // // const { mapping } = transform;
79
+ // const changes = getChangedRanges(transform);
80
+ //
81
+ // changes.forEach(({ oldRange, newRange }) => {
82
+ // const oldNodes = findChildrenInRange(
83
+ // oldState.doc,
84
+ // oldRange,
85
+ // (node) => node.attrs.id
86
+ // );
87
+ //
88
+ // const newNodes = findChildrenInRange(
89
+ // newState.doc,
90
+ // newRange,
91
+ // (node) => node.attrs.id
92
+ // );
93
+
94
+ const currentTransactionOriginalOldBlockAttrs = {} as any;
95
+
96
+ const oldNodes = findChildren(
97
+ oldState.doc,
98
+ (node) => node.attrs.id,
99
+ );
100
+ const oldNodesById = new Map(
101
+ oldNodes.map((node) => [node.node.attrs.id, node]),
102
+ );
103
+ const newNodes = findChildren(
104
+ newState.doc,
105
+ (node) => node.attrs.id,
106
+ );
107
+
108
+ // Traverses all block containers in the new editor state.
109
+ for (const node of newNodes) {
110
+ const oldNode = oldNodesById.get(node.node.attrs.id);
111
+
112
+ const oldContentNode = oldNode?.node.firstChild;
113
+ const newContentNode = node.node.firstChild;
114
+
115
+ if (oldNode && oldContentNode && newContentNode) {
116
+ const newAttrs = {
117
+ index: newContentNode.attrs.index,
118
+ level: newContentNode.attrs.level,
119
+ type: newContentNode.type.name,
120
+ depth: newState.doc.resolve(node.pos).depth,
121
+ };
122
+
123
+ let oldAttrs = {
124
+ index: oldContentNode.attrs.index,
125
+ level: oldContentNode.attrs.level,
126
+ type: oldContentNode.type.name,
127
+ depth: oldState.doc.resolve(oldNode.pos).depth,
128
+ };
129
+
130
+ currentTransactionOriginalOldBlockAttrs[node.node.attrs.id] =
131
+ oldAttrs;
132
+
133
+ // Whenever a transaction is appended by the OrderedListItemIndexPlugin, it's given the metadata:
134
+ // { "orderedListIndexing": true }
135
+ // These appended transactions happen immediately after any transaction which causes ordered list item
136
+ // indices to require updating, including those which trigger animations. Therefore, these animations are
137
+ // immediately overridden when the PreviousBlockTypePlugin processes the appended transaction, despite only
138
+ // the listItemIndex attribute changing. To solve this, oldAttrs must be edited for transactions with the
139
+ // "orderedListIndexing" metadata, so the correct animation can be re-triggered.
140
+ if (transaction.getMeta("numberedListIndexing")) {
141
+ // If the block existed before the transaction, gets the attributes from before the previous transaction
142
+ // (i.e. the transaction that caused list item indices to need updating).
143
+ if (node.node.attrs.id in prev.prevTransactionOldBlockAttrs) {
144
+ oldAttrs =
145
+ prev.prevTransactionOldBlockAttrs[node.node.attrs.id];
146
+ }
147
+
148
+ // Stops list item indices themselves being animated (looks smoother), unless the block's content type is
149
+ // changing from a numbered list item to something else.
150
+ if (newAttrs.type === "numberedListItem") {
151
+ oldAttrs.index = newAttrs.index;
152
+ }
144
153
  }
145
- }
146
154
 
147
- prev.currentTransactionOldBlockAttrs[node.node.attrs.id] =
148
- oldAttrs;
149
-
150
- // TODO: faster deep equal?
151
- if (JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs)) {
152
- (oldAttrs as any)["depth-change"] =
153
- oldAttrs.depth - newAttrs.depth;
154
-
155
- // for debugging:
156
- // console.log(
157
- // "id:",
158
- // node.node.attrs.id,
159
- // "previousBlockTypePlugin changes detected, oldAttrs",
160
- // oldAttrs,
161
- // "new",
162
- // newAttrs
163
- // );
164
-
165
- prev.updatedBlocks.add(node.node.attrs.id);
155
+ prev.currentTransactionOldBlockAttrs[node.node.attrs.id] =
156
+ oldAttrs;
157
+
158
+ // TODO: faster deep equal?
159
+ if (JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs)) {
160
+ (oldAttrs as any)["depth-change"] =
161
+ oldAttrs.depth - newAttrs.depth;
162
+
163
+ // for debugging:
164
+ // console.log(
165
+ // "id:",
166
+ // node.node.attrs.id,
167
+ // "previousBlockTypePlugin changes detected, oldAttrs",
168
+ // oldAttrs,
169
+ // "new",
170
+ // newAttrs
171
+ // );
172
+
173
+ prev.updatedBlocks.add(node.node.attrs.id);
174
+ }
166
175
  }
167
176
  }
168
- }
169
177
 
170
- prev.prevTransactionOldBlockAttrs =
171
- currentTransactionOriginalOldBlockAttrs;
178
+ prev.prevTransactionOldBlockAttrs =
179
+ currentTransactionOriginalOldBlockAttrs;
172
180
 
173
- return prev;
181
+ return prev;
182
+ },
174
183
  },
175
- },
176
- props: {
177
- decorations(state) {
178
- const pluginState = (this as Plugin).getState(state);
179
- if (pluginState.updatedBlocks.size === 0) {
180
- return undefined;
181
- }
182
-
183
- const decorations: Decoration[] = [];
184
-
185
- state.doc.descendants((node, pos) => {
186
- if (!node.attrs.id) {
187
- return;
184
+ props: {
185
+ decorations(state) {
186
+ const pluginState = (this as Plugin).getState(state);
187
+ if (pluginState.updatedBlocks.size === 0) {
188
+ return undefined;
188
189
  }
189
190
 
190
- if (!pluginState.updatedBlocks.has(node.attrs.id)) {
191
- return;
192
- }
191
+ const decorations: Decoration[] = [];
193
192
 
194
- const prevAttrs =
195
- pluginState.currentTransactionOldBlockAttrs[node.attrs.id];
196
- const decorationAttrs: any = {};
193
+ state.doc.descendants((node, pos) => {
194
+ if (!node.attrs.id) {
195
+ return;
196
+ }
197
197
 
198
- for (const [nodeAttr, val] of Object.entries(prevAttrs)) {
199
- decorationAttrs["data-prev-" + nodeAttributes[nodeAttr]] =
200
- val || "none";
201
- }
198
+ if (!pluginState.updatedBlocks.has(node.attrs.id)) {
199
+ return;
200
+ }
202
201
 
203
- // for debugging:
204
- // console.log(
205
- // "previousBlockTypePlugin committing decorations",
206
- // decorationAttrs
207
- // );
202
+ const prevAttrs =
203
+ pluginState.currentTransactionOldBlockAttrs[node.attrs.id];
204
+ const decorationAttrs: any = {};
208
205
 
209
- const decoration = Decoration.node(pos, pos + node.nodeSize, {
210
- ...decorationAttrs,
211
- });
206
+ for (const [nodeAttr, val] of Object.entries(prevAttrs)) {
207
+ decorationAttrs["data-prev-" + nodeAttributes[nodeAttr]] =
208
+ val || "none";
209
+ }
210
+
211
+ // for debugging:
212
+ // console.log(
213
+ // "previousBlockTypePlugin committing decorations",
214
+ // decorationAttrs
215
+ // );
212
216
 
213
- decorations.push(decoration);
214
- });
217
+ const decoration = Decoration.node(pos, pos + node.nodeSize, {
218
+ ...decorationAttrs,
219
+ });
215
220
 
216
- return DecorationSet.create(state.doc, decorations);
221
+ decorations.push(decoration);
222
+ });
223
+
224
+ return DecorationSet.create(state.doc, decorations);
225
+ },
217
226
  },
218
- },
219
- });
227
+ }),
228
+ );
220
229
  }
221
230
  }
@@ -1,3 +1,3 @@
1
1
  ### @blocknote/core/src/extensions
2
2
 
3
- All extra extensions for TipTap / Prosemirror needed to implement the Prosemirror UX and editor behavior.
3
+ All extra extensions for TipTap / Prosemirror needed to implement the Prosemirror UX and editor behavior.
@@ -1,6 +1,7 @@
1
1
  import { Plugin, PluginKey } from "prosemirror-state";
2
2
  import { Decoration, DecorationSet } from "prosemirror-view";
3
3
  import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
4
+ import { BlockNoteExtension } from "../../editor/BlockNoteExtension.js";
4
5
 
5
6
  const PLUGIN_KEY = new PluginKey(`blocknote-show-selection`);
6
7
 
@@ -9,29 +10,31 @@ const PLUGIN_KEY = new PluginKey(`blocknote-show-selection`);
9
10
  * This can be used to highlight the current selection in the UI even when the
10
11
  * text editor is not focused.
11
12
  */
12
- export class ShowSelectionPlugin {
13
- public readonly plugin: Plugin;
13
+ export class ShowSelectionPlugin extends BlockNoteExtension {
14
14
  private enabled = false;
15
15
 
16
16
  public constructor(private readonly editor: BlockNoteEditor<any, any, any>) {
17
- this.plugin = new Plugin({
18
- key: PLUGIN_KEY,
19
- props: {
20
- decorations: (state) => {
21
- const { doc, selection } = state;
22
-
23
- if (!this.enabled) {
24
- return DecorationSet.empty;
25
- }
26
-
27
- const dec = Decoration.inline(selection.from, selection.to, {
28
- "data-show-selection": "true",
29
- });
30
-
31
- return DecorationSet.create(doc, [dec]);
17
+ super();
18
+ this.addProsemirrorPlugin(
19
+ new Plugin({
20
+ key: PLUGIN_KEY,
21
+ props: {
22
+ decorations: (state) => {
23
+ const { doc, selection } = state;
24
+
25
+ if (!this.enabled) {
26
+ return DecorationSet.empty;
27
+ }
28
+
29
+ const dec = Decoration.inline(selection.from, selection.to, {
30
+ "data-show-selection": "true",
31
+ });
32
+
33
+ return DecorationSet.create(doc, [dec]);
34
+ },
32
35
  },
33
- },
34
- });
36
+ }),
37
+ );
35
38
  }
36
39
 
37
40
  public setEnabled(enabled: boolean) {
@@ -77,7 +77,7 @@ export class MultipleNodeSelection extends Selection {
77
77
 
78
78
  return new MultipleNodeSelection(
79
79
  doc.resolve(fromResult.pos),
80
- doc.resolve(toResult.pos)
80
+ doc.resolve(toResult.pos),
81
81
  );
82
82
  }
83
83