@blocknote/core 0.10.0 → 0.11.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/README.md +1 -1
- package/dist/blocknote.js +1536 -1458
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -6
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +5 -3
- package/src/api/blockManipulation/blockManipulation.ts +144 -30
- package/src/api/exporters/copyExtension.ts +97 -24
- package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -1
- package/src/api/exporters/html/__snapshots__/image/button/internal.html +1 -1
- package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -1
- package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -1
- package/src/api/exporters/html/__snapshots__/simpleImage/basic/internal.html +1 -1
- package/src/api/exporters/html/__snapshots__/simpleImage/button/external.html +1 -1
- package/src/api/exporters/html/__snapshots__/simpleImage/button/internal.html +1 -1
- package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -1
- package/src/api/exporters/html/__snapshots__/simpleImage/nested/internal.html +1 -1
- package/src/api/exporters/html/util/sharedHTMLConversion.ts +1 -0
- package/src/api/exporters/markdown/__snapshots__/simpleImage/button/markdown.md +0 -1
- package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +9 -0
- package/src/api/parsers/pasteExtension.ts +0 -1
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +19 -19
- package/src/editor/Block.css +19 -14
- package/src/editor/BlockNoteEditor.ts +11 -12
- package/src/editor/editor.css +1 -0
- package/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.ts +12 -1
- package/src/extensions/SideMenu/SideMenuPlugin.ts +2 -2
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +3 -1
- package/src/pm-nodes/BlockContainer.ts +1 -1
- package/types/src/api/blockManipulation/blockManipulation.d.ts +8 -6
- package/types/src/editor/BlockNoteEditor.d.ts +9 -7
- package/types/src/BlockNoteEditor.d.ts +0 -300
- package/types/src/BlockNoteEditor.test.d.ts +0 -1
- package/types/src/BlockNoteExtensions.d.ts +0 -26
- package/types/src/api/nodeConversions/testUtil.d.ts +0 -7
- package/types/src/api/testCases/cases/customBlocks.d.ts +0 -345
- package/types/src/api/testCases/cases/customInlineContent.d.ts +0 -29
- package/types/src/api/testCases/cases/customStyles.d.ts +0 -64
- package/types/src/api/testCases/cases/defaultSchema.d.ts +0 -3
- package/types/src/api/testCases/index.d.ts +0 -12
- package/types/src/api/util/nodeUtil.d.ts +0 -8
- package/types/src/extensions/Blocks/NonEditableBlockPlugin.d.ts +0 -2
- package/types/src/extensions/Blocks/PreviousBlockTypePlugin.d.ts +0 -14
- package/types/src/extensions/Blocks/api/blocks/createSpec.d.ts +0 -35
- package/types/src/extensions/Blocks/api/blocks/internal.d.ts +0 -45
- package/types/src/extensions/Blocks/api/blocks/types.d.ts +0 -114
- package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +0 -8
- package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +0 -577
- package/types/src/extensions/Blocks/api/defaultProps.d.ts +0 -15
- package/types/src/extensions/Blocks/api/inlineContent/createSpec.d.ts +0 -21
- package/types/src/extensions/Blocks/api/inlineContent/internal.d.ts +0 -25
- package/types/src/extensions/Blocks/api/inlineContent/types.d.ts +0 -62
- package/types/src/extensions/Blocks/api/selectionTypes.d.ts +0 -6
- package/types/src/extensions/Blocks/api/styles/createSpec.d.ts +0 -13
- package/types/src/extensions/Blocks/api/styles/internal.d.ts +0 -22
- package/types/src/extensions/Blocks/api/styles/types.d.ts +0 -21
- package/types/src/extensions/Blocks/helpers/findBlock.d.ts +0 -6
- package/types/src/extensions/Blocks/helpers/getBlockInfoFromPos.d.ts +0 -27
- package/types/src/extensions/Blocks/index.d.ts +0 -4
- package/types/src/extensions/Blocks/nodes/BlockAttributes.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +0 -30
- package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +0 -58
- package/types/src/extensions/Blocks/nodes/BlockContent/ImageBlockContent/ImageBlockContent.d.ts +0 -95
- package/types/src/extensions/Blocks/nodes/BlockContent/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -1
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -46
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/ListItemKeyboardShortcuts.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -46
- package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -52
- package/types/src/extensions/Blocks/nodes/BlockContent/TableBlockContent/TableBlockContent.d.ts +0 -53
- package/types/src/extensions/Blocks/nodes/BlockContent/TableBlockContent/TableExtension.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/defaultBlockHelpers.d.ts +0 -12
- package/types/src/extensions/Blocks/nodes/BlockGroup.d.ts +0 -10
- package/types/src/shared/BaseUiElementTypes.d.ts +0 -7
- package/types/src/shared/EditorElement.d.ts +0 -0
- package/types/src/shared/EventEmitter.d.ts +0 -11
- package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +0 -3
- package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +0 -37
- package/types/src/shared/utils.d.ts +0 -6
package/dist/webpack-stats.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"builtAt":
|
|
1
|
+
{"builtAt":1704762819220,"assets":[{"name":"blocknote.umd.cjs","size":100567},{"name":"blocknote.umd.cjs.map","size":453755}],"chunks":[{"id":"a1ee98a","entry":true,"initial":true,"files":["blocknote.umd.cjs"],"names":["index"]}],"modules":[{"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":108,"chunks":["a1ee98a"]},{"name":"./src/api/nodeConversions/nodeConversions.ts","size":11959,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/sharedHTMLConversion.ts","size":2272,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts","size":2687,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/externalHTMLExporter.ts","size":1059,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/html/internalHTMLSerializer.ts","size":697,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts","size":316,"chunks":["a1ee98a"]},{"name":"./src/util/browser.ts","size":432,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlockHelpers.ts","size":1724,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultProps.ts","size":269,"chunks":["a1ee98a"]},{"name":"./src/util/string.ts","size":108,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/internal.ts","size":3701,"chunks":["a1ee98a"]},{"name":"./src/schema/blocks/createSpec.ts","size":2781,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/internal.ts","size":1357,"chunks":["a1ee98a"]},{"name":"./src/schema/inlineContent/createSpec.ts","size":1613,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/internal.ts","size":1162,"chunks":["a1ee98a"]},{"name":"./src/schema/styles/createSpec.ts","size":1263,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorMark.ts","size":946,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorMark.ts","size":866,"chunks":["a1ee98a"]},{"name":"./src/blocks/HeadingBlockContent/HeadingBlockContent.ts","size":2796,"chunks":["a1ee98a"]},{"name":"./src/util/EventEmitter.ts","size":744,"chunks":["a1ee98a"]},{"name":"./src/extensions/ImageToolbar/ImageToolbarPlugin.ts","size":3772,"chunks":["a1ee98a"]},{"name":"./src/blocks/ImageBlockContent/ImageBlockContent.ts","size":9011,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts","size":1106,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts","size":2691,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts","size":1862,"chunks":["a1ee98a"]},{"name":"./src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts","size":3148,"chunks":["a1ee98a"]},{"name":"./src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts","size":753,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableExtension.ts","size":1462,"chunks":["a1ee98a"]},{"name":"./src/blocks/TableBlockContent/TableBlockContent.ts","size":1207,"chunks":["a1ee98a"]},{"name":"./src/blocks/defaultBlocks.ts","size":1025,"chunks":["a1ee98a"]},{"name":"./src/api/nodeUtil.ts","size":548,"chunks":["a1ee98a"]},{"name":"./src/api/blockManipulation/blockManipulation.ts","size":4471,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/removeUnderlinesRehypePlugin.ts","size":752,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/markdown/markdownExporter.ts","size":549,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/html/util/nestedLists.ts","size":2022,"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/extensions/FormattingToolbar/FormattingToolbarPlugin.ts","size":4866,"chunks":["a1ee98a"]},{"name":"./src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts","size":7599,"chunks":["a1ee98a"]},{"name":"./src/extensions-shared/suggestion/SuggestionPlugin.ts","size":9492,"chunks":["a1ee98a"]},{"name":"./src/extensions/SlashMenu/SlashMenuPlugin.ts","size":839,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/MultipleNodeSelection.ts","size":1616,"chunks":["a1ee98a"]},{"name":"./src/extensions/SideMenu/SideMenuPlugin.ts","size":15178,"chunks":["a1ee98a"]},{"name":"./src/extensions/SlashMenu/defaultSlashMenuItems.ts","size":4114,"chunks":["a1ee98a"]},{"name":"./src/extensions/TableHandles/TableHandlesPlugin.ts","size":14723,"chunks":["a1ee98a"]},{"name":"./src/api/exporters/copyExtension.ts","size":2883,"chunks":["a1ee98a"]},{"name":"./src/api/parsers/pasteExtension.ts","size":1131,"chunks":["a1ee98a"]},{"name":"./src/extensions/BackgroundColor/BackgroundColorExtension.ts","size":688,"chunks":["a1ee98a"]},{"name":"./src/extensions/Placeholder/PlaceholderExtension.ts","size":2106,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextAlignment/TextAlignmentExtension.ts","size":748,"chunks":["a1ee98a"]},{"name":"./src/extensions/TextColor/TextColorExtension.ts","size":622,"chunks":["a1ee98a"]},{"name":"./src/extensions/TrailingNode/TrailingNodeExtension.ts","size":1594,"chunks":["a1ee98a"]},{"name":"./src/extensions/NonEditableBlocks/NonEditableBlockPlugin.ts","size":467,"chunks":["a1ee98a"]},{"name":"./src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts","size":4572,"chunks":["a1ee98a"]},{"name":"./src/pm-nodes/BlockContainer.ts","size":17340,"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":3467,"chunks":["a1ee98a"]},{"name":"./src/editor/transformPasted.ts","size":1017,"chunks":["a1ee98a"]},{"name":"./src/editor/Block.css","size":17,"chunks":["a1ee98a"]},{"name":"./src/editor/editor.css","size":18,"chunks":["a1ee98a"]},{"name":"./src/editor/BlockNoteEditor.ts","size":22030,"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.11.0",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
9
|
"types",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"preview": "vite preview",
|
|
47
47
|
"lint": "eslint src --max-warnings 0",
|
|
48
48
|
"test": "vitest --run",
|
|
49
|
-
"test-watch": "vitest watch"
|
|
49
|
+
"test-watch": "vitest watch",
|
|
50
|
+
"clean": "rimraf dist && rimraf types"
|
|
50
51
|
},
|
|
51
52
|
"dependencies": {
|
|
52
53
|
"@emotion/cache": "^11.10.5",
|
|
@@ -98,6 +99,7 @@
|
|
|
98
99
|
"eslint": "^8.10.0",
|
|
99
100
|
"jsdom": "^21.1.0",
|
|
100
101
|
"prettier": "^2.7.1",
|
|
102
|
+
"rimraf": "^5.0.5",
|
|
101
103
|
"rollup-plugin-webpack-stats": "^0.2.2",
|
|
102
104
|
"typescript": "^5.0.4",
|
|
103
105
|
"vite": "^4.4.8",
|
|
@@ -113,5 +115,5 @@
|
|
|
113
115
|
"access": "public",
|
|
114
116
|
"registry": "https://registry.npmjs.org/"
|
|
115
117
|
},
|
|
116
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "db565110840b367d5e5220fdc790c5e7b476ff5b"
|
|
117
119
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { Editor } from "@tiptap/core";
|
|
2
1
|
import { Node } from "prosemirror-model";
|
|
3
2
|
|
|
4
3
|
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
|
|
5
4
|
import {
|
|
5
|
+
Block,
|
|
6
6
|
BlockIdentifier,
|
|
7
7
|
BlockSchema,
|
|
8
8
|
InlineContentSchema,
|
|
9
9
|
PartialBlock,
|
|
10
10
|
StyleSchema,
|
|
11
11
|
} from "../../schema";
|
|
12
|
-
import { blockToNode } from "../nodeConversions/nodeConversions";
|
|
12
|
+
import { blockToNode, nodeToBlock } from "../nodeConversions/nodeConversions";
|
|
13
13
|
import { getNodeById } from "../nodeUtil";
|
|
14
|
+
import { Transaction } from "prosemirror-state";
|
|
14
15
|
|
|
15
16
|
export function insertBlocks<
|
|
16
17
|
BSchema extends BlockSchema,
|
|
@@ -21,7 +22,7 @@ export function insertBlocks<
|
|
|
21
22
|
referenceBlock: BlockIdentifier,
|
|
22
23
|
placement: "before" | "after" | "nested" = "before",
|
|
23
24
|
editor: BlockNoteEditor<BSchema, I, S>
|
|
24
|
-
):
|
|
25
|
+
): Block<BSchema, I, S>[] {
|
|
25
26
|
const ttEditor = editor._tiptapEditor;
|
|
26
27
|
|
|
27
28
|
const id =
|
|
@@ -34,39 +35,53 @@ export function insertBlocks<
|
|
|
34
35
|
);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
let insertionPos = -1;
|
|
38
|
-
|
|
39
38
|
const { node, posBeforeNode } = getNodeById(id, ttEditor.state.doc);
|
|
40
39
|
|
|
41
40
|
if (placement === "before") {
|
|
42
|
-
|
|
41
|
+
ttEditor.view.dispatch(
|
|
42
|
+
ttEditor.state.tr.insert(posBeforeNode, nodesToInsert)
|
|
43
|
+
);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
if (placement === "after") {
|
|
46
|
-
|
|
47
|
+
ttEditor.view.dispatch(
|
|
48
|
+
ttEditor.state.tr.insert(posBeforeNode + node.nodeSize, nodesToInsert)
|
|
49
|
+
);
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
if (placement === "nested") {
|
|
50
53
|
// Case if block doesn't already have children.
|
|
51
54
|
if (node.childCount < 2) {
|
|
52
|
-
insertionPos = posBeforeNode + node.firstChild!.nodeSize + 1;
|
|
53
|
-
|
|
54
55
|
const blockGroupNode = ttEditor.state.schema.nodes["blockGroup"].create(
|
|
55
56
|
{},
|
|
56
57
|
nodesToInsert
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
ttEditor.view.dispatch(
|
|
60
|
-
ttEditor.state.tr.insert(
|
|
61
|
+
ttEditor.state.tr.insert(
|
|
62
|
+
posBeforeNode + node.firstChild!.nodeSize + 1,
|
|
63
|
+
blockGroupNode
|
|
64
|
+
)
|
|
61
65
|
);
|
|
62
|
-
|
|
63
|
-
return;
|
|
64
66
|
}
|
|
67
|
+
}
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
// Now that the `PartialBlock`s have been converted to nodes, we can
|
|
70
|
+
// re-convert them into full `Block`s.
|
|
71
|
+
const insertedBlocks: Block<BSchema, I, S>[] = [];
|
|
72
|
+
for (const node of nodesToInsert) {
|
|
73
|
+
insertedBlocks.push(
|
|
74
|
+
nodeToBlock(
|
|
75
|
+
node,
|
|
76
|
+
editor.blockSchema,
|
|
77
|
+
editor.inlineContentSchema,
|
|
78
|
+
editor.styleSchema,
|
|
79
|
+
editor.blockCache
|
|
80
|
+
)
|
|
81
|
+
);
|
|
67
82
|
}
|
|
68
83
|
|
|
69
|
-
|
|
84
|
+
return insertedBlocks;
|
|
70
85
|
}
|
|
71
86
|
|
|
72
87
|
export function updateBlock<
|
|
@@ -76,28 +91,56 @@ export function updateBlock<
|
|
|
76
91
|
>(
|
|
77
92
|
blockToUpdate: BlockIdentifier,
|
|
78
93
|
update: PartialBlock<BSchema, I, S>,
|
|
79
|
-
editor:
|
|
80
|
-
) {
|
|
94
|
+
editor: BlockNoteEditor<BSchema, I, S>
|
|
95
|
+
): Block<BSchema, I, S> {
|
|
96
|
+
const ttEditor = editor._tiptapEditor;
|
|
97
|
+
|
|
81
98
|
const id =
|
|
82
99
|
typeof blockToUpdate === "string" ? blockToUpdate : blockToUpdate.id;
|
|
83
|
-
const { posBeforeNode } = getNodeById(id,
|
|
100
|
+
const { posBeforeNode } = getNodeById(id, ttEditor.state.doc);
|
|
101
|
+
|
|
102
|
+
ttEditor.commands.BNUpdateBlock(posBeforeNode + 1, update);
|
|
103
|
+
|
|
104
|
+
const blockContainerNode = ttEditor.state.doc
|
|
105
|
+
.resolve(posBeforeNode + 1)
|
|
106
|
+
.node();
|
|
84
107
|
|
|
85
|
-
|
|
108
|
+
return nodeToBlock(
|
|
109
|
+
blockContainerNode,
|
|
110
|
+
editor.blockSchema,
|
|
111
|
+
editor.inlineContentSchema,
|
|
112
|
+
editor.styleSchema,
|
|
113
|
+
editor.blockCache
|
|
114
|
+
);
|
|
86
115
|
}
|
|
87
116
|
|
|
88
|
-
|
|
117
|
+
function removeBlocksWithCallback<
|
|
118
|
+
BSchema extends BlockSchema,
|
|
119
|
+
I extends InlineContentSchema,
|
|
120
|
+
S extends StyleSchema
|
|
121
|
+
>(
|
|
89
122
|
blocksToRemove: BlockIdentifier[],
|
|
90
|
-
editor:
|
|
91
|
-
|
|
123
|
+
editor: BlockNoteEditor<BSchema, I, S>,
|
|
124
|
+
// Should return new removedSize.
|
|
125
|
+
callback?: (
|
|
126
|
+
node: Node,
|
|
127
|
+
pos: number,
|
|
128
|
+
tr: Transaction,
|
|
129
|
+
removedSize: number
|
|
130
|
+
) => number
|
|
131
|
+
): Block<BSchema, I, S>[] {
|
|
132
|
+
const ttEditor = editor._tiptapEditor;
|
|
133
|
+
const tr = ttEditor.state.tr;
|
|
134
|
+
|
|
92
135
|
const idsOfBlocksToRemove = new Set<string>(
|
|
93
136
|
blocksToRemove.map((block) =>
|
|
94
137
|
typeof block === "string" ? block : block.id
|
|
95
138
|
)
|
|
96
139
|
);
|
|
97
|
-
|
|
140
|
+
const removedBlocks: Block<BSchema, I, S>[] = [];
|
|
98
141
|
let removedSize = 0;
|
|
99
142
|
|
|
100
|
-
|
|
143
|
+
ttEditor.state.doc.descendants((node, pos) => {
|
|
101
144
|
// Skips traversing nodes after all target blocks have been removed.
|
|
102
145
|
if (idsOfBlocksToRemove.size === 0) {
|
|
103
146
|
return false;
|
|
@@ -111,17 +154,29 @@ export function removeBlocks(
|
|
|
111
154
|
return true;
|
|
112
155
|
}
|
|
113
156
|
|
|
157
|
+
// Saves the block that is being deleted.
|
|
158
|
+
removedBlocks.push(
|
|
159
|
+
nodeToBlock(
|
|
160
|
+
node,
|
|
161
|
+
editor.blockSchema,
|
|
162
|
+
editor.inlineContentSchema,
|
|
163
|
+
editor.styleSchema,
|
|
164
|
+
editor.blockCache
|
|
165
|
+
)
|
|
166
|
+
);
|
|
114
167
|
idsOfBlocksToRemove.delete(node.attrs.id);
|
|
115
|
-
const oldDocSize = editor.state.doc.nodeSize;
|
|
116
168
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
169
|
+
// Removes the block and calculates the change in document size.
|
|
170
|
+
removedSize = callback?.(node, pos, tr, removedSize) || removedSize;
|
|
171
|
+
const oldDocSize = tr.doc.nodeSize;
|
|
172
|
+
tr.delete(pos - removedSize - 1, pos - removedSize + node.nodeSize + 1);
|
|
173
|
+
const newDocSize = tr.doc.nodeSize;
|
|
120
174
|
removedSize += oldDocSize - newDocSize;
|
|
121
175
|
|
|
122
176
|
return false;
|
|
123
177
|
});
|
|
124
178
|
|
|
179
|
+
// Throws an error if now all blocks could be found.
|
|
125
180
|
if (idsOfBlocksToRemove.size > 0) {
|
|
126
181
|
const notFoundIds = [...idsOfBlocksToRemove].join("\n");
|
|
127
182
|
|
|
@@ -130,6 +185,21 @@ export function removeBlocks(
|
|
|
130
185
|
notFoundIds
|
|
131
186
|
);
|
|
132
187
|
}
|
|
188
|
+
|
|
189
|
+
ttEditor.view.dispatch(tr);
|
|
190
|
+
|
|
191
|
+
return removedBlocks;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function removeBlocks<
|
|
195
|
+
BSchema extends BlockSchema,
|
|
196
|
+
I extends InlineContentSchema,
|
|
197
|
+
S extends StyleSchema
|
|
198
|
+
>(
|
|
199
|
+
blocksToRemove: BlockIdentifier[],
|
|
200
|
+
editor: BlockNoteEditor<BSchema, I, S>
|
|
201
|
+
): Block<BSchema, I, S>[] {
|
|
202
|
+
return removeBlocksWithCallback(blocksToRemove, editor);
|
|
133
203
|
}
|
|
134
204
|
|
|
135
205
|
export function replaceBlocks<
|
|
@@ -140,7 +210,51 @@ export function replaceBlocks<
|
|
|
140
210
|
blocksToRemove: BlockIdentifier[],
|
|
141
211
|
blocksToInsert: PartialBlock<BSchema, I, S>[],
|
|
142
212
|
editor: BlockNoteEditor<BSchema, I, S>
|
|
143
|
-
) {
|
|
144
|
-
|
|
145
|
-
|
|
213
|
+
): {
|
|
214
|
+
insertedBlocks: Block<BSchema, I, S>[];
|
|
215
|
+
removedBlocks: Block<BSchema, I, S>[];
|
|
216
|
+
} {
|
|
217
|
+
const ttEditor = editor._tiptapEditor;
|
|
218
|
+
|
|
219
|
+
const nodesToInsert: Node[] = [];
|
|
220
|
+
for (const block of blocksToInsert) {
|
|
221
|
+
nodesToInsert.push(blockToNode(block, ttEditor.schema, editor.styleSchema));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const idOfFirstBlock =
|
|
225
|
+
typeof blocksToRemove[0] === "string"
|
|
226
|
+
? blocksToRemove[0]
|
|
227
|
+
: blocksToRemove[0].id;
|
|
228
|
+
const removedBlocks = removeBlocksWithCallback(
|
|
229
|
+
blocksToRemove,
|
|
230
|
+
editor,
|
|
231
|
+
(node, pos, tr, removedSize) => {
|
|
232
|
+
if (node.attrs.id === idOfFirstBlock) {
|
|
233
|
+
const oldDocSize = tr.doc.nodeSize;
|
|
234
|
+
tr.insert(pos, nodesToInsert);
|
|
235
|
+
const newDocSize = tr.doc.nodeSize;
|
|
236
|
+
|
|
237
|
+
return removedSize + oldDocSize - newDocSize;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return removedSize;
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
// Now that the `PartialBlock`s have been converted to nodes, we can
|
|
245
|
+
// re-convert them into full `Block`s.
|
|
246
|
+
const insertedBlocks: Block<BSchema, I, S>[] = [];
|
|
247
|
+
for (const node of nodesToInsert) {
|
|
248
|
+
insertedBlocks.push(
|
|
249
|
+
nodeToBlock(
|
|
250
|
+
node,
|
|
251
|
+
editor.blockSchema,
|
|
252
|
+
editor.inlineContentSchema,
|
|
253
|
+
editor.styleSchema,
|
|
254
|
+
editor.blockCache
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return { insertedBlocks, removedBlocks };
|
|
146
260
|
}
|
|
@@ -1,11 +1,46 @@
|
|
|
1
1
|
import { Extension } from "@tiptap/core";
|
|
2
|
-
import { Plugin } from "prosemirror-state";
|
|
2
|
+
import { NodeSelection, Plugin } from "prosemirror-state";
|
|
3
|
+
import { Node } from "prosemirror-model";
|
|
3
4
|
|
|
4
5
|
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
|
|
5
6
|
import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
|
|
6
7
|
import { createExternalHTMLExporter } from "./html/externalHTMLExporter";
|
|
7
8
|
import { createInternalHTMLSerializer } from "./html/internalHTMLSerializer";
|
|
8
9
|
import { cleanHTMLToMarkdown } from "./markdown/markdownExporter";
|
|
10
|
+
import { EditorView } from "prosemirror-view";
|
|
11
|
+
|
|
12
|
+
function selectedFragmentToHTML<
|
|
13
|
+
BSchema extends BlockSchema,
|
|
14
|
+
I extends InlineContentSchema,
|
|
15
|
+
S extends StyleSchema
|
|
16
|
+
>(
|
|
17
|
+
view: EditorView,
|
|
18
|
+
editor: BlockNoteEditor<BSchema, I, S>
|
|
19
|
+
): {
|
|
20
|
+
internalHTML: string;
|
|
21
|
+
externalHTML: string;
|
|
22
|
+
plainText: string;
|
|
23
|
+
} {
|
|
24
|
+
const selectedFragment = view.state.selection.content().content;
|
|
25
|
+
|
|
26
|
+
const internalHTMLSerializer = createInternalHTMLSerializer(
|
|
27
|
+
view.state.schema,
|
|
28
|
+
editor
|
|
29
|
+
);
|
|
30
|
+
const internalHTML =
|
|
31
|
+
internalHTMLSerializer.serializeProseMirrorFragment(selectedFragment);
|
|
32
|
+
|
|
33
|
+
const externalHTMLExporter = createExternalHTMLExporter(
|
|
34
|
+
view.state.schema,
|
|
35
|
+
editor
|
|
36
|
+
);
|
|
37
|
+
const externalHTML =
|
|
38
|
+
externalHTMLExporter.exportProseMirrorFragment(selectedFragment);
|
|
39
|
+
|
|
40
|
+
const plainText = cleanHTMLToMarkdown(externalHTML);
|
|
41
|
+
|
|
42
|
+
return { internalHTML, externalHTML, plainText };
|
|
43
|
+
}
|
|
9
44
|
|
|
10
45
|
export const createCopyToClipboardExtension = <
|
|
11
46
|
BSchema extends BlockSchema,
|
|
@@ -17,39 +52,35 @@ export const createCopyToClipboardExtension = <
|
|
|
17
52
|
Extension.create<{ editor: BlockNoteEditor<BSchema, I, S> }, undefined>({
|
|
18
53
|
name: "copyToClipboard",
|
|
19
54
|
addProseMirrorPlugins() {
|
|
20
|
-
const tiptap = this.editor;
|
|
21
|
-
const schema = this.editor.schema;
|
|
22
55
|
return [
|
|
23
56
|
new Plugin({
|
|
24
57
|
props: {
|
|
25
58
|
handleDOMEvents: {
|
|
26
|
-
copy(
|
|
59
|
+
copy(view, event) {
|
|
27
60
|
// Stops the default browser copy behaviour.
|
|
28
61
|
event.preventDefault();
|
|
29
62
|
event.clipboardData!.clearData();
|
|
30
63
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
47
|
-
const externalHTML =
|
|
48
|
-
externalHTMLExporter.exportProseMirrorFragment(
|
|
49
|
-
selectedFragment
|
|
64
|
+
// Checks if a `blockContent` node is being copied and expands
|
|
65
|
+
// the selection to the parent `blockContainer` node. This is
|
|
66
|
+
// for the use-case in which only a block without content is
|
|
67
|
+
// selected, e.g. an image block.
|
|
68
|
+
if (
|
|
69
|
+
"node" in view.state.selection &&
|
|
70
|
+
(view.state.selection.node as Node).type.spec.group ===
|
|
71
|
+
"blockContent"
|
|
72
|
+
) {
|
|
73
|
+
view.dispatch(
|
|
74
|
+
view.state.tr.setSelection(
|
|
75
|
+
new NodeSelection(
|
|
76
|
+
view.state.doc.resolve(view.state.selection.from - 1)
|
|
77
|
+
)
|
|
78
|
+
)
|
|
50
79
|
);
|
|
80
|
+
}
|
|
51
81
|
|
|
52
|
-
const plainText =
|
|
82
|
+
const { internalHTML, externalHTML, plainText } =
|
|
83
|
+
selectedFragmentToHTML(view, editor);
|
|
53
84
|
|
|
54
85
|
// TODO: Writing to other MIME types not working in Safari for
|
|
55
86
|
// some reason.
|
|
@@ -57,6 +88,48 @@ export const createCopyToClipboardExtension = <
|
|
|
57
88
|
event.clipboardData!.setData("text/html", externalHTML);
|
|
58
89
|
event.clipboardData!.setData("text/plain", plainText);
|
|
59
90
|
|
|
91
|
+
// Prevent default PM handler to be called
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
// This is for the use-case in which only a block without content
|
|
95
|
+
// is selected, e.g. an image block, and dragged (not using the
|
|
96
|
+
// drag handle).
|
|
97
|
+
dragstart(view, event) {
|
|
98
|
+
// Checks if a `NodeSelection` is active.
|
|
99
|
+
if (!("node" in view.state.selection)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Checks if a `blockContent` node is being dragged.
|
|
104
|
+
if (
|
|
105
|
+
(view.state.selection.node as Node).type.spec.group !==
|
|
106
|
+
"blockContent"
|
|
107
|
+
) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Expands the selection to the parent `blockContainer` node.
|
|
112
|
+
view.dispatch(
|
|
113
|
+
view.state.tr.setSelection(
|
|
114
|
+
new NodeSelection(
|
|
115
|
+
view.state.doc.resolve(view.state.selection.from - 1)
|
|
116
|
+
)
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Stops the default browser drag start behaviour.
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
event.dataTransfer!.clearData();
|
|
123
|
+
|
|
124
|
+
const { internalHTML, externalHTML, plainText } =
|
|
125
|
+
selectedFragmentToHTML(view, editor);
|
|
126
|
+
|
|
127
|
+
// TODO: Writing to other MIME types not working in Safari for
|
|
128
|
+
// some reason.
|
|
129
|
+
event.dataTransfer!.setData("blocknote/html", internalHTML);
|
|
130
|
+
event.dataTransfer!.setData("text/html", externalHTML);
|
|
131
|
+
event.dataTransfer!.setData("text/plain", plainText);
|
|
132
|
+
|
|
60
133
|
// Prevent default PM handler to be called
|
|
61
134
|
return true;
|
|
62
135
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-
|
|
1
|
+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div></div></div></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-add-image-button"><div class="bn-add-image-button-icon"></div><p class="bn-add-image-button-text"></p></div
|
|
1
|
+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-add-image-button"><div class="bn-add-image-button-icon"></div><p class="bn-add-image-button-text"></p></div></div></div></div></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-
|
|
1
|
+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div></div><div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="2"><div class="bn-block" data-node-type="blockContainer" data-id="2"><div class="bn-block-content" data-content-type="image" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div></div></div></div></div></div></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-
|
|
1
|
+
<div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="simpleImage" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-
|
|
1
|
+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="simpleImage" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div></div></div></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-add-image-button"><div class="bn-add-image-button-icon"></div><p class="bn-add-image-button-text"></p></div
|
|
1
|
+
<div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-add-image-button"><div class="bn-add-image-button-icon"></div><p class="bn-add-image-button-text"></p></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="simpleImage"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-add-image-button"><div class="bn-add-image-button-icon"></div><p class="bn-add-image-button-text"></p></div
|
|
1
|
+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="simpleImage"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-add-image-button"><div class="bn-add-image-button-icon"></div><p class="bn-add-image-button-text"></p></div></div></div></div></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-
|
|
1
|
+
<div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="simpleImage" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-
|
|
1
|
+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="simpleImage" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div></div><div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="2"><div class="bn-block" data-node-type="blockContainer" data-id="2"><div class="bn-block-content" data-content-type="simpleImage" data-url="exampleURL" data-caption="Caption" data-width="256"><div class="bn-image-block-content-wrapper" style="align-items: flex-start;"><div class="bn-image-and-caption-wrapper"><div class="bn-image-wrapper"><img class="bn-image" src="exampleURL" alt="placeholder" draggable="false" style="width: 0px;"></div><p class="bn-image-caption" style="padding: 4px;"></p></div></div></div></div></div></div></div></div></div>
|
|
@@ -32,6 +32,7 @@ export const serializeNodeInner = <
|
|
|
32
32
|
if (!serializer.nodes[node.type.name]) {
|
|
33
33
|
throw new Error("Serializer is missing a node type: " + node.type.name);
|
|
34
34
|
}
|
|
35
|
+
|
|
35
36
|
const { dom, contentDOM } = DOMSerializer.renderSpec(
|
|
36
37
|
doc(options),
|
|
37
38
|
serializer.nodes[node.type.name](node)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
![placeholder]()
|