Skip to content

Commit 26440c0

Browse files
committed
feat(core): add blocknote transactions
1 parent f5a83c1 commit 26440c0

File tree

31 files changed

+415
-332
lines changed

31 files changed

+415
-332
lines changed

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

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,19 @@ export function insertBlocks<
3232
);
3333
}
3434

35-
const posInfo = getNodeById(id, editor._tiptapEditor.state.doc);
35+
const tr = editor.transaction;
36+
const posInfo = getNodeById(id, tr.doc);
3637
if (!posInfo) {
3738
throw new Error(`Block with ID ${id} not found`);
3839
}
3940

40-
// TODO: we might want to use the ReplaceStep directly here instead of insert,
41-
// because the fitting algorithm should not be necessary and might even cause unexpected behavior
42-
if (placement === "before") {
43-
editor.dispatch(
44-
editor._tiptapEditor.state.tr.insert(posInfo.posBeforeNode, nodesToInsert)
45-
);
46-
}
47-
41+
let pos = posInfo.posBeforeNode;
4842
if (placement === "after") {
49-
editor.dispatch(
50-
editor._tiptapEditor.state.tr.insert(
51-
posInfo.posBeforeNode + posInfo.node.nodeSize,
52-
nodesToInsert
53-
)
54-
);
43+
pos += posInfo.node.nodeSize;
5544
}
5645

46+
editor.dispatch(tr.insert(pos, nodesToInsert));
47+
5748
// Now that the `PartialBlock`s have been converted to nodes, we can
5849
// re-convert them into full `Block`s.
5950
const insertedBlocks: Block<BSchema, I, S>[] = [];

packages/core/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function mergeBlocks(posBetweenBlocks: number) {
1313
}
1414

1515
function getPosBeforeSelectedBlock() {
16-
return getBlockInfoFromSelection(getEditor()._tiptapEditor.state).bnBlock
16+
return getBlockInfoFromSelection(getEditor().prosemirrorState).bnBlock
1717
.beforePos;
1818
}
1919

@@ -62,14 +62,14 @@ describe("Test mergeBlocks", () => {
6262
getEditor().setTextCursorPosition("paragraph-0", "end");
6363

6464
const firstBlockEndOffset =
65-
getEditor()._tiptapEditor.state.selection.$anchor.parentOffset;
65+
getEditor().prosemirrorState.selection.$anchor.parentOffset;
6666

6767
getEditor().setTextCursorPosition("paragraph-1");
6868

6969
mergeBlocks(getPosBeforeSelectedBlock());
7070

7171
const anchorIsAtOldFirstBlockEndPos =
72-
getEditor()._tiptapEditor.state.selection.$anchor.parentOffset ===
72+
getEditor().prosemirrorState.selection.$anchor.parentOffset ===
7373
firstBlockEndOffset;
7474

7575
expect(anchorIsAtOldFirstBlockEndPos).toBeTruthy();

packages/core/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.ts

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,35 @@ import {
1313
const getEditor = setupTestEnv();
1414

1515
function makeSelectionSpanContent(selectionType: "text" | "node" | "cell") {
16-
const blockInfo = getBlockInfoFromSelection(getEditor()._tiptapEditor.state);
16+
const blockInfo = getBlockInfoFromSelection(getEditor().prosemirrorState);
1717
if (!blockInfo.isBlockContainer) {
1818
throw new Error(
1919
`Selection points to a ${blockInfo.blockNoteType} node, not a blockContainer node`
2020
);
2121
}
2222
const { blockContent } = blockInfo;
2323

24+
const editor = getEditor();
25+
const tr = editor.transaction;
2426
if (selectionType === "cell") {
25-
getEditor().dispatch(
26-
getEditor()._tiptapEditor.state.tr.setSelection(
27+
editor.dispatch(
28+
tr.setSelection(
2729
CellSelection.create(
28-
getEditor()._tiptapEditor.state.doc,
29-
getEditor()
30-
._tiptapEditor.state.doc.resolve(blockContent.beforePos + 3)
31-
.before(),
32-
getEditor()
33-
._tiptapEditor.state.doc.resolve(blockContent.afterPos - 3)
34-
.before()
30+
tr.doc,
31+
tr.doc.resolve(blockContent.beforePos + 3).before(),
32+
tr.doc.resolve(blockContent.afterPos - 3).before()
3533
)
3634
)
3735
);
3836
} else if (selectionType === "node") {
39-
getEditor().dispatch(
40-
getEditor()._tiptapEditor.state.tr.setSelection(
41-
NodeSelection.create(
42-
getEditor()._tiptapEditor.state.doc,
43-
blockContent.beforePos
44-
)
45-
)
37+
editor.dispatch(
38+
tr.setSelection(NodeSelection.create(tr.doc, blockContent.beforePos))
4639
);
4740
} else {
48-
getEditor().dispatch(
49-
getEditor()._tiptapEditor.state.tr.setSelection(
41+
editor.dispatch(
42+
tr.setSelection(
5043
TextSelection.create(
51-
getEditor()._tiptapEditor.state.doc,
44+
tr.doc,
5245
blockContent.beforePos + 1,
5346
blockContent.afterPos - 1
5447
)
@@ -64,13 +57,11 @@ describe("Test moveSelectedBlockAndSelection", () => {
6457

6558
moveSelectedBlocksAndSelection(getEditor(), "paragraph-0", "before");
6659

67-
const selection = getEditor()._tiptapEditor.state.selection;
60+
const selection = getEditor().transaction.selection;
6861
getEditor().setTextCursorPosition("paragraph-1");
6962
makeSelectionSpanContent("text");
7063

71-
expect(
72-
selection.eq(getEditor()._tiptapEditor.state.selection)
73-
).toBeTruthy();
64+
expect(selection.eq(getEditor().transaction.selection)).toBeTruthy();
7465
});
7566

7667
it("Node selection", () => {
@@ -79,13 +70,11 @@ describe("Test moveSelectedBlockAndSelection", () => {
7970

8071
moveSelectedBlocksAndSelection(getEditor(), "paragraph-0", "before");
8172

82-
const selection = getEditor()._tiptapEditor.state.selection;
73+
const selection = getEditor().transaction.selection;
8374
getEditor().setTextCursorPosition("image-0");
8475
makeSelectionSpanContent("node");
8576

86-
expect(
87-
selection.eq(getEditor()._tiptapEditor.state.selection)
88-
).toBeTruthy();
77+
expect(selection.eq(getEditor().transaction.selection)).toBeTruthy();
8978
});
9079

9180
it("Cell selection", () => {
@@ -94,39 +83,33 @@ describe("Test moveSelectedBlockAndSelection", () => {
9483

9584
moveSelectedBlocksAndSelection(getEditor(), "paragraph-0", "before");
9685

97-
const selection = getEditor()._tiptapEditor.state.selection;
86+
const selection = getEditor().transaction.selection;
9887
getEditor().setTextCursorPosition("table-0");
9988
makeSelectionSpanContent("cell");
10089

101-
expect(
102-
selection.eq(getEditor()._tiptapEditor.state.selection)
103-
).toBeTruthy();
90+
expect(selection.eq(getEditor().transaction.selection)).toBeTruthy();
10491
});
10592

10693
it("Multiple block selection", () => {
10794
getEditor().setSelection("paragraph-1", "paragraph-2");
10895

10996
moveSelectedBlocksAndSelection(getEditor(), "paragraph-0", "before");
11097

111-
const selection = getEditor()._tiptapEditor.state.selection;
98+
const selection = getEditor().transaction.selection;
11299
getEditor().setSelection("paragraph-1", "paragraph-2");
113100

114-
expect(
115-
selection.eq(getEditor()._tiptapEditor.state.selection)
116-
).toBeTruthy();
101+
expect(selection.eq(getEditor().transaction.selection)).toBeTruthy();
117102
});
118103

119104
it("Multiple block selection with table", () => {
120105
getEditor().setSelection("paragraph-6", "table-0");
121106

122107
moveSelectedBlocksAndSelection(getEditor(), "paragraph-0", "before");
123108

124-
const selection = getEditor()._tiptapEditor.state.selection;
109+
const selection = getEditor().transaction.selection;
125110
getEditor().setSelection("paragraph-6", "table-0");
126111

127-
expect(
128-
selection.eq(getEditor()._tiptapEditor.state.selection)
129-
).toBeTruthy();
112+
expect(selection.eq(getEditor().transaction.selection)).toBeTruthy();
130113
});
131114
});
132115

0 commit comments

Comments
 (0)