aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/editor/defineDecorationSetExtension.ts
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/frontend/src/editor/defineDecorationSetExtension.ts')
-rw-r--r--subprojects/frontend/src/editor/defineDecorationSetExtension.ts42
1 files changed, 42 insertions, 0 deletions
diff --git a/subprojects/frontend/src/editor/defineDecorationSetExtension.ts b/subprojects/frontend/src/editor/defineDecorationSetExtension.ts
new file mode 100644
index 00000000..d9c7bc7d
--- /dev/null
+++ b/subprojects/frontend/src/editor/defineDecorationSetExtension.ts
@@ -0,0 +1,42 @@
1import { StateEffect, StateField, TransactionSpec } from '@codemirror/state';
2import { EditorView, Decoration, DecorationSet } from '@codemirror/view';
3
4export type TransactionSpecFactory = (
5 decorations: DecorationSet,
6) => TransactionSpec;
7
8export default function defineDecorationSetExtension(): [
9 TransactionSpecFactory,
10 StateField<DecorationSet>,
11] {
12 const setEffect = StateEffect.define<DecorationSet>();
13 const stateField = StateField.define<DecorationSet>({
14 create() {
15 return Decoration.none;
16 },
17 update(currentDecorations, transaction) {
18 let newDecorations: DecorationSet | null = null;
19 transaction.effects.forEach((effect) => {
20 if (effect.is(setEffect)) {
21 newDecorations = effect.value;
22 }
23 });
24 if (newDecorations === null) {
25 if (transaction.docChanged) {
26 return currentDecorations.map(transaction.changes);
27 }
28 return currentDecorations;
29 }
30 return newDecorations;
31 },
32 provide: (field) => EditorView.decorations.from(field),
33 });
34
35 function transactionSpecFactory(decorations: DecorationSet) {
36 return {
37 effects: [setEffect.of(decorations)],
38 };
39 }
40
41 return [transactionSpecFactory, stateField];
42}