Skip to content

Commit 295c7ba

Browse files
fix: Bug in replaceBlocks (#487)
* Improved code for `replaceBlocks` * Cleaned up code * Fixed test failure
1 parent 375b03b commit 295c7ba

File tree

1 file changed

+55
-8
lines changed

1 file changed

+55
-8
lines changed

packages/core/src/api/blockManipulation/blockManipulation.ts

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from "../../schema";
1212
import { blockToNode } from "../nodeConversions/nodeConversions";
1313
import { getNodeById } from "../nodeUtil";
14+
import { Transaction } from "prosemirror-state";
1415

1516
export function insertBlocks<
1617
BSchema extends BlockSchema,
@@ -85,10 +86,19 @@ export function updateBlock<
8586
editor.commands.BNUpdateBlock(posBeforeNode + 1, update);
8687
}
8788

88-
export function removeBlocks(
89+
function removeBlocksWithCallback(
8990
blocksToRemove: BlockIdentifier[],
90-
editor: Editor
91+
editor: Editor,
92+
// Should return new removedSize.
93+
callback?: (
94+
node: Node,
95+
pos: number,
96+
tr: Transaction,
97+
removedSize: number
98+
) => number
9199
) {
100+
const tr = editor.state.tr;
101+
92102
const idsOfBlocksToRemove = new Set<string>(
93103
blocksToRemove.map((block) =>
94104
typeof block === "string" ? block : block.id
@@ -111,12 +121,13 @@ export function removeBlocks(
111121
return true;
112122
}
113123

114-
idsOfBlocksToRemove.delete(node.attrs.id);
115-
const oldDocSize = editor.state.doc.nodeSize;
124+
removedSize = callback?.(node, pos, tr, removedSize) || removedSize;
116125

117-
editor.commands.BNDeleteBlock(pos - removedSize + 1);
126+
idsOfBlocksToRemove.delete(node.attrs.id);
118127

119-
const newDocSize = editor.state.doc.nodeSize;
128+
const oldDocSize = tr.doc.nodeSize;
129+
tr.delete(pos - removedSize - 1, pos - removedSize + node.nodeSize + 1);
130+
const newDocSize = tr.doc.nodeSize;
120131
removedSize += oldDocSize - newDocSize;
121132

122133
return false;
@@ -130,6 +141,15 @@ export function removeBlocks(
130141
notFoundIds
131142
);
132143
}
144+
145+
editor.view.dispatch(tr);
146+
}
147+
148+
export function removeBlocks(
149+
blocksToRemove: BlockIdentifier[],
150+
editor: Editor
151+
) {
152+
removeBlocksWithCallback(blocksToRemove, editor);
133153
}
134154

135155
export function replaceBlocks<
@@ -141,6 +161,33 @@ export function replaceBlocks<
141161
blocksToInsert: PartialBlock<BSchema, I, S>[],
142162
editor: BlockNoteEditor<BSchema, I, S>
143163
) {
144-
insertBlocks(blocksToInsert, blocksToRemove[0], "before", editor);
145-
removeBlocks(blocksToRemove, editor._tiptapEditor);
164+
const ttEditor = editor._tiptapEditor;
165+
166+
const nodesToInsert: Node[] = [];
167+
for (const blockSpec of blocksToInsert) {
168+
nodesToInsert.push(
169+
blockToNode(blockSpec, ttEditor.schema, editor.styleSchema)
170+
);
171+
}
172+
173+
const idOfFirstBlock =
174+
typeof blocksToRemove[0] === "string"
175+
? blocksToRemove[0]
176+
: blocksToRemove[0].id;
177+
178+
removeBlocksWithCallback(
179+
blocksToRemove,
180+
ttEditor,
181+
(node, pos, tr, removedSize) => {
182+
if (node.attrs.id === idOfFirstBlock) {
183+
const oldDocSize = tr.doc.nodeSize;
184+
tr.insert(pos, nodesToInsert);
185+
const newDocSize = tr.doc.nodeSize;
186+
187+
return removedSize + oldDocSize - newDocSize;
188+
}
189+
190+
return removedSize;
191+
}
192+
);
146193
}

0 commit comments

Comments
 (0)