@blocknote/core 0.38.0 → 0.39.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 (225) hide show
  1. package/dist/BlockNoteSchema-DmZ6UQfY.cjs +11 -0
  2. package/dist/BlockNoteSchema-DmZ6UQfY.cjs.map +1 -0
  3. package/dist/BlockNoteSchema-oR047ACf.js +4275 -0
  4. package/dist/BlockNoteSchema-oR047ACf.js.map +1 -0
  5. package/dist/blocknote.cjs +4 -12
  6. package/dist/blocknote.cjs.map +1 -1
  7. package/dist/blocknote.js +3296 -7187
  8. package/dist/blocknote.js.map +1 -1
  9. package/dist/blocks.cjs +2 -0
  10. package/dist/blocks.cjs.map +1 -0
  11. package/dist/blocks.js +71 -0
  12. package/dist/blocks.js.map +1 -0
  13. package/dist/style.css +1 -1
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/webpack-stats.json +1 -1
  16. package/package.json +19 -16
  17. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +1 -1
  18. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +2 -2
  19. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +34 -25
  20. package/src/api/blockManipulation/setupTestEnv.ts +0 -1
  21. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +4 -8
  22. package/src/api/clipboard/toClipboard/copyExtension.ts +1 -1
  23. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +128 -28
  24. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +101 -41
  25. package/src/api/pmUtil.ts +1 -1
  26. package/src/api/positionMapping.test.ts +58 -15
  27. package/src/api/positionMapping.ts +2 -4
  28. package/src/blocks/Audio/block.ts +174 -0
  29. package/src/blocks/BlockNoteSchema.ts +59 -0
  30. package/src/blocks/Code/block.ts +303 -0
  31. package/src/blocks/Code/shiki.ts +73 -0
  32. package/src/blocks/File/block.ts +98 -0
  33. package/src/blocks/{FileBlockContent → File}/helpers/render/createAddFileButton.ts +5 -2
  34. package/src/blocks/{FileBlockContent → File}/helpers/render/createFileBlockWrapper.ts +15 -6
  35. package/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.ts +15 -2
  36. package/src/blocks/{FileBlockContent → File}/helpers/render/createResizableFileBlockWrapper.ts +21 -2
  37. package/src/blocks/Heading/block.ts +138 -0
  38. package/src/blocks/Image/block.ts +190 -0
  39. package/src/blocks/ListItem/BulletListItem/block.ts +116 -0
  40. package/src/blocks/ListItem/CheckListItem/block.ts +175 -0
  41. package/src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts +173 -0
  42. package/src/blocks/ListItem/NumberedListItem/block.ts +133 -0
  43. package/src/blocks/ListItem/ToggleListItem/block.ts +78 -0
  44. package/src/blocks/PageBreak/block.ts +72 -0
  45. package/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.ts +9 -7
  46. package/src/blocks/Paragraph/block.ts +80 -0
  47. package/src/blocks/Quote/block.ts +90 -0
  48. package/src/blocks/{TableBlockContent/TableBlockContent.ts → Table/block.ts} +169 -51
  49. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +1 -1
  50. package/src/blocks/Video/block.ts +143 -0
  51. package/src/blocks/defaultBlockHelpers.ts +2 -2
  52. package/src/blocks/defaultBlockTypeGuards.ts +143 -174
  53. package/src/blocks/defaultBlocks.ts +107 -35
  54. package/src/blocks/defaultProps.ts +145 -4
  55. package/src/blocks/index.ts +26 -0
  56. package/src/blocks/utils/listItemEnterHandler.ts +42 -0
  57. package/src/editor/Block.css +54 -18
  58. package/src/editor/BlockNoteEditor.ts +251 -210
  59. package/src/editor/BlockNoteExtension.ts +92 -0
  60. package/src/editor/BlockNoteExtensions.ts +18 -17
  61. package/src/editor/defaultColors.ts +2 -2
  62. package/src/exporter/Exporter.ts +1 -1
  63. package/src/exporter/mapping.ts +1 -1
  64. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +3 -20
  65. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +6 -8
  66. package/src/extensions/BlockChange/BlockChangePlugin.ts +2 -1
  67. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +2 -2
  68. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +2 -2
  69. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -1
  70. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -1
  71. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +52 -0
  72. package/src/extensions/Collaboration/schemaMigration/migrationRules/index.ts +4 -0
  73. package/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.ts +4 -0
  74. package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.ts +78 -0
  75. package/src/extensions/Comments/CommentsPlugin.ts +1 -1
  76. package/src/extensions/FilePanel/FilePanelPlugin.ts +5 -10
  77. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +1 -1
  78. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +4 -3
  79. package/src/extensions/Placeholder/PlaceholderPlugin.ts +2 -2
  80. package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +1 -23
  81. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +0 -5
  82. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +6 -2
  83. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +24 -17
  84. package/src/extensions/TableHandles/TableHandlesPlugin.ts +2 -2
  85. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +5 -11
  86. package/src/extensions/TextColor/TextColorExtension.ts +3 -17
  87. package/src/extensions/TextColor/TextColorMark.ts +4 -9
  88. package/src/extensions/UniqueID/UniqueID.ts +6 -13
  89. package/src/index.ts +2 -28
  90. package/src/schema/blocks/createSpec.ts +342 -169
  91. package/src/schema/blocks/internal.ts +77 -138
  92. package/src/schema/blocks/types.ts +264 -94
  93. package/src/schema/index.ts +1 -0
  94. package/src/schema/inlineContent/createSpec.ts +99 -21
  95. package/src/schema/inlineContent/internal.ts +16 -7
  96. package/src/schema/inlineContent/types.ts +24 -2
  97. package/src/schema/propTypes.ts +15 -9
  98. package/src/schema/schema.ts +209 -0
  99. package/src/schema/styles/createSpec.ts +79 -31
  100. package/src/schema/styles/internal.ts +61 -2
  101. package/src/schema/styles/types.ts +17 -3
  102. package/src/util/topo-sort.test.ts +125 -0
  103. package/src/util/topo-sort.ts +160 -0
  104. package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +2 -1
  105. package/types/src/api/blockManipulation/selections/selection.d.ts +1 -1
  106. package/types/src/api/blockManipulation/setupTestEnv.d.ts +29 -543
  107. package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +1 -1
  108. package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +1 -1
  109. package/types/src/api/pmUtil.d.ts +1 -1
  110. package/types/src/blocks/Audio/block.d.ts +58 -0
  111. package/types/src/blocks/BlockNoteSchema.d.ts +18 -0
  112. package/types/src/blocks/{CodeBlockContent/CodeBlockContent.d.ts → Code/block.d.ts} +25 -26
  113. package/types/src/blocks/Code/shiki.d.ts +4 -0
  114. package/types/src/blocks/File/block.d.ts +37 -0
  115. package/types/src/blocks/File/helpers/render/createAddFileButton.d.ts +6 -0
  116. package/types/src/blocks/File/helpers/render/createFileBlockWrapper.d.ts +25 -0
  117. package/types/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.d.ts +6 -2
  118. package/types/src/blocks/File/helpers/render/createResizableFileBlockWrapper.d.ts +31 -0
  119. package/types/src/blocks/Heading/block.d.ts +71 -0
  120. package/types/src/blocks/Image/block.d.ts +102 -0
  121. package/types/src/blocks/ListItem/BulletListItem/block.d.ts +25 -0
  122. package/types/src/blocks/ListItem/CheckListItem/block.d.ts +33 -0
  123. package/types/src/blocks/ListItem/NumberedListItem/IndexingPlugin.d.ts +8 -0
  124. package/types/src/blocks/ListItem/NumberedListItem/block.d.ts +33 -0
  125. package/types/src/blocks/ListItem/ToggleListItem/block.d.ts +25 -0
  126. package/types/src/blocks/PageBreak/block.d.ts +11 -0
  127. package/types/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.d.ts +4 -2
  128. package/types/src/blocks/Paragraph/block.d.ts +25 -0
  129. package/types/src/blocks/Quote/block.d.ts +17 -0
  130. package/types/src/blocks/Table/block.d.ts +21 -0
  131. package/types/src/blocks/Video/block.d.ts +67 -0
  132. package/types/src/blocks/defaultBlockHelpers.d.ts +1 -1
  133. package/types/src/blocks/defaultBlockTypeGuards.d.ts +15 -36
  134. package/types/src/blocks/defaultBlocks.d.ts +221 -1060
  135. package/types/src/blocks/defaultProps.d.ts +17 -1
  136. package/types/src/blocks/index.d.ts +24 -0
  137. package/types/src/blocks/utils/listItemEnterHandler.d.ts +2 -0
  138. package/types/src/editor/BlockNoteEditor.d.ts +33 -66
  139. package/types/src/editor/BlockNoteExtension.d.ts +67 -0
  140. package/types/src/editor/BlockNoteExtensions.d.ts +1 -1
  141. package/types/src/editor/defaultColors.d.ts +8 -76
  142. package/types/src/exporter/Exporter.d.ts +1 -1
  143. package/types/src/exporter/mapping.d.ts +1 -1
  144. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +4 -1
  145. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +7 -0
  146. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/index.d.ts +3 -0
  147. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.d.ts +3 -0
  148. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.d.ts +2 -0
  149. package/types/src/extensions/Comments/CommentsPlugin.d.ts +1 -1
  150. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
  151. package/types/src/extensions/TextColor/TextColorMark.d.ts +4 -1
  152. package/types/src/index.d.ts +2 -25
  153. package/types/src/schema/blocks/createSpec.d.ts +16 -36
  154. package/types/src/schema/blocks/internal.d.ts +11 -33
  155. package/types/src/schema/blocks/types.d.ts +181 -57
  156. package/types/src/schema/index.d.ts +1 -0
  157. package/types/src/schema/inlineContent/createSpec.d.ts +36 -2
  158. package/types/src/schema/inlineContent/internal.d.ts +7 -15
  159. package/types/src/schema/inlineContent/types.d.ts +15 -1
  160. package/types/src/schema/propTypes.d.ts +4 -4
  161. package/types/src/schema/schema.d.ts +40 -0
  162. package/types/src/schema/styles/createSpec.d.ts +6 -4
  163. package/types/src/schema/styles/internal.d.ts +6 -3
  164. package/types/src/schema/styles/types.d.ts +11 -2
  165. package/types/src/util/topo-sort.d.ts +18 -0
  166. package/types/src/util/topo-sort.test.d.ts +1 -0
  167. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +0 -144
  168. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +0 -445
  169. package/src/blocks/FileBlockContent/FileBlockContent.ts +0 -100
  170. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +0 -159
  171. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +0 -159
  172. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +0 -134
  173. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +0 -299
  174. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +0 -86
  175. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +0 -172
  176. package/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.ts +0 -104
  177. package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +0 -49
  178. package/src/blocks/PageBreakBlockContent/schema.ts +0 -40
  179. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +0 -78
  180. package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +0 -121
  181. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +0 -158
  182. package/src/editor/BlockNoteSchema.ts +0 -107
  183. package/src/editor/BlockNoteTipTapEditor.ts +0 -335
  184. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +0 -99
  185. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +0 -90
  186. package/types/src/blocks/FileBlockContent/helpers/render/createAddFileButton.d.ts +0 -6
  187. package/types/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.d.ts +0 -9
  188. package/types/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.d.ts +0 -9
  189. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +0 -67
  190. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +0 -131
  191. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -46
  192. package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +0 -55
  193. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -2
  194. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -58
  195. package/types/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.d.ts +0 -46
  196. package/types/src/blocks/PageBreakBlockContent/PageBreakBlockContent.d.ts +0 -31
  197. package/types/src/blocks/PageBreakBlockContent/schema.d.ts +0 -86
  198. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -52
  199. package/types/src/blocks/QuoteBlockContent/QuoteBlockContent.d.ts +0 -52
  200. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +0 -39
  201. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +0 -131
  202. package/types/src/editor/BlockNoteSchema.d.ts +0 -34
  203. package/types/src/editor/BlockNoteTipTapEditor.d.ts +0 -43
  204. /package/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.ts +0 -0
  205. /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.ts +0 -0
  206. /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.ts +0 -0
  207. /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.ts +0 -0
  208. /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.ts +0 -0
  209. /package/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  210. /package/src/blocks/{ImageBlockContent → Image}/parseImageElement.ts +0 -0
  211. /package/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.ts +0 -0
  212. /package/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.ts +0 -0
  213. /package/src/blocks/{TableBlockContent → Table}/TableExtension.ts +0 -0
  214. /package/src/blocks/{VideoBlockContent → Video}/parseVideoElement.ts +0 -0
  215. /package/types/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.d.ts +0 -0
  216. /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.d.ts +0 -0
  217. /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.d.ts +0 -0
  218. /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.d.ts +0 -0
  219. /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.d.ts +0 -0
  220. /package/types/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
  221. /package/types/src/blocks/{ImageBlockContent → Image}/parseImageElement.d.ts +0 -0
  222. /package/types/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.d.ts +0 -0
  223. /package/types/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.d.ts +0 -0
  224. /package/types/src/blocks/{TableBlockContent → Table}/TableExtension.d.ts +0 -0
  225. /package/types/src/blocks/{VideoBlockContent → Video}/parseVideoElement.d.ts +0 -0
@@ -1,16 +1,28 @@
1
1
  import {
2
2
  AnyExtension,
3
+ createDocument,
3
4
  EditorOptions,
4
5
  Extension,
5
6
  getSchema,
7
+ InputRule,
6
8
  isNodeSelection,
7
9
  Mark,
8
10
  posToDOMRect,
11
+ Editor as TiptapEditor,
9
12
  Node as TipTapNode,
10
13
  } from "@tiptap/core";
14
+ import { redo, undo } from "@tiptap/pm/history";
15
+ import {
16
+ TextSelection,
17
+ type Command,
18
+ type Plugin,
19
+ type Transaction,
20
+ } from "@tiptap/pm/state";
21
+ import { dropCursor } from "prosemirror-dropcursor";
11
22
  import { Node, Schema } from "prosemirror-model";
12
- // import "./blocknote.css";
23
+ import { redoCommand, undoCommand, ySyncPluginKey } from "y-prosemirror";
13
24
  import * as Y from "yjs";
25
+
14
26
  import { insertBlocks } from "../api/blockManipulation/commands/insertBlocks/insertBlocks.js";
15
27
  import {
16
28
  moveBlocksDown,
@@ -23,7 +35,10 @@ import {
23
35
  unnestBlock,
24
36
  } from "../api/blockManipulation/commands/nestBlock/nestBlock.js";
25
37
  import { removeAndInsertBlocks } from "../api/blockManipulation/commands/replaceBlocks/replaceBlocks.js";
26
- import { updateBlock } from "../api/blockManipulation/commands/updateBlock/updateBlock.js";
38
+ import {
39
+ updateBlock,
40
+ updateBlockTr,
41
+ } from "../api/blockManipulation/commands/updateBlock/updateBlock.js";
27
42
  import {
28
43
  getBlock,
29
44
  getNextBlock,
@@ -41,19 +56,28 @@ import {
41
56
  setTextCursorPosition,
42
57
  } from "../api/blockManipulation/selections/textCursorPosition.js";
43
58
  import { createExternalHTMLExporter } from "../api/exporters/html/externalHTMLExporter.js";
59
+ import { createInternalHTMLSerializer } from "../api/exporters/html/internalHTMLSerializer.js";
44
60
  import { blocksToMarkdown } from "../api/exporters/markdown/markdownExporter.js";
61
+ import { getBlockInfoFromTransaction } from "../api/getBlockInfoFromPos.js";
62
+ import {
63
+ BlocksChanged,
64
+ getBlocksChangedByTransaction,
65
+ } from "../api/getBlocksChangedByTransaction.js";
66
+ import {
67
+ blockToNode,
68
+ inlineContentToNodes,
69
+ } from "../api/nodeConversions/blockToNode.js";
70
+ import { docToBlocks } from "../api/nodeConversions/nodeToBlock.js";
45
71
  import { HTMLToBlocks } from "../api/parsers/html/parseHTML.js";
46
72
  import {
47
73
  markdownToBlocks,
48
74
  markdownToHTML,
49
75
  } from "../api/parsers/markdown/parseMarkdown.js";
50
- import {
51
- Block,
52
- DefaultBlockSchema,
53
- DefaultInlineContentSchema,
54
- DefaultStyleSchema,
55
- PartialBlock,
56
- } from "../blocks/defaultBlocks.js";
76
+ import { editorHasBlockWithType } from "../blocks/defaultBlockTypeGuards.js";
77
+ import type { ThreadStore, User } from "../comments/index.js";
78
+ import { BlockChangePlugin } from "../extensions/BlockChange/BlockChangePlugin.js";
79
+ import type { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js";
80
+ import type { ForkYDocPlugin } from "../extensions/Collaboration/ForkYDocPlugin.js";
57
81
  import type { CommentsPlugin } from "../extensions/Comments/CommentsPlugin.js";
58
82
  import { FilePanelProsemirrorPlugin } from "../extensions/FilePanel/FilePanelPlugin.js";
59
83
  import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin.js";
@@ -63,11 +87,14 @@ import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin
63
87
  import { SuggestionMenuProseMirrorPlugin } from "../extensions/SuggestionMenu/SuggestionPlugin.js";
64
88
  import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin.js";
65
89
  import { UniqueID } from "../extensions/UniqueID/UniqueID.js";
90
+ import { Dictionary } from "../i18n/dictionary.js";
91
+ import { en } from "../i18n/locales/index.js";
66
92
  import {
67
93
  BlockIdentifier,
68
94
  BlockNoteDOMAttributes,
69
95
  BlockSchema,
70
96
  BlockSpecs,
97
+ CustomBlockNoteSchema,
71
98
  InlineContentSchema,
72
99
  InlineContentSpecs,
73
100
  PartialInlineContent,
@@ -75,49 +102,25 @@ import {
75
102
  StyleSchema,
76
103
  StyleSpecs,
77
104
  } from "../schema/index.js";
105
+ import "../style.css";
78
106
  import { mergeCSSClasses } from "../util/browser.js";
107
+ import { EventEmitter } from "../util/EventEmitter.js";
79
108
  import { NoInfer, UnreachableCaseError } from "../util/typescript.js";
80
-
109
+ import { BlockNoteExtension } from "./BlockNoteExtension.js";
81
110
  import { getBlockNoteExtensions } from "./BlockNoteExtensions.js";
82
111
  import { TextCursorPosition } from "./cursorPositionTypes.js";
83
-
84
112
  import { Selection } from "./selectionTypes.js";
85
113
  import { transformPasted } from "./transformPasted.js";
86
114
 
87
- import { checkDefaultBlockTypeInSchema } from "../blocks/defaultBlockTypeGuards.js";
88
- import { BlockNoteSchema } from "./BlockNoteSchema.js";
115
+ // TODO eventually we will want to de-couple this from the editor instance, for now it provides a default schema to use
89
116
  import {
90
- BlockNoteTipTapEditor,
91
- BlockNoteTipTapEditorOptions,
92
- } from "./BlockNoteTipTapEditor.js";
93
-
94
- import { Dictionary } from "../i18n/dictionary.js";
95
- import { en } from "../i18n/locales/index.js";
96
-
97
- import { redo, undo } from "@tiptap/pm/history";
98
- import {
99
- TextSelection,
100
- type Command,
101
- type Plugin,
102
- type Transaction,
103
- } from "@tiptap/pm/state";
104
- import { dropCursor } from "prosemirror-dropcursor";
105
- import { EditorView } from "prosemirror-view";
106
- import { redoCommand, undoCommand, ySyncPluginKey } from "y-prosemirror";
107
- import { createInternalHTMLSerializer } from "../api/exporters/html/internalHTMLSerializer.js";
108
- import {
109
- BlocksChanged,
110
- getBlocksChangedByTransaction,
111
- } from "../api/getBlocksChangedByTransaction.js";
112
- import { inlineContentToNodes } from "../api/nodeConversions/blockToNode.js";
113
- import { docToBlocks } from "../api/nodeConversions/nodeToBlock.js";
114
- import { CodeBlockOptions } from "../blocks/CodeBlockContent/CodeBlockContent.js";
115
- import type { ThreadStore, User } from "../comments/index.js";
116
- import { BlockChangePlugin } from "../extensions/BlockChange/BlockChangePlugin.js";
117
- import type { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js";
118
- import type { ForkYDocPlugin } from "../extensions/Collaboration/ForkYDocPlugin.js";
119
- import { EventEmitter } from "../util/EventEmitter.js";
120
- import { BlockNoteExtension } from "./BlockNoteExtension.js";
117
+ Block,
118
+ BlockNoteSchema,
119
+ DefaultBlockSchema,
120
+ DefaultInlineContentSchema,
121
+ DefaultStyleSchema,
122
+ PartialBlock,
123
+ } from "../blocks/index.js";
121
124
 
122
125
  import "../style.css";
123
126
 
@@ -188,11 +191,6 @@ export type BlockNoteEditorOptions<
188
191
  showCursorLabels?: "always" | "activity";
189
192
  };
190
193
 
191
- /**
192
- * Options for code blocks.
193
- */
194
- codeBlock?: CodeBlockOptions;
195
-
196
194
  /**
197
195
  * Configuration for the comments feature, requires a `threadStore`.
198
196
  *
@@ -252,18 +250,6 @@ export type BlockNoteEditorOptions<
252
250
  class?: string;
253
251
  }) => Plugin;
254
252
 
255
- /**
256
- * Configuration for headings
257
- */
258
- heading?: {
259
- /**
260
- * The levels of headings that should be available in the editor.
261
- * @note Configurable up to 6 levels of headings.
262
- * @default [1, 2, 3]
263
- */
264
- levels?: (1 | 2 | 3 | 4 | 5 | 6)[];
265
- };
266
-
267
253
  /**
268
254
  * The content that should be in the editor when it's created, represented as an array of {@link PartialBlock} objects.
269
255
  *
@@ -303,7 +289,11 @@ export type BlockNoteEditorOptions<
303
289
  */
304
290
  pasteHandler?: (context: {
305
291
  event: ClipboardEvent;
306
- editor: BlockNoteEditor<BSchema, ISchema, SSchema>;
292
+ editor: BlockNoteEditor<
293
+ NoInfer<BSchema>,
294
+ NoInfer<ISchema>,
295
+ NoInfer<SSchema>
296
+ >;
307
297
  /**
308
298
  * The default paste handler
309
299
  * @param context The context object
@@ -343,7 +333,7 @@ export type BlockNoteEditorOptions<
343
333
  * See [Custom Schemas](https://www.blocknotejs.org/docs/custom-schemas) for more info.
344
334
  * @remarks `BlockNoteSchema`
345
335
  */
346
- schema: BlockNoteSchema<BSchema, ISchema, SSchema>;
336
+ schema: CustomBlockNoteSchema<BSchema, ISchema, SSchema>;
347
337
 
348
338
  /**
349
339
  * A flag indicating whether to set an HTML ID for every block
@@ -446,16 +436,6 @@ export type BlockNoteEditorOptions<
446
436
  * @internal
447
437
  */
448
438
  extensions?: Array<BlockNoteExtension | BlockNoteExtensionFactory>;
449
-
450
- /**
451
- * Boolean indicating whether the editor is in headless mode.
452
- * Headless mode means we can use features like importing / exporting blocks,
453
- * but there's no underlying editor (UI) instantiated.
454
- *
455
- * You probably don't need to set this manually, but use the `server-util` package instead that uses this option internally
456
- * @internal
457
- */
458
- _headless?: boolean;
459
439
  };
460
440
 
461
441
  const blockNoteTipTapOptions = {
@@ -481,19 +461,9 @@ export class BlockNoteEditor<
481
461
  */
482
462
  public extensions: Record<string, SupportedExtension> = {};
483
463
 
484
- /**
485
- * Boolean indicating whether the editor is in headless mode.
486
- * Headless mode means we can use features like importing / exporting blocks,
487
- * but there's no underlying editor (UI) instantiated.
488
- *
489
- * You probably don't need to set this manually, but use the `server-util` package instead that uses this option internally
490
- */
491
- public readonly headless: boolean = false;
492
-
493
- public readonly _tiptapEditor: Omit<BlockNoteTipTapEditor, "view"> & {
494
- view: EditorView | undefined;
464
+ public readonly _tiptapEditor: TiptapEditor & {
495
465
  contentComponent: any;
496
- } = undefined as any; // TODO: Type should actually reflect that it can be `undefined` in headless mode
466
+ };
497
467
 
498
468
  /**
499
469
  * Used by React to store a reference to an `ElementRenderer` helper utility to make sure we can render React elements
@@ -517,7 +487,7 @@ export class BlockNoteEditor<
517
487
  /**
518
488
  * The schema of the editor. The schema defines which Blocks, InlineContent, and Styles are available in the editor.
519
489
  */
520
- public readonly schema: BlockNoteSchema<BSchema, ISchema, SSchema>;
490
+ public readonly schema: CustomBlockNoteSchema<BSchema, ISchema, SSchema>;
521
491
 
522
492
  public readonly blockImplementations: BlockSpecs;
523
493
  public readonly inlineContentImplementations: InlineContentSpecs;
@@ -580,22 +550,27 @@ export class BlockNoteEditor<
580
550
  cellTextColor: boolean;
581
551
  headers: boolean;
582
552
  };
583
- codeBlock: CodeBlockOptions;
584
- heading: {
585
- levels: (1 | 2 | 3 | 4 | 5 | 6)[];
586
- };
587
553
  };
588
-
589
554
  public static create<
590
- BSchema extends BlockSchema = DefaultBlockSchema,
591
- ISchema extends InlineContentSchema = DefaultInlineContentSchema,
592
- SSchema extends StyleSchema = DefaultStyleSchema,
593
- >(options: Partial<BlockNoteEditorOptions<BSchema, ISchema, SSchema>> = {}) {
594
- return new BlockNoteEditor<BSchema, ISchema, SSchema>(options);
555
+ Options extends Partial<BlockNoteEditorOptions<any, any, any>> | undefined,
556
+ >(
557
+ options?: Options,
558
+ ): Options extends {
559
+ schema: CustomBlockNoteSchema<infer BSchema, infer ISchema, infer SSchema>;
560
+ }
561
+ ? BlockNoteEditor<BSchema, ISchema, SSchema>
562
+ : BlockNoteEditor<
563
+ DefaultBlockSchema,
564
+ DefaultInlineContentSchema,
565
+ DefaultStyleSchema
566
+ > {
567
+ return new BlockNoteEditor(options ?? {}) as any;
595
568
  }
596
569
 
597
570
  protected constructor(
598
- protected readonly options: Partial<BlockNoteEditorOptions<any, any, any>>,
571
+ protected readonly options: Partial<
572
+ BlockNoteEditorOptions<BSchema, ISchema, SSchema>
573
+ >,
599
574
  ) {
600
575
  super();
601
576
  const anyOpts = options as any;
@@ -631,22 +606,18 @@ export class BlockNoteEditor<
631
606
  cellTextColor: options?.tables?.cellTextColor ?? false,
632
607
  headers: options?.tables?.headers ?? false,
633
608
  },
634
- codeBlock: {
635
- indentLineWithTab: options?.codeBlock?.indentLineWithTab ?? true,
636
- defaultLanguage: options?.codeBlock?.defaultLanguage ?? "text",
637
- supportedLanguages: options?.codeBlock?.supportedLanguages ?? {},
638
- createHighlighter: options?.codeBlock?.createHighlighter ?? undefined,
639
- },
640
- heading: {
641
- levels: options?.heading?.levels ?? [1, 2, 3],
642
- },
643
609
  };
644
610
 
645
611
  // apply defaults
646
612
  const newOptions = {
647
613
  defaultStyles: true,
648
- schema: options.schema || BlockNoteSchema.create(),
649
- _headless: false,
614
+ schema:
615
+ options.schema ||
616
+ (BlockNoteSchema.create() as unknown as CustomBlockNoteSchema<
617
+ BSchema,
618
+ ISchema,
619
+ SSchema
620
+ >),
650
621
  ...options,
651
622
  placeholders: {
652
623
  ...this.dictionary.placeholders,
@@ -660,7 +631,6 @@ export class BlockNoteEditor<
660
631
 
661
632
  this.resolveUsers = newOptions.resolveUsers;
662
633
 
663
- // @ts-ignore
664
634
  this.schema = newOptions.schema;
665
635
  this.blockImplementations = newOptions.schema.blockSpecs;
666
636
  this.inlineContentImplementations = newOptions.schema.inlineContentSpecs;
@@ -677,7 +647,7 @@ export class BlockNoteEditor<
677
647
  disableExtensions: newOptions.disableExtensions,
678
648
  setIdAttribute: newOptions.setIdAttribute,
679
649
  animations: newOptions.animations ?? true,
680
- tableHandles: checkDefaultBlockTypeInSchema("table", this),
650
+ tableHandles: editorHasBlockWithType(this, "table"),
681
651
  dropCursor: this.options.dropCursor ?? dropCursor,
682
652
  placeholders: newOptions.placeholders,
683
653
  tabBehavior: newOptions.tabBehavior,
@@ -696,7 +666,7 @@ export class BlockNoteEditor<
696
666
  // factory
697
667
  ext = ext(this);
698
668
  }
699
- const key = (ext.constructor as any).key();
669
+ const key = (ext as any).key ?? (ext.constructor as any).key();
700
670
  if (!key) {
701
671
  throw new Error(
702
672
  `Extension ${ext.constructor.name} does not have a key method`,
@@ -763,7 +733,6 @@ export class BlockNoteEditor<
763
733
  }
764
734
 
765
735
  this.resolveFileUrl = newOptions.resolveFileUrl;
766
- this.headless = newOptions._headless;
767
736
 
768
737
  const collaborationEnabled =
769
738
  "ySyncPlugin" in this.extensions ||
@@ -776,57 +745,107 @@ export class BlockNoteEditor<
776
745
  );
777
746
  }
778
747
 
779
- const initialContent =
780
- newOptions.initialContent ||
781
- (collaborationEnabled
782
- ? [
783
- {
784
- type: "paragraph",
785
- id: "initialBlockId",
786
- },
787
- ]
788
- : [
789
- {
790
- type: "paragraph",
791
- id: UniqueID.options.generateID(),
792
- },
793
- ]);
794
-
795
- if (!Array.isArray(initialContent) || initialContent.length === 0) {
796
- throw new Error(
797
- "initialContent must be a non-empty array of blocks, received: " +
798
- initialContent,
799
- );
800
- }
801
-
748
+ const blockExtensions = Object.fromEntries(
749
+ Object.values(this.schema.blockSpecs)
750
+ .map((block) => (block as any).extensions as any)
751
+ .filter((ext) => ext !== undefined)
752
+ .flat()
753
+ .map((ext) => [ext.key ?? ext.constructor.key(), ext]),
754
+ );
802
755
  const tiptapExtensions = [
803
- ...Object.entries(this.extensions).map(([key, ext]) => {
804
- if (
805
- ext instanceof Extension ||
806
- ext instanceof TipTapNode ||
807
- ext instanceof Mark
808
- ) {
809
- // tiptap extension
810
- return ext;
811
- }
756
+ ...Object.entries({ ...this.extensions, ...blockExtensions }).map(
757
+ ([key, ext]) => {
758
+ if (
759
+ ext instanceof Extension ||
760
+ ext instanceof TipTapNode ||
761
+ ext instanceof Mark
762
+ ) {
763
+ // tiptap extension
764
+ return ext;
765
+ }
812
766
 
813
- if (ext instanceof BlockNoteExtension && !ext.plugins.length) {
814
- return undefined;
815
- }
767
+ if (ext instanceof BlockNoteExtension) {
768
+ if (
769
+ !ext.plugins.length &&
770
+ !ext.keyboardShortcuts &&
771
+ !ext.inputRules &&
772
+ !ext.tiptapExtensions
773
+ ) {
774
+ return undefined;
775
+ }
776
+ // "blocknote" extensions (prosemirror plugins)
777
+ return Extension.create({
778
+ name: key,
779
+ priority: ext.priority,
780
+ addProseMirrorPlugins: () => ext.plugins,
781
+ addExtensions: () => ext.tiptapExtensions || [],
782
+ // TODO maybe collect all input rules from all extensions into one plugin
783
+ // TODO consider using the prosemirror-inputrules package instead
784
+ addInputRules: ext.inputRules
785
+ ? () =>
786
+ ext.inputRules!.map(
787
+ (inputRule) =>
788
+ new InputRule({
789
+ find: inputRule.find,
790
+ handler: ({ range, match, state }) => {
791
+ const replaceWith = inputRule.replace({
792
+ match,
793
+ range,
794
+ editor: this,
795
+ });
796
+ if (replaceWith) {
797
+ const blockInfo = getBlockInfoFromTransaction(
798
+ state.tr,
799
+ );
800
+
801
+ // TODO this is weird, why do we need it?
802
+ if (
803
+ blockInfo.isBlockContainer &&
804
+ blockInfo.blockContent.node.type.spec
805
+ .content === "inline*"
806
+ ) {
807
+ const tr = state.tr.deleteRange(
808
+ range.from,
809
+ range.to,
810
+ );
811
+ updateBlockTr(
812
+ tr,
813
+ blockInfo.bnBlock.beforePos,
814
+ replaceWith,
815
+ range.from,
816
+ range.to,
817
+ );
818
+ return undefined;
819
+ }
820
+ }
821
+ return null;
822
+ },
823
+ }),
824
+ )
825
+ : undefined,
826
+ addKeyboardShortcuts: ext.keyboardShortcuts
827
+ ? () => {
828
+ return Object.fromEntries(
829
+ Object.entries(ext.keyboardShortcuts!).map(
830
+ ([key, value]) => [
831
+ key,
832
+ () => value({ editor: this as any }),
833
+ ],
834
+ ),
835
+ );
836
+ }
837
+ : undefined,
838
+ });
839
+ }
816
840
 
817
- // "blocknote" extensions (prosemirror plugins)
818
- return Extension.create({
819
- name: key,
820
- priority: ext.priority,
821
- addProseMirrorPlugins: () => ext.plugins,
822
- });
823
- }),
841
+ return undefined;
842
+ },
843
+ ),
824
844
  ].filter((ext): ext is Extension => ext !== undefined);
825
-
826
- const tiptapOptions: BlockNoteTipTapEditorOptions = {
845
+ const tiptapOptions: EditorOptions = {
827
846
  ...blockNoteTipTapOptions,
828
847
  ...newOptions._tiptapOptions,
829
- content: initialContent,
848
+ element: null,
830
849
  extensions: tiptapExtensions,
831
850
  editorProps: {
832
851
  ...newOptions._tiptapOptions?.editorProps,
@@ -845,22 +864,61 @@ export class BlockNoteEditor<
845
864
  },
846
865
  transformPasted,
847
866
  },
848
- };
867
+ } as any;
849
868
 
850
- if (!this.headless) {
851
- this._tiptapEditor = BlockNoteTipTapEditor.create(
852
- tiptapOptions,
853
- this.schema.styleSchema,
854
- ) as BlockNoteTipTapEditor & {
855
- view: any;
856
- contentComponent: any;
857
- };
869
+ try {
870
+ const initialContent =
871
+ newOptions.initialContent ||
872
+ (collaborationEnabled
873
+ ? [
874
+ {
875
+ type: "paragraph",
876
+ id: "initialBlockId",
877
+ },
878
+ ]
879
+ : [
880
+ {
881
+ type: "paragraph",
882
+ id: UniqueID.options.generateID(),
883
+ },
884
+ ]);
885
+
886
+ if (!Array.isArray(initialContent) || initialContent.length === 0) {
887
+ throw new Error(
888
+ "initialContent must be a non-empty array of blocks, received: " +
889
+ initialContent,
890
+ );
891
+ }
892
+ const schema = getSchema(tiptapOptions.extensions!);
893
+ const pmNodes = initialContent.map((b) =>
894
+ blockToNode(b, schema, this.schema.styleSchema).toJSON(),
895
+ );
896
+ const doc = createDocument(
897
+ {
898
+ type: "doc",
899
+ content: [
900
+ {
901
+ type: "blockGroup",
902
+ content: pmNodes,
903
+ },
904
+ ],
905
+ },
906
+ schema,
907
+ tiptapOptions.parseOptions,
908
+ );
909
+
910
+ this._tiptapEditor = new TiptapEditor({
911
+ ...tiptapOptions,
912
+ content: doc.toJSON(),
913
+ }) as any;
858
914
  this.pmSchema = this._tiptapEditor.schema;
859
- } else {
860
- // In headless mode, we don't instantiate an underlying TipTap editor,
861
- // but we still need the schema
862
- this.pmSchema = getSchema(tiptapOptions.extensions!);
915
+ } catch (e) {
916
+ throw new Error(
917
+ "Error creating document from blocks passed as `initialContent`",
918
+ { cause: e },
919
+ );
863
920
  }
921
+
864
922
  this.pmSchema.cached.blockNoteEditor = this;
865
923
  this.emit("create");
866
924
  }
@@ -890,7 +948,7 @@ export class BlockNoteEditor<
890
948
  }
891
949
  const state = this._tiptapEditor.state;
892
950
  const view = this._tiptapEditor.view;
893
- const dispatch = (tr: Transaction) => this._tiptapEditor.dispatch(tr);
951
+ const dispatch = (tr: Transaction) => view.dispatch(tr);
894
952
 
895
953
  return command(state, dispatch, view);
896
954
  }
@@ -973,7 +1031,7 @@ export class BlockNoteEditor<
973
1031
  !activeTr.isGeneric)
974
1032
  ) {
975
1033
  // Dispatch the transaction if it was modified
976
- this._tiptapEditor.dispatch(activeTr);
1034
+ this._tiptapEditor.view.dispatch(activeTr);
977
1035
  }
978
1036
 
979
1037
  return result;
@@ -1002,17 +1060,21 @@ export class BlockNoteEditor<
1002
1060
  }
1003
1061
  return extension;
1004
1062
  }
1005
-
1006
1063
  /**
1007
- * Mount the editor to a parent DOM element. Call mount(undefined) to clean up
1064
+ * Mount the editor to a DOM element.
1008
1065
  *
1009
1066
  * @warning Not needed to call manually when using React, use BlockNoteView to take care of mounting
1010
1067
  */
1011
- public mount = (
1012
- parentElement?: HTMLElement | null,
1013
- contentComponent?: any,
1014
- ) => {
1015
- this._tiptapEditor.mount(this, parentElement, contentComponent);
1068
+ public mount = (element: HTMLElement) => {
1069
+ // TODO: Fix typing for this in a TipTap PR
1070
+ this._tiptapEditor.mount({ mount: element } as any);
1071
+ };
1072
+
1073
+ /**
1074
+ * Unmount the editor from the DOM element it is bound to
1075
+ */
1076
+ public unmount = () => {
1077
+ this._tiptapEditor.unmount();
1016
1078
  };
1017
1079
 
1018
1080
  /**
@@ -1045,8 +1107,15 @@ export class BlockNoteEditor<
1045
1107
  return this.prosemirrorView?.hasFocus() || false;
1046
1108
  }
1047
1109
 
1110
+ public get headless() {
1111
+ return !this._tiptapEditor.isInitialized;
1112
+ }
1113
+
1048
1114
  public focus() {
1049
- this.prosemirrorView?.focus();
1115
+ if (this.headless) {
1116
+ return;
1117
+ }
1118
+ this.prosemirrorView.focus();
1050
1119
  }
1051
1120
 
1052
1121
  public onUploadStart(callback: (blockId?: string) => void) {
@@ -1263,12 +1332,6 @@ export class BlockNoteEditor<
1263
1332
  * @returns True if the editor is editable, false otherwise.
1264
1333
  */
1265
1334
  public get isEditable(): boolean {
1266
- if (!this._tiptapEditor) {
1267
- if (!this.headless) {
1268
- throw new Error("no editor, but also not headless?");
1269
- }
1270
- return false;
1271
- }
1272
1335
  return this._tiptapEditor.isEditable === undefined
1273
1336
  ? true
1274
1337
  : this._tiptapEditor.isEditable;
@@ -1279,13 +1342,6 @@ export class BlockNoteEditor<
1279
1342
  * @param editable True to make the editor editable, or false to lock it.
1280
1343
  */
1281
1344
  public set isEditable(editable: boolean) {
1282
- if (!this._tiptapEditor) {
1283
- if (!this.headless) {
1284
- throw new Error("no editor, but also not headless?");
1285
- }
1286
- // not relevant on headless
1287
- return;
1288
- }
1289
1345
  if (this._tiptapEditor.options.editable !== editable) {
1290
1346
  this._tiptapEditor.setEditable(editable);
1291
1347
  }
@@ -1662,12 +1718,6 @@ export class BlockNoteEditor<
1662
1718
  },
1663
1719
  ) => boolean | void,
1664
1720
  ): () => void {
1665
- if (this.headless) {
1666
- return () => {
1667
- // noop
1668
- };
1669
- }
1670
-
1671
1721
  return (this.extensions["blockChange"] as BlockChangePlugin).subscribe(
1672
1722
  (context) => callback(this, context),
1673
1723
  );
@@ -1690,11 +1740,6 @@ export class BlockNoteEditor<
1690
1740
  },
1691
1741
  ) => void,
1692
1742
  ) {
1693
- if (this.headless) {
1694
- // Note: would be nice if this is possible in headless mode as well
1695
- return;
1696
- }
1697
-
1698
1743
  const cb = ({
1699
1744
  transaction,
1700
1745
  appendedTransactions,
@@ -1708,10 +1753,10 @@ export class BlockNoteEditor<
1708
1753
  });
1709
1754
  };
1710
1755
 
1711
- this._tiptapEditor.on("v3-update", cb);
1756
+ this._tiptapEditor.on("update", cb);
1712
1757
 
1713
1758
  return () => {
1714
- this._tiptapEditor.off("v3-update", cb);
1759
+ this._tiptapEditor.off("update", cb);
1715
1760
  };
1716
1761
  }
1717
1762
 
@@ -1725,10 +1770,6 @@ export class BlockNoteEditor<
1725
1770
  callback: (editor: BlockNoteEditor<BSchema, ISchema, SSchema>) => void,
1726
1771
  includeSelectionChangedByRemote?: boolean,
1727
1772
  ) {
1728
- if (this.headless) {
1729
- return;
1730
- }
1731
-
1732
1773
  const cb = (e: { transaction: Transaction }) => {
1733
1774
  if (
1734
1775
  e.transaction.getMeta(ySyncPluginKey) &&