Skip to content

Commit 77f1bee

Browse files
committed
fix: execute updateBlock as a transaction
1 parent 760d76e commit 77f1bee

File tree

1 file changed

+51
-47
lines changed
  • packages/core/src/api/blockManipulation/commands/updateBlock

1 file changed

+51
-47
lines changed

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

+51-47
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Fragment, NodeType, Node as PMNode, Slice } from "prosemirror-model";
2-
import { EditorState } from "prosemirror-state";
2+
import { Transaction } from "prosemirror-state";
33

44
import { ReplaceStep } from "prosemirror-transform";
55
import { Block, PartialBlock } from "../../../../blocks/defaultBlocks.js";
@@ -34,33 +34,33 @@ export const updateBlockCommand =
3434
block: PartialBlock<BSchema, I, S>
3535
) =>
3636
({
37-
state,
37+
tr,
3838
dispatch,
3939
}: {
40-
state: EditorState;
41-
dispatch: ((args?: any) => any) | undefined;
40+
tr: Transaction;
41+
dispatch: (() => void) | undefined;
4242
}) => {
4343
const blockInfo = getBlockInfoFromResolvedPos(
44-
state.doc.resolve(posBeforeBlock)
44+
tr.doc.resolve(posBeforeBlock)
4545
);
4646

4747
if (dispatch) {
4848
// Adds blockGroup node with child blocks if necessary.
4949

50-
const oldNodeType = state.schema.nodes[blockInfo.blockNoteType];
50+
const oldNodeType = editor.pmSchema.nodes[blockInfo.blockNoteType];
5151
const newNodeType =
52-
state.schema.nodes[block.type || blockInfo.blockNoteType];
52+
editor.pmSchema.nodes[block.type || blockInfo.blockNoteType];
5353
const newBnBlockNodeType = newNodeType.isInGroup("bnBlock")
5454
? newNodeType
55-
: state.schema.nodes["blockContainer"];
55+
: editor.pmSchema.nodes["blockContainer"];
5656

5757
if (blockInfo.isBlockContainer && newNodeType.isInGroup("blockContent")) {
58-
updateChildren(block, state, editor, blockInfo);
58+
updateChildren(block, tr, editor, blockInfo);
5959
// The code below determines the new content of the block.
6060
// or "keep" to keep as-is
6161
updateBlockContentNode(
6262
block,
63-
state,
63+
tr,
6464
editor,
6565
oldNodeType,
6666
newNodeType,
@@ -70,7 +70,7 @@ export const updateBlockCommand =
7070
!blockInfo.isBlockContainer &&
7171
newNodeType.isInGroup("bnBlock")
7272
) {
73-
updateChildren(block, state, editor, blockInfo);
73+
updateChildren(block, tr, editor, blockInfo);
7474
// old node was a bnBlock type (like column or columnList) and new block as well
7575
// No op, we just update the bnBlock below (at end of function) and have already updated the children
7676
} else {
@@ -88,15 +88,15 @@ export const updateBlockCommand =
8888
editor.schema.styleSchema,
8989
editor.blockCache
9090
);
91-
state.tr.replaceWith(
91+
tr.replaceWith(
9292
blockInfo.bnBlock.beforePos,
9393
blockInfo.bnBlock.afterPos,
9494
blockToNode(
9595
{
9696
children: existingBlock.children, // if no children are passed in, use existing children
9797
...block,
9898
},
99-
state.schema,
99+
editor.pmSchema,
100100
editor.schema.styleSchema
101101
)
102102
);
@@ -106,7 +106,7 @@ export const updateBlockCommand =
106106

107107
// Adds all provided props as attributes to the parent blockContainer node too, and also preserves existing
108108
// attributes.
109-
state.tr.setNodeMarkup(blockInfo.bnBlock.beforePos, newBnBlockNodeType, {
109+
tr.setNodeMarkup(blockInfo.bnBlock.beforePos, newBnBlockNodeType, {
110110
...blockInfo.bnBlock.node.attrs,
111111
...block.props,
112112
});
@@ -121,7 +121,7 @@ function updateBlockContentNode<
121121
S extends StyleSchema
122122
>(
123123
block: PartialBlock<BSchema, I, S>,
124-
state: EditorState,
124+
tr: Transaction,
125125
editor: BlockNoteEditor<BSchema, I, S>,
126126
oldNodeType: NodeType,
127127
newNodeType: NodeType,
@@ -140,7 +140,7 @@ function updateBlockContentNode<
140140
// Adds a single text node with no marks to the content.
141141
content = inlineContentToNodes(
142142
[block.content],
143-
state.schema,
143+
editor.pmSchema,
144144
editor.schema.styleSchema,
145145
newNodeType.name
146146
);
@@ -149,14 +149,14 @@ function updateBlockContentNode<
149149
// for each InlineContent object.
150150
content = inlineContentToNodes(
151151
block.content,
152-
state.schema,
152+
editor.pmSchema,
153153
editor.schema.styleSchema,
154154
newNodeType.name
155155
);
156156
} else if (block.content.type === "tableContent") {
157157
content = tableContentToNodes(
158158
block.content,
159-
state.schema,
159+
editor.pmSchema,
160160
editor.schema.styleSchema
161161
);
162162
} else {
@@ -186,9 +186,9 @@ function updateBlockContentNode<
186186
// content is being replaced or not.
187187
if (content === "keep") {
188188
// use setNodeMarkup to only update the type and attributes
189-
state.tr.setNodeMarkup(
189+
tr.setNodeMarkup(
190190
blockInfo.blockContent.beforePos,
191-
block.type === undefined ? undefined : state.schema.nodes[block.type],
191+
block.type === undefined ? undefined : editor.pmSchema.nodes[block.type],
192192
{
193193
...blockInfo.blockContent.node.attrs,
194194
...block.props,
@@ -198,7 +198,7 @@ function updateBlockContentNode<
198198
// use replaceWith to replace the content and the block itself
199199
// also reset the selection since replacing the block content
200200
// sets it to the next block.
201-
state.tr.replaceWith(
201+
tr.replaceWith(
202202
blockInfo.blockContent.beforePos,
203203
blockInfo.blockContent.afterPos,
204204
newNodeType.createChecked(
@@ -218,21 +218,21 @@ function updateChildren<
218218
S extends StyleSchema
219219
>(
220220
block: PartialBlock<BSchema, I, S>,
221-
state: EditorState,
221+
tr: Transaction,
222222
editor: BlockNoteEditor<BSchema, I, S>,
223223
blockInfo: BlockInfo
224224
) {
225225
if (block.children !== undefined && block.children.length > 0) {
226226
const childNodes = block.children.map((child) => {
227-
return blockToNode(child, state.schema, editor.schema.styleSchema);
227+
return blockToNode(child, editor.pmSchema, editor.schema.styleSchema);
228228
});
229229

230230
// Checks if a blockGroup node already exists.
231231
if (blockInfo.childContainer) {
232232
// Replaces all child nodes in the existing blockGroup with the ones created earlier.
233233

234234
// use a replacestep to avoid the fitting algorithm
235-
state.tr.step(
235+
tr.step(
236236
new ReplaceStep(
237237
blockInfo.childContainer.beforePos + 1,
238238
blockInfo.childContainer.afterPos - 1,
@@ -244,9 +244,9 @@ function updateChildren<
244244
throw new Error("impossible");
245245
}
246246
// Inserts a new blockGroup containing the child nodes created earlier.
247-
state.tr.insert(
247+
tr.insert(
248248
blockInfo.blockContent.afterPos,
249-
state.schema.nodes["blockGroup"].createChecked({}, childNodes)
249+
editor.pmSchema.nodes["blockGroup"].createChecked({}, childNodes)
250250
);
251251
}
252252
}
@@ -261,34 +261,38 @@ export function updateBlock<
261261
blockToUpdate: BlockIdentifier,
262262
update: PartialBlock<BSchema, I, S>
263263
): Block<BSchema, I, S> {
264-
const ttEditor = editor._tiptapEditor;
265-
266264
const id =
267265
typeof blockToUpdate === "string" ? blockToUpdate : blockToUpdate.id;
266+
return editor.transact(() => {
267+
const tr = editor.transaction;
268+
const posInfo = getNodeById(id, tr.doc);
269+
if (!posInfo) {
270+
throw new Error(`Block with ID ${id} not found`);
271+
}
268272

269-
const posInfo = getNodeById(id, ttEditor.state.doc);
270-
if (!posInfo) {
271-
throw new Error(`Block with ID ${id} not found`);
272-
}
273-
274-
ttEditor.commands.command(({ state, dispatch }) => {
275273
updateBlockCommand(
276274
editor,
277275
posInfo.posBeforeNode,
278276
update
279-
)({ state, dispatch });
280-
return true;
281-
});
277+
)({
278+
tr,
279+
dispatch: () => {
280+
// no-op
281+
},
282+
});
283+
// Actually dispatch that transaction
284+
editor.dispatch(tr);
282285

283-
const blockContainerNode = ttEditor.state.doc
284-
.resolve(posInfo.posBeforeNode + 1) // TODO: clean?
285-
.node();
286+
const blockContainerNode = tr.doc
287+
.resolve(posInfo.posBeforeNode + 1) // TODO: clean?
288+
.node();
286289

287-
return nodeToBlock(
288-
blockContainerNode,
289-
editor.schema.blockSchema,
290-
editor.schema.inlineContentSchema,
291-
editor.schema.styleSchema,
292-
editor.blockCache
293-
);
290+
return nodeToBlock(
291+
blockContainerNode,
292+
editor.schema.blockSchema,
293+
editor.schema.inlineContentSchema,
294+
editor.schema.styleSchema,
295+
editor.blockCache
296+
);
297+
});
294298
}

0 commit comments

Comments
 (0)