@blocknote/core 0.14.5 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocknote.js +1219 -1005
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -6
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +26 -23
- package/src/api/blockManipulation/blockManipulation.ts +21 -21
- package/src/api/exporters/copyExtension.ts +14 -10
- package/src/api/exporters/html/externalHTMLExporter.ts +26 -8
- package/src/api/exporters/html/htmlConversion.test.ts +27 -25
- package/src/api/exporters/html/internalHTMLSerializer.ts +22 -7
- package/src/api/exporters/html/util/sharedHTMLConversion.ts +3 -2
- package/src/api/exporters/markdown/markdownExporter.ts +5 -4
- package/src/api/nodeConversions/nodeConversions.test.ts +9 -6
- package/src/api/parsers/html/parseHTML.test.ts +3 -4
- package/src/blocks/FileBlockContent/fileBlockHelpers.ts +1 -1
- package/src/blocks/defaultBlockHelpers.ts +3 -6
- package/src/blocks/defaultBlockTypeGuards.ts +26 -1
- package/src/editor/BlockNoteEditor.test.ts +48 -1
- package/src/editor/BlockNoteEditor.ts +153 -36
- package/src/editor/BlockNoteExtensions.ts +0 -1
- package/src/editor/BlockNoteTipTapEditor.ts +14 -5
- package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +10 -4
- package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +2 -2
- package/src/extensions/SideMenu/SideMenuPlugin.ts +7 -12
- package/src/extensions/SuggestionMenu/DefaultGridSuggestionItem.ts +4 -0
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +2 -2
- package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +38 -0
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +13 -6
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +5 -5
- package/src/extensions/TextAlignment/TextAlignmentExtension.ts +7 -3
- package/src/extensions/TextColor/TextColorExtension.ts +7 -3
- package/src/i18n/locales/ar.ts +6 -0
- package/src/i18n/locales/en.ts +18 -12
- package/src/i18n/locales/fr.ts +6 -0
- package/src/i18n/locales/is.ts +6 -0
- package/src/i18n/locales/ja.ts +6 -0
- package/src/i18n/locales/ko.ts +15 -0
- package/src/i18n/locales/nl.ts +11 -0
- package/src/i18n/locales/pl.ts +6 -0
- package/src/i18n/locales/pt.ts +6 -0
- package/src/i18n/locales/ru.ts +322 -309
- package/src/i18n/locales/vi.ts +13 -0
- package/src/i18n/locales/zh.ts +14 -0
- package/src/index.ts +14 -5
- package/src/style.css +2 -7
- package/types/src/api/exporters/html/externalHTMLExporter.d.ts +6 -2
- package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +6 -2
- package/types/src/api/exporters/html/util/sharedHTMLConversion.d.ts +3 -1
- package/types/src/api/exporters/markdown/markdownExporter.d.ts +4 -2
- package/types/src/blocks/defaultBlockTypeGuards.d.ts +4 -1
- package/types/src/editor/BlockNoteEditor.d.ts +71 -11
- package/types/src/editor/BlockNoteExtensions.d.ts +0 -1
- package/types/src/editor/BlockNoteTipTapEditor.d.ts +2 -2
- package/types/src/extensions/SuggestionMenu/DefaultGridSuggestionItem.d.ts +4 -0
- package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +1 -2
- package/types/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.d.ts +4 -0
- package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +1 -1
- package/types/src/i18n/locales/en.d.ts +6 -0
- package/types/src/index.d.ts +11 -5
package/dist/webpack-stats.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"builtAt":
|
|
1
|
+
{"builtAt":1721046963540,"assets":[{"name":"blocknote.umd.cjs","size":185285},{"name":"blocknote.umd.cjs.map","size":680363}],"chunks":[{"id":"a1ee98a","entry":true,"initial":true,"files":["blocknote.umd.cjs"],"names":["index"]}],"modules":[{"name":"./src/i18n/locales/ar.ts","size":6582,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/en.ts","size":6664,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/fr.ts","size":7294,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/is.ts","size":6876,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/ja.ts","size":6323,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/ko.ts","size":6146,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/nl.ts","size":7079,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/pl.ts","size":6768,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/pt.ts","size":6965,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/vi.ts","size":6927,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/zh.ts","size":6093,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/ru.ts","size":7638,"chunks":["a1ee98a"]},{"name":"./src/i18n/locales/index.ts","size":0,"chunks":["a1ee98a"]},{"name":"./src/extensions/UniqueID/UniqueID.ts","size":8518,"chunks":["a1ee98a"]},{"name":"./src/api/getBlockInfoFromPos.ts","size":1691,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/types.ts","size":302,"chunks":["a1ee98a"]},{"name":"./src/util/typescript.ts","size":331,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/nodeConversions.ts","size":11998,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/sharedHTMLConversion.ts","size":2311,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts","size":3119,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/externalHTMLExporter.ts","size":1161,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/internalHTMLSerializer.ts","size":758,"chunks":["a1ee98a"]},{"name":"./src/util/browser.ts","size":536,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockHelpers.ts","size":1691,"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":3877,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/createSpec.ts","size":2814,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/internal.ts","size":1357,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/createSpec.ts","size":1627,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/internal.ts","size":1162,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/createSpec.ts","size":1263,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/fileBlockHelpers.ts","size":8574,"chunks":["a1ee98a"]},{"name":"./src/blocks/AudioBlockContent/audioBlockHelpers.ts","size":108,"chunks":["a1ee98a"]},{"name":"./src/blocks/AudioBlockContent/AudioBlockContent.ts","size":3741,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/FileBlockContent.ts","size":1939,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/imageBlockHelpers.ts","size":175,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/ImageBlockContent.ts","size":3959,"chunks":["a1ee98a"]},{"name":"./src/blocks/VideoBlockContent/videoBlockHelpers.ts","size":175,"chunks":["a1ee98a"]},{"name":"./src/blocks/VideoBlockContent/VideoBlockContent.ts","size":3763,"chunks":["a1ee98a"]},{"name":"./src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts","size":316,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorMark.ts","size":946,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorMark.ts","size":866,"chunks":["a1ee98a"]},{"name":"./src/api/getCurrentBlockContentType.ts","size":192,"chunks":["a1ee98a"]},{"name":"./src/blocks/HeadingBlockContent/HeadingBlockContent.ts","size":3439,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts","size":1201,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts","size":3122,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts","size":1862,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts","size":3437,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts","size":6423,"chunks":["a1ee98a"]},{"name":"./src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts","size":1307,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableExtension.ts","size":1462,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableBlockContent.ts","size":1624,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlocks.ts","size":1123,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockTypeGuards.ts","size":1580,"chunks":["a1ee98a"]},{"name":"./src/api/nodeUtil.ts","size":548,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/blockManipulation.ts","size":5664,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/removeUnderlinesRehypePlugin.ts","size":752,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts","size":775,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/markdownExporter.ts","size":640,"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":1054,"chunks":["a1ee98a"]},{"name":"./src/util/EventEmitter.ts","size":744,"chunks":["a1ee98a"]},{"name":"./src/extensions/FilePanel/FilePanelPlugin.ts","size":3480,"chunks":["a1ee98a"]},{"name":"./src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts","size":4355,"chunks":["a1ee98a"]},{"name":"./src/extensions/LinkToolbar/LinkToolbarPlugin.ts","size":7365,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/MultipleNodeSelection.ts","size":1616,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/SideMenuPlugin.ts","size":16774,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/SuggestionPlugin.ts","size":7719,"chunks":["a1ee98a"]},{"name":"./src/extensions/TableHandles/TableHandlesPlugin.ts","size":15235,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/copyExtension.ts","size":2951,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts","size":6319,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/acceptedMIMETypes.ts","size":91,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/handleFileInsertion.ts","size":1983,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/pasteExtension.ts","size":1244,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/fileDropExtension.ts","size":884,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorExtension.ts","size":791,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextAlignment/TextAlignmentExtension.ts","size":928,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorExtension.ts","size":725,"chunks":["a1ee98a"]},{"name":"./src/extensions/TrailingNode/TrailingNodeExtension.ts","size":1594,"chunks":["a1ee98a"]},{"name":"./src/extensions/NonEditableBlocks/NonEditableBlockPlugin.ts","size":1014,"chunks":["a1ee98a"]},{"name":"./src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts","size":4578,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockContainer.ts","size":18112,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockGroup.ts","size":1097,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/Doc.ts","size":90,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteExtensions.ts","size":4243,"chunks":["a1ee98a"]},{"name":"./src/editor/transformPasted.ts","size":1062,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteSchema.ts","size":1044,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteTipTapEditor.ts","size":2823,"chunks":["a1ee98a"]},{"name":"./src/extensions/Placeholder/PlaceholderPlugin.ts","size":2758,"chunks":["a1ee98a"]},{"name":"./src/style.css","size":17,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteEditor.ts","size":26212,"chunks":["a1ee98a"]},{"name":"./src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts","size":603,"chunks":["a1ee98a"]},{"name":"./src/api/testUtil/partialBlockTestUtil.ts","size":2166,"chunks":["a1ee98a"]},{"name":"./src/index.ts","size":0,"chunks":["a1ee98a"]}]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"homepage": "https://github.com/TypeCellOS/BlockNote",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.15.0",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
9
|
"types",
|
|
@@ -54,26 +54,28 @@
|
|
|
54
54
|
"clean": "rimraf dist && rimraf types"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"@tiptap/
|
|
59
|
-
"@tiptap/extension-
|
|
60
|
-
"@tiptap/extension-
|
|
61
|
-
"@tiptap/extension-collaboration
|
|
62
|
-
"@tiptap/extension-
|
|
63
|
-
"@tiptap/extension-
|
|
64
|
-
"@tiptap/extension-
|
|
65
|
-
"@tiptap/extension-
|
|
66
|
-
"@tiptap/extension-
|
|
67
|
-
"@tiptap/extension-
|
|
68
|
-
"@tiptap/extension-
|
|
69
|
-
"@tiptap/extension-
|
|
70
|
-
"@tiptap/extension-
|
|
71
|
-
"@tiptap/extension-
|
|
72
|
-
"@tiptap/extension-table-
|
|
73
|
-
"@tiptap/extension-table-
|
|
74
|
-
"@tiptap/extension-
|
|
75
|
-
"@tiptap/extension-
|
|
76
|
-
"@tiptap/
|
|
57
|
+
"@emoji-mart/data": "^1.2.1",
|
|
58
|
+
"@tiptap/core": "^2.5.0",
|
|
59
|
+
"@tiptap/extension-bold": "^2.5.0",
|
|
60
|
+
"@tiptap/extension-code": "^2.5.0",
|
|
61
|
+
"@tiptap/extension-collaboration": "^2.5.0",
|
|
62
|
+
"@tiptap/extension-collaboration-cursor": "^2.5.0",
|
|
63
|
+
"@tiptap/extension-dropcursor": "^2.5.0",
|
|
64
|
+
"@tiptap/extension-gapcursor": "^2.5.0",
|
|
65
|
+
"@tiptap/extension-hard-break": "^2.5.0",
|
|
66
|
+
"@tiptap/extension-history": "^2.5.0",
|
|
67
|
+
"@tiptap/extension-horizontal-rule": "^2.5.0",
|
|
68
|
+
"@tiptap/extension-italic": "^2.5.0",
|
|
69
|
+
"@tiptap/extension-link": "^2.5.0",
|
|
70
|
+
"@tiptap/extension-paragraph": "^2.5.0",
|
|
71
|
+
"@tiptap/extension-strike": "^2.5.0",
|
|
72
|
+
"@tiptap/extension-table-cell": "^2.5.0",
|
|
73
|
+
"@tiptap/extension-table-header": "^2.5.0",
|
|
74
|
+
"@tiptap/extension-table-row": "^2.5.0",
|
|
75
|
+
"@tiptap/extension-text": "^2.5.0",
|
|
76
|
+
"@tiptap/extension-underline": "^2.5.0",
|
|
77
|
+
"@tiptap/pm": "^2.5.0",
|
|
78
|
+
"emoji-mart": "^5.6.0",
|
|
77
79
|
"hast-util-from-dom": "^4.2.0",
|
|
78
80
|
"prosemirror-model": "^1.21.0",
|
|
79
81
|
"prosemirror-state": "^1.4.3",
|
|
@@ -90,11 +92,12 @@
|
|
|
90
92
|
"remark-stringify": "^10.0.2",
|
|
91
93
|
"unified": "^10.1.2",
|
|
92
94
|
"uuid": "^8.3.2",
|
|
93
|
-
"y-prosemirror": "1.2.
|
|
95
|
+
"y-prosemirror": "1.2.9",
|
|
94
96
|
"y-protocols": "^1.0.6",
|
|
95
97
|
"yjs": "^13.6.15"
|
|
96
98
|
},
|
|
97
99
|
"devDependencies": {
|
|
100
|
+
"@types/emoji-mart": "^3.0.14",
|
|
98
101
|
"@types/hast": "^2.3.4",
|
|
99
102
|
"@types/uuid": "^8.3.4",
|
|
100
103
|
"eslint": "^8.10.0",
|
|
@@ -116,5 +119,5 @@
|
|
|
116
119
|
"access": "public",
|
|
117
120
|
"registry": "https://registry.npmjs.org/"
|
|
118
121
|
},
|
|
119
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "acd5683d0b1dca70013e16ce360ebc9fd6f50716"
|
|
120
123
|
}
|
|
@@ -23,42 +23,45 @@ export function insertBlocks<
|
|
|
23
23
|
placement: "before" | "after" | "nested" = "before",
|
|
24
24
|
editor: BlockNoteEditor<BSchema, I, S>
|
|
25
25
|
): Block<BSchema, I, S>[] {
|
|
26
|
-
const ttEditor = editor._tiptapEditor;
|
|
27
|
-
|
|
28
26
|
const id =
|
|
29
27
|
typeof referenceBlock === "string" ? referenceBlock : referenceBlock.id;
|
|
30
28
|
|
|
31
29
|
const nodesToInsert: Node[] = [];
|
|
32
30
|
for (const blockSpec of blocksToInsert) {
|
|
33
31
|
nodesToInsert.push(
|
|
34
|
-
blockToNode(blockSpec,
|
|
32
|
+
blockToNode(blockSpec, editor.pmSchema, editor.schema.styleSchema)
|
|
35
33
|
);
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
const { node, posBeforeNode } = getNodeById(
|
|
36
|
+
const { node, posBeforeNode } = getNodeById(
|
|
37
|
+
id,
|
|
38
|
+
editor._tiptapEditor.state.doc
|
|
39
|
+
);
|
|
39
40
|
|
|
40
41
|
if (placement === "before") {
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
editor.dispatch(
|
|
43
|
+
editor._tiptapEditor.state.tr.insert(posBeforeNode, nodesToInsert)
|
|
43
44
|
);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
if (placement === "after") {
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
editor.dispatch(
|
|
49
|
+
editor._tiptapEditor.state.tr.insert(
|
|
50
|
+
posBeforeNode + node.nodeSize,
|
|
51
|
+
nodesToInsert
|
|
52
|
+
)
|
|
49
53
|
);
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
if (placement === "nested") {
|
|
53
57
|
// Case if block doesn't already have children.
|
|
54
58
|
if (node.childCount < 2) {
|
|
55
|
-
const blockGroupNode =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
59
|
+
const blockGroupNode = editor._tiptapEditor.state.schema.nodes[
|
|
60
|
+
"blockGroup"
|
|
61
|
+
].create({}, nodesToInsert);
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
editor.dispatch(
|
|
64
|
+
editor._tiptapEditor.state.tr.insert(
|
|
62
65
|
posBeforeNode + node.firstChild!.nodeSize + 1,
|
|
63
66
|
blockGroupNode
|
|
64
67
|
)
|
|
@@ -186,7 +189,7 @@ function removeBlocksWithCallback<
|
|
|
186
189
|
);
|
|
187
190
|
}
|
|
188
191
|
|
|
189
|
-
|
|
192
|
+
editor.dispatch(tr);
|
|
190
193
|
|
|
191
194
|
return removedBlocks;
|
|
192
195
|
}
|
|
@@ -214,12 +217,10 @@ export function replaceBlocks<
|
|
|
214
217
|
insertedBlocks: Block<BSchema, I, S>[];
|
|
215
218
|
removedBlocks: Block<BSchema, I, S>[];
|
|
216
219
|
} {
|
|
217
|
-
const ttEditor = editor._tiptapEditor;
|
|
218
|
-
|
|
219
220
|
const nodesToInsert: Node[] = [];
|
|
220
221
|
for (const block of blocksToInsert) {
|
|
221
222
|
nodesToInsert.push(
|
|
222
|
-
blockToNode(block,
|
|
223
|
+
blockToNode(block, editor.pmSchema, editor.schema.styleSchema)
|
|
223
224
|
);
|
|
224
225
|
}
|
|
225
226
|
|
|
@@ -274,8 +275,7 @@ export function insertContentAt<
|
|
|
274
275
|
updateSelection: boolean;
|
|
275
276
|
} = { updateSelection: true }
|
|
276
277
|
) {
|
|
277
|
-
const
|
|
278
|
-
const tr = ttEditor.state.tr;
|
|
278
|
+
const tr = editor._tiptapEditor.state.tr;
|
|
279
279
|
|
|
280
280
|
// don’t dispatch an empty fragment because this can lead to strange errors
|
|
281
281
|
// if (content.toString() === "<>") {
|
|
@@ -344,7 +344,7 @@ export function insertContentAt<
|
|
|
344
344
|
selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
|
|
347
|
+
editor.dispatch(tr);
|
|
348
348
|
|
|
349
349
|
return true;
|
|
350
350
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Extension } from "@tiptap/core";
|
|
2
|
-
import { NodeSelection, Plugin } from "prosemirror-state";
|
|
3
2
|
import { Node } from "prosemirror-model";
|
|
3
|
+
import { NodeSelection, Plugin } from "prosemirror-state";
|
|
4
4
|
|
|
5
|
+
import { EditorView } from "prosemirror-view";
|
|
5
6
|
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
|
|
6
7
|
import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
|
|
7
8
|
import { createExternalHTMLExporter } from "./html/externalHTMLExporter";
|
|
8
9
|
import { createInternalHTMLSerializer } from "./html/internalHTMLSerializer";
|
|
9
10
|
import { cleanHTMLToMarkdown } from "./markdown/markdownExporter";
|
|
10
|
-
import { EditorView } from "prosemirror-view";
|
|
11
11
|
|
|
12
12
|
function selectedFragmentToHTML<
|
|
13
13
|
BSchema extends BlockSchema,
|
|
@@ -27,15 +27,19 @@ function selectedFragmentToHTML<
|
|
|
27
27
|
view.state.schema,
|
|
28
28
|
editor
|
|
29
29
|
);
|
|
30
|
-
const internalHTML =
|
|
31
|
-
|
|
30
|
+
const internalHTML = internalHTMLSerializer.serializeProseMirrorFragment(
|
|
31
|
+
selectedFragment,
|
|
32
|
+
{}
|
|
33
|
+
);
|
|
32
34
|
|
|
33
35
|
const externalHTMLExporter = createExternalHTMLExporter(
|
|
34
36
|
view.state.schema,
|
|
35
37
|
editor
|
|
36
38
|
);
|
|
37
|
-
const externalHTML =
|
|
38
|
-
|
|
39
|
+
const externalHTML = externalHTMLExporter.exportProseMirrorFragment(
|
|
40
|
+
selectedFragment,
|
|
41
|
+
{}
|
|
42
|
+
);
|
|
39
43
|
|
|
40
44
|
const plainText = cleanHTMLToMarkdown(externalHTML);
|
|
41
45
|
|
|
@@ -70,8 +74,8 @@ export const createCopyToClipboardExtension = <
|
|
|
70
74
|
(view.state.selection.node as Node).type.spec.group ===
|
|
71
75
|
"blockContent"
|
|
72
76
|
) {
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
editor.dispatch(
|
|
78
|
+
editor._tiptapEditor.state.tr.setSelection(
|
|
75
79
|
new NodeSelection(
|
|
76
80
|
view.state.doc.resolve(view.state.selection.from - 1)
|
|
77
81
|
)
|
|
@@ -109,8 +113,8 @@ export const createCopyToClipboardExtension = <
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
// Expands the selection to the parent `blockContainer` node.
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
editor.dispatch(
|
|
117
|
+
editor._tiptapEditor.state.tr.setSelection(
|
|
114
118
|
new NodeSelection(
|
|
115
119
|
view.state.doc.resolve(view.state.selection.from - 1)
|
|
116
120
|
)
|
|
@@ -37,8 +37,14 @@ export interface ExternalHTMLExporter<
|
|
|
37
37
|
I extends InlineContentSchema,
|
|
38
38
|
S extends StyleSchema
|
|
39
39
|
> {
|
|
40
|
-
exportBlocks: (
|
|
41
|
-
|
|
40
|
+
exportBlocks: (
|
|
41
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
42
|
+
options: { document?: Document }
|
|
43
|
+
) => string;
|
|
44
|
+
exportProseMirrorFragment: (
|
|
45
|
+
fragment: Fragment,
|
|
46
|
+
options: { document?: Document }
|
|
47
|
+
) => string;
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
export const createExternalHTMLExporter = <
|
|
@@ -54,8 +60,14 @@ export const createExternalHTMLExporter = <
|
|
|
54
60
|
node: Node,
|
|
55
61
|
options: { document?: Document }
|
|
56
62
|
) => HTMLElement;
|
|
57
|
-
exportProseMirrorFragment: (
|
|
58
|
-
|
|
63
|
+
exportProseMirrorFragment: (
|
|
64
|
+
fragment: Fragment,
|
|
65
|
+
options: { document?: Document }
|
|
66
|
+
) => string;
|
|
67
|
+
exportBlocks: (
|
|
68
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
69
|
+
options: { document?: Document }
|
|
70
|
+
) => string;
|
|
59
71
|
};
|
|
60
72
|
|
|
61
73
|
serializer.serializeNodeInner = (
|
|
@@ -66,7 +78,7 @@ export const createExternalHTMLExporter = <
|
|
|
66
78
|
// Like the `internalHTMLSerializer`, also uses `serializeProseMirrorFragment`
|
|
67
79
|
// but additionally runs it through the `simplifyBlocks` rehype plugin to
|
|
68
80
|
// convert the internal HTML to external.
|
|
69
|
-
serializer.exportProseMirrorFragment = (fragment) => {
|
|
81
|
+
serializer.exportProseMirrorFragment = (fragment, options) => {
|
|
70
82
|
const externalHTML = unified()
|
|
71
83
|
.use(rehypeParse, { fragment: true })
|
|
72
84
|
.use(simplifyBlocks, {
|
|
@@ -77,18 +89,24 @@ export const createExternalHTMLExporter = <
|
|
|
77
89
|
]),
|
|
78
90
|
})
|
|
79
91
|
.use(rehypeStringify)
|
|
80
|
-
.processSync(serializeProseMirrorFragment(fragment, serializer));
|
|
92
|
+
.processSync(serializeProseMirrorFragment(fragment, serializer, options));
|
|
81
93
|
|
|
82
94
|
return externalHTML.value as string;
|
|
83
95
|
};
|
|
84
96
|
|
|
85
|
-
serializer.exportBlocks = (
|
|
97
|
+
serializer.exportBlocks = (
|
|
98
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
99
|
+
options
|
|
100
|
+
) => {
|
|
86
101
|
const nodes = blocks.map((block) =>
|
|
87
102
|
blockToNode(block, schema, editor.schema.styleSchema)
|
|
88
103
|
);
|
|
89
104
|
const blockGroup = schema.nodes["blockGroup"].create(null, nodes);
|
|
90
105
|
|
|
91
|
-
return serializer.exportProseMirrorFragment(
|
|
106
|
+
return serializer.exportProseMirrorFragment(
|
|
107
|
+
Fragment.from(blockGroup),
|
|
108
|
+
options
|
|
109
|
+
);
|
|
92
110
|
};
|
|
93
111
|
|
|
94
112
|
return serializer;
|
|
@@ -25,11 +25,8 @@ async function convertToHTMLAndCompareSnapshots<
|
|
|
25
25
|
snapshotName: string
|
|
26
26
|
) {
|
|
27
27
|
addIdsToBlocks(blocks);
|
|
28
|
-
const serializer = createInternalHTMLSerializer(
|
|
29
|
-
|
|
30
|
-
editor
|
|
31
|
-
);
|
|
32
|
-
const internalHTML = serializer.serializeBlocks(blocks);
|
|
28
|
+
const serializer = createInternalHTMLSerializer(editor.pmSchema, editor);
|
|
29
|
+
const internalHTML = serializer.serializeBlocks(blocks, {});
|
|
33
30
|
const internalHTMLSnapshotPath =
|
|
34
31
|
"./__snapshots__/" +
|
|
35
32
|
snapshotDirectory +
|
|
@@ -48,11 +45,8 @@ async function convertToHTMLAndCompareSnapshots<
|
|
|
48
45
|
expect(parsed).toStrictEqual(fullBlocks);
|
|
49
46
|
|
|
50
47
|
// Create the "external" HTML, which is a cleaned up HTML representation, but lossy
|
|
51
|
-
const exporter = createExternalHTMLExporter(
|
|
52
|
-
|
|
53
|
-
editor
|
|
54
|
-
);
|
|
55
|
-
const externalHTML = exporter.exportBlocks(blocks);
|
|
48
|
+
const exporter = createExternalHTMLExporter(editor.pmSchema, editor);
|
|
49
|
+
const externalHTML = exporter.exportBlocks(blocks, {});
|
|
56
50
|
const externalHTMLSnapshotPath =
|
|
57
51
|
"./__snapshots__/" +
|
|
58
52
|
snapshotDirectory +
|
|
@@ -76,6 +70,14 @@ describe("Test HTML conversion", () => {
|
|
|
76
70
|
const div = document.createElement("div");
|
|
77
71
|
beforeEach(() => {
|
|
78
72
|
editor = testCase.createEditor();
|
|
73
|
+
|
|
74
|
+
// Note that we don't necessarily need to mount a root
|
|
75
|
+
// Currently, we do mount to a root so that it reflects the "production" use-case more closely.
|
|
76
|
+
|
|
77
|
+
// However, it would be nice to increased converage and share the same set of tests for these cases:
|
|
78
|
+
// - does render to a root
|
|
79
|
+
// - does not render to a root
|
|
80
|
+
// - runs in server (jsdom) environment using server-util
|
|
79
81
|
editor.mount(div);
|
|
80
82
|
});
|
|
81
83
|
|
|
@@ -175,7 +177,7 @@ describe("Test ProseMirror fragment edge case conversion", () => {
|
|
|
175
177
|
|
|
176
178
|
it("Selection within a block's children", () => {
|
|
177
179
|
// Selection starts and ends within the first block's children.
|
|
178
|
-
editor.
|
|
180
|
+
editor.dispatch(
|
|
179
181
|
editor._tiptapEditor.state.tr.setSelection(
|
|
180
182
|
TextSelection.create(editor._tiptapEditor.state.doc, 18, 80)
|
|
181
183
|
)
|
|
@@ -184,11 +186,11 @@ describe("Test ProseMirror fragment edge case conversion", () => {
|
|
|
184
186
|
const copiedFragment =
|
|
185
187
|
editor._tiptapEditor.state.selection.content().content;
|
|
186
188
|
|
|
187
|
-
const exporter = createExternalHTMLExporter(
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
const exporter = createExternalHTMLExporter(editor.pmSchema, editor);
|
|
190
|
+
const externalHTML = exporter.exportProseMirrorFragment(
|
|
191
|
+
copiedFragment,
|
|
192
|
+
{}
|
|
190
193
|
);
|
|
191
|
-
const externalHTML = exporter.exportProseMirrorFragment(copiedFragment);
|
|
192
194
|
expect(externalHTML).toMatchFileSnapshot(
|
|
193
195
|
"./__snapshots_fragment_edge_cases__/" +
|
|
194
196
|
"selectionWithinBlockChildren.html"
|
|
@@ -198,7 +200,7 @@ describe("Test ProseMirror fragment edge case conversion", () => {
|
|
|
198
200
|
it("Selection leaves a block's children", () => {
|
|
199
201
|
// Selection starts and ends within the first block's children and ends
|
|
200
202
|
// outside, at a shallower nesting level in the second block.
|
|
201
|
-
editor.
|
|
203
|
+
editor.dispatch(
|
|
202
204
|
editor._tiptapEditor.state.tr.setSelection(
|
|
203
205
|
TextSelection.create(editor._tiptapEditor.state.doc, 18, 97)
|
|
204
206
|
)
|
|
@@ -207,11 +209,11 @@ describe("Test ProseMirror fragment edge case conversion", () => {
|
|
|
207
209
|
const copiedFragment =
|
|
208
210
|
editor._tiptapEditor.state.selection.content().content;
|
|
209
211
|
|
|
210
|
-
const exporter = createExternalHTMLExporter(
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
const exporter = createExternalHTMLExporter(editor.pmSchema, editor);
|
|
213
|
+
const externalHTML = exporter.exportProseMirrorFragment(
|
|
214
|
+
copiedFragment,
|
|
215
|
+
{}
|
|
213
216
|
);
|
|
214
|
-
const externalHTML = exporter.exportProseMirrorFragment(copiedFragment);
|
|
215
217
|
expect(externalHTML).toMatchFileSnapshot(
|
|
216
218
|
"./__snapshots_fragment_edge_cases__/" +
|
|
217
219
|
"selectionLeavesBlockChildren.html"
|
|
@@ -221,7 +223,7 @@ describe("Test ProseMirror fragment edge case conversion", () => {
|
|
|
221
223
|
it("Selection spans multiple blocks' children", () => {
|
|
222
224
|
// Selection starts and ends within the first block's children and ends
|
|
223
225
|
// within the second block's children.
|
|
224
|
-
editor.
|
|
226
|
+
editor.dispatch(
|
|
225
227
|
editor._tiptapEditor.state.tr.setSelection(
|
|
226
228
|
TextSelection.create(editor._tiptapEditor.state.doc, 18, 163)
|
|
227
229
|
)
|
|
@@ -229,11 +231,11 @@ describe("Test ProseMirror fragment edge case conversion", () => {
|
|
|
229
231
|
|
|
230
232
|
const copiedFragment =
|
|
231
233
|
editor._tiptapEditor.state.selection.content().content;
|
|
232
|
-
const exporter = createExternalHTMLExporter(
|
|
233
|
-
|
|
234
|
-
|
|
234
|
+
const exporter = createExternalHTMLExporter(editor.pmSchema, editor);
|
|
235
|
+
const externalHTML = exporter.exportProseMirrorFragment(
|
|
236
|
+
copiedFragment,
|
|
237
|
+
{}
|
|
235
238
|
);
|
|
236
|
-
const externalHTML = exporter.exportProseMirrorFragment(copiedFragment);
|
|
237
239
|
expect(externalHTML).toMatchFileSnapshot(
|
|
238
240
|
"./__snapshots_fragment_edge_cases__/" +
|
|
239
241
|
"selectionSpansBlocksChildren.html"
|
|
@@ -30,8 +30,14 @@ export interface InternalHTMLSerializer<
|
|
|
30
30
|
> {
|
|
31
31
|
// TODO: Ideally we would expand the BlockNote API to support partial
|
|
32
32
|
// selections so we don't need this.
|
|
33
|
-
serializeProseMirrorFragment: (
|
|
34
|
-
|
|
33
|
+
serializeProseMirrorFragment: (
|
|
34
|
+
fragment: Fragment,
|
|
35
|
+
options: { document?: Document }
|
|
36
|
+
) => string;
|
|
37
|
+
serializeBlocks: (
|
|
38
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
39
|
+
options: { document?: Document }
|
|
40
|
+
) => string;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
export const createInternalHTMLSerializer = <
|
|
@@ -47,7 +53,10 @@ export const createInternalHTMLSerializer = <
|
|
|
47
53
|
node: Node,
|
|
48
54
|
options: { document?: Document }
|
|
49
55
|
) => HTMLElement;
|
|
50
|
-
serializeBlocks: (
|
|
56
|
+
serializeBlocks: (
|
|
57
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
58
|
+
options: { document?: Document }
|
|
59
|
+
) => string;
|
|
51
60
|
serializeProseMirrorFragment: (
|
|
52
61
|
fragment: Fragment,
|
|
53
62
|
options?: { document?: Document | undefined } | undefined,
|
|
@@ -60,16 +69,22 @@ export const createInternalHTMLSerializer = <
|
|
|
60
69
|
options: { document?: Document }
|
|
61
70
|
) => serializeNodeInner(node, options, serializer, editor, false);
|
|
62
71
|
|
|
63
|
-
serializer.serializeProseMirrorFragment = (fragment: Fragment) =>
|
|
64
|
-
serializeProseMirrorFragment(fragment, serializer);
|
|
72
|
+
serializer.serializeProseMirrorFragment = (fragment: Fragment, options) =>
|
|
73
|
+
serializeProseMirrorFragment(fragment, serializer, options);
|
|
65
74
|
|
|
66
|
-
serializer.serializeBlocks = (
|
|
75
|
+
serializer.serializeBlocks = (
|
|
76
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
77
|
+
options
|
|
78
|
+
) => {
|
|
67
79
|
const nodes = blocks.map((block) =>
|
|
68
80
|
blockToNode(block, schema, editor.schema.styleSchema)
|
|
69
81
|
);
|
|
70
82
|
const blockGroup = schema.nodes["blockGroup"].create(null, nodes);
|
|
71
83
|
|
|
72
|
-
return serializer.serializeProseMirrorFragment(
|
|
84
|
+
return serializer.serializeProseMirrorFragment(
|
|
85
|
+
Fragment.from(blockGroup),
|
|
86
|
+
options
|
|
87
|
+
);
|
|
73
88
|
};
|
|
74
89
|
|
|
75
90
|
return serializer;
|
|
@@ -119,9 +119,10 @@ export const serializeNodeInner = <
|
|
|
119
119
|
// returns a string instead, to make it easier to use.
|
|
120
120
|
export const serializeProseMirrorFragment = (
|
|
121
121
|
fragment: Fragment,
|
|
122
|
-
serializer: DOMSerializer
|
|
122
|
+
serializer: DOMSerializer,
|
|
123
|
+
options?: { document?: Document }
|
|
123
124
|
) => {
|
|
124
|
-
const internalHTML = serializer.serializeFragment(fragment);
|
|
125
|
+
const internalHTML = serializer.serializeFragment(fragment, options);
|
|
125
126
|
const parent = document.createElement("div");
|
|
126
127
|
parent.appendChild(internalHTML);
|
|
127
128
|
|
|
@@ -4,7 +4,7 @@ import rehypeRemark from "rehype-remark";
|
|
|
4
4
|
import remarkGfm from "remark-gfm";
|
|
5
5
|
import remarkStringify from "remark-stringify";
|
|
6
6
|
import { unified } from "unified";
|
|
7
|
-
import {
|
|
7
|
+
import { PartialBlock } from "../../../blocks/defaultBlocks";
|
|
8
8
|
import type { BlockNoteEditor } from "../../../editor/BlockNoteEditor";
|
|
9
9
|
import { BlockSchema, InlineContentSchema, StyleSchema } from "../../../schema";
|
|
10
10
|
import { createExternalHTMLExporter } from "../html/externalHTMLExporter";
|
|
@@ -29,12 +29,13 @@ export function blocksToMarkdown<
|
|
|
29
29
|
I extends InlineContentSchema,
|
|
30
30
|
S extends StyleSchema
|
|
31
31
|
>(
|
|
32
|
-
blocks:
|
|
32
|
+
blocks: PartialBlock<BSchema, I, S>[],
|
|
33
33
|
schema: Schema,
|
|
34
|
-
editor: BlockNoteEditor<BSchema, I, S
|
|
34
|
+
editor: BlockNoteEditor<BSchema, I, S>,
|
|
35
|
+
options: { document?: Document }
|
|
35
36
|
): string {
|
|
36
37
|
const exporter = createExternalHTMLExporter(schema, editor);
|
|
37
|
-
const externalHTML = exporter.exportBlocks(blocks);
|
|
38
|
+
const externalHTML = exporter.exportBlocks(blocks, options);
|
|
38
39
|
|
|
39
40
|
return cleanHTMLToMarkdown(externalHTML);
|
|
40
41
|
}
|
|
@@ -3,10 +3,10 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
|
3
3
|
import { BlockNoteEditor } from "../../editor/BlockNoteEditor";
|
|
4
4
|
|
|
5
5
|
import { PartialBlock } from "../../blocks/defaultBlocks";
|
|
6
|
+
import { customBlocksTestCases } from "../testUtil/cases/customBlocks";
|
|
6
7
|
import { customInlineContentTestCases } from "../testUtil/cases/customInlineContent";
|
|
7
8
|
import { customStylesTestCases } from "../testUtil/cases/customStyles";
|
|
8
9
|
import { defaultSchemaTestCases } from "../testUtil/cases/defaultSchema";
|
|
9
|
-
import { customBlocksTestCases } from "../testUtil/cases/customBlocks";
|
|
10
10
|
import {
|
|
11
11
|
addIdsToBlock,
|
|
12
12
|
partialBlockToBlockForTesting,
|
|
@@ -18,11 +18,7 @@ function validateConversion(
|
|
|
18
18
|
editor: BlockNoteEditor<any, any, any>
|
|
19
19
|
) {
|
|
20
20
|
addIdsToBlock(block);
|
|
21
|
-
const node = blockToNode(
|
|
22
|
-
block,
|
|
23
|
-
editor._tiptapEditor.schema,
|
|
24
|
-
editor.schema.styleSchema
|
|
25
|
-
);
|
|
21
|
+
const node = blockToNode(block, editor.pmSchema, editor.schema.styleSchema);
|
|
26
22
|
|
|
27
23
|
expect(node).toMatchSnapshot();
|
|
28
24
|
|
|
@@ -56,6 +52,13 @@ describe("Test BlockNote-Prosemirror conversion", () => {
|
|
|
56
52
|
|
|
57
53
|
beforeEach(() => {
|
|
58
54
|
editor = testCase.createEditor();
|
|
55
|
+
// Note that we don't necessarily need to mount a root
|
|
56
|
+
// Currently, we do mount to a root so that it reflects the "production" use-case more closely.
|
|
57
|
+
|
|
58
|
+
// However, it would be nice to increased converage and share the same set of tests for these cases:
|
|
59
|
+
// - does render to a root
|
|
60
|
+
// - does not render to a root
|
|
61
|
+
// - runs in server (jsdom) environment using server-util
|
|
59
62
|
editor.mount(div);
|
|
60
63
|
});
|
|
61
64
|
|