Skip to content

Commit 06b4306

Browse files
committed
feat: implement the dispatchTransaction method from Tiptap to provide a new v3-update method
1 parent 56e079b commit 06b4306

File tree

3 files changed

+109
-16
lines changed

3 files changed

+109
-16
lines changed

packages/core/src/api/nodeUtil.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ export function getBlocksChangedByTransaction<
142142
SSchema extends StyleSchema = DefaultStyleSchema
143143
>(
144144
transaction: Transaction,
145-
editor: BlockNoteEditor<BSchema, ISchema, SSchema>
145+
editor: BlockNoteEditor<BSchema, ISchema, SSchema>,
146+
appendedTransactions: Transaction[] = []
146147
): BlocksChanged<BSchema, ISchema, SSchema> {
147148
let source: BlockChangeSource = { type: "local" };
148149

@@ -163,11 +164,9 @@ export function getBlocksChangedByTransaction<
163164
}
164165

165166
const changes: BlocksChanged<BSchema, ISchema, SSchema> = [];
166-
// TODO when we upgrade to Tiptap v3, we can get the appendedTransactions which would give us things like the actual inserted Block IDs.
167-
// since they are appended to the transaction via the unique-id plugin
168167
const combinedTransaction = combineTransactionSteps(transaction.before, [
169168
transaction,
170-
...[] /*appendedTransactions*/,
169+
...appendedTransactions,
171170
]);
172171

173172
let prevAffectedBlocks: Block<BSchema, ISchema, SSchema>[] = [];

packages/core/src/editor/BlockNoteEditor.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,16 +1482,27 @@ export class BlockNoteEditor<
14821482
return;
14831483
}
14841484

1485-
const cb = ({ transaction }: { transaction: Transaction }) => {
1485+
const cb = ({
1486+
transaction,
1487+
appendedTransactions,
1488+
}: {
1489+
transaction: Transaction;
1490+
appendedTransactions: Transaction[];
1491+
}) => {
14861492
callback(this, {
1487-
getChanges: () => getBlocksChangedByTransaction(transaction, this),
1493+
getChanges: () =>
1494+
getBlocksChangedByTransaction(
1495+
transaction,
1496+
this,
1497+
appendedTransactions
1498+
),
14881499
});
14891500
};
14901501

1491-
this._tiptapEditor.on("update", cb);
1502+
this._tiptapEditor.on("v3-update", cb);
14921503

14931504
return () => {
1494-
this._tiptapEditor.off("update", cb);
1505+
this._tiptapEditor.off("v3-update", cb);
14951506
};
14961507
}
14971508

packages/core/src/editor/BlockNoteTipTapEditor.ts

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { EditorOptions, createDocument } from "@tiptap/core";
2-
// import "./blocknote.css";
1+
import { Editor, EditorOptions, createDocument } from "@tiptap/core";
32
import { Editor as TiptapEditor } from "@tiptap/core";
43

54
import { Node } from "@tiptap/pm/model";
@@ -138,13 +137,83 @@ export class BlockNoteTipTapEditor extends TiptapEditor {
138137
return this._state;
139138
}
140139

141-
dispatch(tr: Transaction) {
142-
if (this.view) {
143-
this.view.dispatch(tr);
144-
} else {
140+
dispatch(transaction: Transaction) {
141+
if (!this.view) {
145142
// before view has been initialized
146-
this._state = this.state.apply(tr);
143+
this._state = this.state.apply(transaction);
144+
return;
145+
}
146+
// This is a verbatim copy of the default dispatch method, but with the following changes:
147+
// - We provide the appendedTransactions to a new `v3-update` event
148+
// In the future, we can remove this dispatch method entirely and rely on the new `update` event signature which does what we want by providing the appendedTransactions
149+
////////////////////////////////////////////////////////////////////////////////
150+
// if the editor / the view of the editor was destroyed
151+
// the transaction should not be dispatched as there is no view anymore.
152+
if (this.view.isDestroyed) {
153+
return;
154+
}
155+
156+
if (this.isCapturingTransaction) {
157+
// Do the default capture behavior
158+
(this as any).dispatchTransaction(transaction);
159+
160+
return;
161+
}
162+
163+
const { state, transactions: appendedTransactions } =
164+
this.state.applyTransaction(transaction);
165+
const selectionHasChanged = !this.state.selection.eq(state.selection);
166+
167+
this.emit("beforeTransaction", {
168+
editor: this,
169+
transaction,
170+
nextState: state,
171+
});
172+
this.view.updateState(state);
173+
this.emit("transaction", {
174+
editor: this,
175+
transaction,
176+
});
177+
178+
if (selectionHasChanged) {
179+
this.emit("selectionUpdate", {
180+
editor: this,
181+
transaction,
182+
});
183+
}
184+
185+
const focus = transaction.getMeta("focus");
186+
const blur = transaction.getMeta("blur");
187+
188+
if (focus) {
189+
this.emit("focus", {
190+
editor: this,
191+
event: focus.event,
192+
transaction,
193+
});
194+
}
195+
196+
if (blur) {
197+
this.emit("blur", {
198+
editor: this,
199+
event: blur.event,
200+
transaction,
201+
});
147202
}
203+
204+
if (!transaction.docChanged || transaction.getMeta("preventUpdate")) {
205+
return;
206+
}
207+
208+
this.emit("update", {
209+
editor: this,
210+
transaction,
211+
});
212+
this.emit("v3-update", {
213+
editor: this,
214+
transaction,
215+
appendedTransactions: appendedTransactions.slice(1),
216+
});
148217
}
149218

150219
/**
@@ -171,7 +240,7 @@ export class BlockNoteTipTapEditor extends TiptapEditor {
171240
{
172241
...this.options.editorProps,
173242
// @ts-ignore
174-
dispatchTransaction: this.dispatchTransaction.bind(this),
243+
dispatchTransaction: this.dispatch.bind(this),
175244
state: this.state,
176245
markViews,
177246
nodeViews: this.extensionManager.nodeViews,
@@ -228,3 +297,17 @@ export class BlockNoteTipTapEditor extends TiptapEditor {
228297
// (note: can probably be removed after tiptap upgrade fixed in 2.8.0)
229298
this.options.onPaste = this.options.onDrop = undefined;
230299
};
300+
301+
declare module "@tiptap/core" {
302+
interface EditorEvents {
303+
/**
304+
* This is a custom event that will be emitted in Tiptap V3.
305+
* We use it to provide the appendedTransactions, until Tiptap V3 is released.
306+
*/
307+
"v3-update": {
308+
editor: Editor;
309+
transaction: Transaction;
310+
appendedTransactions: Transaction[];
311+
};
312+
}
313+
}

0 commit comments

Comments
 (0)