Skip to content

Commit

Permalink
fix: Bug in replaceBlocks (#487)
Browse files Browse the repository at this point in the history
* Improved code for `replaceBlocks`

* Cleaned up code

* Fixed test failure
  • Loading branch information
matthewlipski authored Jan 3, 2024
1 parent 375b03b commit 295c7ba
Showing 1 changed file with 55 additions and 8 deletions.
63 changes: 55 additions & 8 deletions packages/core/src/api/blockManipulation/blockManipulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "../../schema";
import { blockToNode } from "../nodeConversions/nodeConversions";
import { getNodeById } from "../nodeUtil";
import { Transaction } from "prosemirror-state";

export function insertBlocks<
BSchema extends BlockSchema,
Expand Down Expand Up @@ -85,10 +86,19 @@ export function updateBlock<
editor.commands.BNUpdateBlock(posBeforeNode + 1, update);
}

export function removeBlocks(
function removeBlocksWithCallback(
blocksToRemove: BlockIdentifier[],
editor: Editor
editor: Editor,
// Should return new removedSize.
callback?: (
node: Node,
pos: number,
tr: Transaction,
removedSize: number
) => number
) {
const tr = editor.state.tr;

const idsOfBlocksToRemove = new Set<string>(
blocksToRemove.map((block) =>
typeof block === "string" ? block : block.id
Expand All @@ -111,12 +121,13 @@ export function removeBlocks(
return true;
}

idsOfBlocksToRemove.delete(node.attrs.id);
const oldDocSize = editor.state.doc.nodeSize;
removedSize = callback?.(node, pos, tr, removedSize) || removedSize;

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

const newDocSize = editor.state.doc.nodeSize;
const oldDocSize = tr.doc.nodeSize;
tr.delete(pos - removedSize - 1, pos - removedSize + node.nodeSize + 1);
const newDocSize = tr.doc.nodeSize;
removedSize += oldDocSize - newDocSize;

return false;
Expand All @@ -130,6 +141,15 @@ export function removeBlocks(
notFoundIds
);
}

editor.view.dispatch(tr);
}

export function removeBlocks(
blocksToRemove: BlockIdentifier[],
editor: Editor
) {
removeBlocksWithCallback(blocksToRemove, editor);
}

export function replaceBlocks<
Expand All @@ -141,6 +161,33 @@ export function replaceBlocks<
blocksToInsert: PartialBlock<BSchema, I, S>[],
editor: BlockNoteEditor<BSchema, I, S>
) {
insertBlocks(blocksToInsert, blocksToRemove[0], "before", editor);
removeBlocks(blocksToRemove, editor._tiptapEditor);
const ttEditor = editor._tiptapEditor;

const nodesToInsert: Node[] = [];
for (const blockSpec of blocksToInsert) {
nodesToInsert.push(
blockToNode(blockSpec, ttEditor.schema, editor.styleSchema)
);
}

const idOfFirstBlock =
typeof blocksToRemove[0] === "string"
? blocksToRemove[0]
: blocksToRemove[0].id;

removeBlocksWithCallback(
blocksToRemove,
ttEditor,
(node, pos, tr, removedSize) => {
if (node.attrs.id === idOfFirstBlock) {
const oldDocSize = tr.doc.nodeSize;
tr.insert(pos, nodesToInsert);
const newDocSize = tr.doc.nodeSize;

return removedSize + oldDocSize - newDocSize;
}

return removedSize;
}
);
}

2 comments on commit 295c7ba

@vercel
Copy link

@vercel vercel bot commented on 295c7ba Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 295c7ba Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.