aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/editor/EditorStore.ts
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-10-02 02:11:31 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-10-02 02:11:31 +0200
commitb834db0fd424e7ab02fcd5e509d855f2d97863bd (patch)
treeb56ce9b8f752d8ca98e1d9082c63542e5dd993c1 /language-web/src/main/js/editor/EditorStore.ts
parentfeat: skeleton for language to store mapping (diff)
downloadrefinery-b834db0fd424e7ab02fcd5e509d855f2d97863bd.tar.gz
refinery-b834db0fd424e7ab02fcd5e509d855f2d97863bd.tar.zst
refinery-b834db0fd424e7ab02fcd5e509d855f2d97863bd.zip
perf(web): split off CodeMirror chunks
Also optimizes statis asset caching.
Diffstat (limited to 'language-web/src/main/js/editor/EditorStore.ts')
-rw-r--r--language-web/src/main/js/editor/EditorStore.ts75
1 files changed, 62 insertions, 13 deletions
diff --git a/language-web/src/main/js/editor/EditorStore.ts b/language-web/src/main/js/editor/EditorStore.ts
index 5da45ac1..1ac2e79f 100644
--- a/language-web/src/main/js/editor/EditorStore.ts
+++ b/language-web/src/main/js/editor/EditorStore.ts
@@ -1,19 +1,14 @@
1import { Editor, EditorConfiguration } from 'codemirror'; 1import type { Editor, EditorConfiguration } from 'codemirror';
2import 'codemirror/addon/selection/active-line';
3import { 2import {
4 createAtom, 3 createAtom,
5 makeAutoObservable, 4 makeAutoObservable,
6 observable, 5 observable,
6 runInAction,
7} from 'mobx'; 7} from 'mobx';
8import 'mode-problem'; 8import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror';
9import {
10 IXtextOptions,
11 IXtextServices,
12 createServices,
13 removeServices,
14} from 'xtext/xtext-codemirror';
15 9
16import { ThemeStore } from '../theme/ThemeStore'; 10import type { IEditorChunk } from './editor';
11import type { ThemeStore } from '../theme/ThemeStore';
17 12
18const xtextLang = 'problem'; 13const xtextLang = 'problem';
19 14
@@ -33,6 +28,8 @@ export class EditorStore {
33 28
34 atom; 29 atom;
35 30
31 chunk?: IEditorChunk;
32
36 editor?: Editor; 33 editor?: Editor;
37 34
38 xtextServices?: IXtextServices; 35 xtextServices?: IXtextServices;
@@ -41,15 +38,56 @@ export class EditorStore {
41 38
42 showLineNumbers = false; 39 showLineNumbers = false;
43 40
41 initialSelection!: { start: number, end: number, focused: boolean };
42
44 constructor(themeStore: ThemeStore) { 43 constructor(themeStore: ThemeStore) {
45 this.themeStore = themeStore; 44 this.themeStore = themeStore;
46 this.atom = createAtom('EditorStore'); 45 this.atom = createAtom('EditorStore');
46 this.resetInitialSelection();
47 makeAutoObservable(this, { 47 makeAutoObservable(this, {
48 themeStore: false, 48 themeStore: false,
49 atom: false, 49 atom: false,
50 chunk: observable.ref,
50 editor: observable.ref, 51 editor: observable.ref,
51 xtextServices: observable.ref, 52 xtextServices: observable.ref,
53 initialSelection: false,
52 }); 54 });
55 import('./editor').then(({ editorChunk }) => {
56 runInAction(() => {
57 this.chunk = editorChunk;
58 });
59 }).catch((error) => {
60 console.warn('Error while loading editor', error);
61 });
62 }
63
64 setInitialSelection(start: number, end: number, focused: boolean): void {
65 this.initialSelection = { start, end, focused };
66 this.applyInitialSelectionToEditor();
67 }
68
69 private resetInitialSelection(): void {
70 this.initialSelection = {
71 start: 0,
72 end: 0,
73 focused: false,
74 };
75 }
76
77 private applyInitialSelectionToEditor(): void {
78 if (this.editor) {
79 const { start, end, focused } = this.initialSelection;
80 const doc = this.editor.getDoc();
81 const startPos = doc.posFromIndex(start);
82 const endPos = doc.posFromIndex(end);
83 doc.setSelection(startPos, endPos, {
84 scroll: true,
85 });
86 if (focused) {
87 this.editor.focus();
88 }
89 this.resetInitialSelection();
90 }
53 } 91 }
54 92
55 /** 93 /**
@@ -61,16 +99,23 @@ export class EditorStore {
61 * @param newEditor The new CodeMirror instance 99 * @param newEditor The new CodeMirror instance
62 */ 100 */
63 editorDidMount(newEditor: Editor): void { 101 editorDidMount(newEditor: Editor): void {
102 if (!this.chunk) {
103 throw new Error('Editor not loaded yet');
104 }
64 if (this.editor) { 105 if (this.editor) {
65 throw new Error('CoreMirror editor mounted before unmounting'); 106 throw new Error('CoreMirror editor mounted before unmounting');
66 } 107 }
67 this.editor = newEditor; 108 this.editor = newEditor;
68 this.xtextServices = createServices(newEditor, xtextOptions); 109 this.xtextServices = this.chunk.createServices(newEditor, xtextOptions);
110 this.applyInitialSelectionToEditor();
69 } 111 }
70 112
71 editorWillUnmount(): void { 113 editorWillUnmount(): void {
114 if (!this.chunk) {
115 throw new Error('Editor not loaded yet');
116 }
72 if (this.editor) { 117 if (this.editor) {
73 removeServices(this.editor); 118 this.chunk.removeServices(this.editor);
74 } 119 }
75 delete this.editor; 120 delete this.editor;
76 delete this.xtextServices; 121 delete this.xtextServices;
@@ -93,10 +138,14 @@ export class EditorStore {
93 this.atom.reportObserved(); 138 this.atom.reportObserved();
94 } 139 }
95 140
141 get codeMirrorTheme(): string {
142 return `problem-${this.themeStore.className}`;
143 }
144
96 get codeMirrorOptions(): EditorConfiguration { 145 get codeMirrorOptions(): EditorConfiguration {
97 return { 146 return {
98 ...codeMirrorGlobalOptions, 147 ...codeMirrorGlobalOptions,
99 theme: this.themeStore.codeMirrorTheme, 148 theme: this.codeMirrorTheme,
100 lineNumbers: this.showLineNumbers, 149 lineNumbers: this.showLineNumbers,
101 }; 150 };
102 } 151 }