aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src')
-rw-r--r--language-web/src/main/js/App.tsx (renamed from language-web/src/main/js/App.jsx)0
-rw-r--r--language-web/src/main/js/Navbar.jsx37
-rw-r--r--language-web/src/main/js/RootStore.tsx (renamed from language-web/src/main/js/RootStore.jsx)6
-rw-r--r--language-web/src/main/js/editor/Editor.jsx52
-rw-r--r--language-web/src/main/js/editor/Editor.tsx20
-rw-r--r--language-web/src/main/js/editor/EditorButtons.tsx (renamed from language-web/src/main/js/editor/EditorButtons.jsx)2
-rw-r--r--language-web/src/main/js/editor/EditorStore.jsx87
-rw-r--r--language-web/src/main/js/editor/EditorStore.ts127
-rw-r--r--language-web/src/main/js/index.tsx (renamed from language-web/src/main/js/index.jsx)4
-rw-r--r--language-web/src/main/js/makeStyles.ts (renamed from language-web/src/main/js/makeStyles.js)0
-rw-r--r--language-web/src/main/js/xtext/xtext-codemirror.d.ts43
11 files changed, 196 insertions, 182 deletions
diff --git a/language-web/src/main/js/App.jsx b/language-web/src/main/js/App.tsx
index 5bd46c09..5bd46c09 100644
--- a/language-web/src/main/js/App.jsx
+++ b/language-web/src/main/js/App.tsx
diff --git a/language-web/src/main/js/Navbar.jsx b/language-web/src/main/js/Navbar.jsx
deleted file mode 100644
index cf1bc54f..00000000
--- a/language-web/src/main/js/Navbar.jsx
+++ /dev/null
@@ -1,37 +0,0 @@
1import React from 'react';
2import { Button, Navbar, Nav } from 'react-bootstrap';
3import { FaGithub, FaPlayCircle } from 'react-icons/fa';
4
5export default () => (
6 <Navbar
7 variant='secondary'
8 className='px-2'
9 >
10 <Navbar.Brand>GraphSolver</Navbar.Brand>
11 <Navbar.Toggle aria-controls='basic-navbar-nav'/>
12 <Navbar.Collapse id='basic-navbar-nav'>
13 <Nav className="me-auto">
14 <Nav.Link
15 href="https://github.com/viatra/VIATRA-Generator#readme"
16 >
17 About
18 </Nav.Link>
19 <Nav.Link
20 href="https://github.com/viatra/VIATRA-Generator/wiki"
21 >
22 Getting started
23 </Nav.Link>
24 <Nav.Link
25 href="https://github.com/viatra/VIATRA-Generator"
26 >
27 <FaGithub/> Github
28 </Nav.Link>
29 </Nav>
30 <Button
31 variant='success'
32 >
33 <FaPlayCircle/> Generate
34 </Button>
35 </Navbar.Collapse>
36 </Navbar>
37);
diff --git a/language-web/src/main/js/RootStore.jsx b/language-web/src/main/js/RootStore.tsx
index a437fdd0..2159f440 100644
--- a/language-web/src/main/js/RootStore.jsx
+++ b/language-web/src/main/js/RootStore.tsx
@@ -1,3 +1,4 @@
1
1import React, { createContext, useContext } from 'react'; 2import React, { createContext, useContext } from 'react';
2 3
3import EditorStore from './editor/EditorStore'; 4import EditorStore from './editor/EditorStore';
@@ -10,15 +11,14 @@ export default class RootStore {
10 } 11 }
11} 12}
12 13
13const StoreContext = createContext(undefined); 14const StoreContext = createContext<RootStore | undefined>(undefined);
14 15
15export const RootStoreProvider = ({ children, rootStore }) => ( 16export const RootStoreProvider: React.FC<{ rootStore: RootStore }> = ({ children, rootStore }) => (
16 <StoreContext.Provider value={rootStore}> 17 <StoreContext.Provider value={rootStore}>
17 {children} 18 {children}
18 </StoreContext.Provider> 19 </StoreContext.Provider>
19); 20);
20 21
21/** @returns {RootStore} */
22export const useRootStore = () => { 22export const useRootStore = () => {
23 const rootStore = useContext(StoreContext); 23 const rootStore = useContext(StoreContext);
24 if (!rootStore) { 24 if (!rootStore) {
diff --git a/language-web/src/main/js/editor/Editor.jsx b/language-web/src/main/js/editor/Editor.jsx
deleted file mode 100644
index 4cd9b3bd..00000000
--- a/language-web/src/main/js/editor/Editor.jsx
+++ /dev/null
@@ -1,52 +0,0 @@
1import { observer } from 'mobx-react-lite';
2import 'mode-problem';
3import React, { useCallback } from 'react';
4import { Controlled as CodeMirror } from 'react-codemirror2-react-17';
5import { createServices, removeServices } from 'xtext/xtext-codemirror';
6
7import { useRootStore } from '../RootStore';
8
9export default observer(() => {
10 const editorStore = useRootStore().editorStore;
11
12 const codeMirrorOptions = {
13 mode: 'xtext/problem',
14 indentUnit: 2,
15 theme: 'material-darker',
16 lineNumbers: editorStore.showLineNumbers,
17 };
18
19 const xtextOptions = {
20 xtextLang: 'problem',
21 enableFormattingAction: true,
22 }
23
24 const editorDidMount = useCallback((editor) => {
25 createServices(editor, xtextOptions);
26 editorStore.updateEditor(editor);
27 }, [editorStore]);
28
29 const editorWillUnmount = useCallback((editor) => {
30 editorStore.editor = null;
31 removeServices(editor);
32 }, [editorStore]);
33
34 const onBeforeChange = useCallback((_editor, _data, value) => {
35 editorStore.updateValue(value);
36 }, [editorStore]);
37
38 const onChange = useCallback((_editor, _data, _value) => {
39 editorStore.reportChanged();
40 }, [editorStore]);
41
42 return (
43 <CodeMirror
44 value={editorStore.value}
45 options={codeMirrorOptions}
46 editorDidMount={editorDidMount}
47 editorWillUnmount={editorWillUnmount}
48 onBeforeChange={onBeforeChange}
49 onChange={onChange}
50 />
51 );
52});
diff --git a/language-web/src/main/js/editor/Editor.tsx b/language-web/src/main/js/editor/Editor.tsx
new file mode 100644
index 00000000..f81c5c37
--- /dev/null
+++ b/language-web/src/main/js/editor/Editor.tsx
@@ -0,0 +1,20 @@
1import { observer } from 'mobx-react-lite';
2import React from 'react';
3import { Controlled as CodeMirror } from 'react-codemirror2';
4
5import { useRootStore } from '../RootStore';
6
7export default observer(() => {
8 const { editorStore } = useRootStore();
9
10 return (
11 <CodeMirror
12 value={editorStore.value}
13 options={editorStore.codeMirrorOptions}
14 editorDidMount={(editor) => editorStore.editorDidMount(editor)}
15 editorWillUnmount={() => editorStore.editorWillUnmount()}
16 onBeforeChange={(_editor, _data, value) => editorStore.updateValue(value)}
17 onChange={() => editorStore.reportChanged()}
18 />
19 );
20});
diff --git a/language-web/src/main/js/editor/EditorButtons.jsx b/language-web/src/main/js/editor/EditorButtons.tsx
index a5a57f93..1a187635 100644
--- a/language-web/src/main/js/editor/EditorButtons.jsx
+++ b/language-web/src/main/js/editor/EditorButtons.tsx
@@ -29,7 +29,7 @@ const useStyles = makeStyles()(theme => ({
29})); 29}));
30 30
31export default observer(() => { 31export default observer(() => {
32 const editorStore = useRootStore().editorStore; 32 const { editorStore } = useRootStore();
33 const { classes, cx } = useStyles(); 33 const { classes, cx } = useStyles();
34 return ( 34 return (
35 <> 35 <>
diff --git a/language-web/src/main/js/editor/EditorStore.jsx b/language-web/src/main/js/editor/EditorStore.jsx
deleted file mode 100644
index b6f9bc0a..00000000
--- a/language-web/src/main/js/editor/EditorStore.jsx
+++ /dev/null
@@ -1,87 +0,0 @@
1import CodeMirror from 'codemirror';
2import { createAtom, makeAutoObservable, observable } from 'mobx';
3
4export default class EditorStore {
5 atom;
6 /** @type {CodeMirror} */
7 editor = null;
8 /** @type {string} */
9 value = '';
10 /** @type {boolean} */
11 showLineNumbers = false;
12 /** @type {boolean} */
13 showLigatures = true;
14
15 constructor() {
16 this.atom = createAtom('EditorStore');
17 makeAutoObservable(this, {
18 atom: false,
19 editor: observable.ref,
20 });
21 }
22
23 /**
24 * Attaches a new CodeMirror instance.
25 *
26 * The store will node subscribe to any CodeMirror events. Instead,
27 * the editor component should subscribe to them and relay them to the store.
28 *
29 * @param {CodeMirror} newEditor The new CodeMirror instance
30 */
31 updateEditor(newEditor) {
32 this.editor = newEditor;
33 }
34
35 /**
36 * Updates the contents of the editor.
37 *
38 * @param {string} newValue The new contents of the editor
39 */
40 updateValue(newValue) {
41 this.value = newValue;
42 }
43
44 reportChanged() {
45 this.atom.reportChanged();
46 }
47
48 /**
49 * @returns {boolean} `true` if there is history to undo
50 */
51 get canUndo() {
52 this.atom.reportObserved();
53 if (!this.editor) {
54 return false;
55 }
56 const { undo: undoSize } = this.editor.historySize();
57 return undoSize > 0;
58 }
59
60 undo() {
61 this.editor.undo();
62 }
63
64 /**
65 * @returns {boolean} `true` if there is history to redo
66 */
67 get canRedo() {
68 this.atom.reportObserved();
69 if (!this.editor) {
70 return false;
71 }
72 const { redo: redoSize } = this.editor.historySize();
73 return redoSize > 0;
74 }
75
76 redo() {
77 this.editor.redo();
78 }
79
80 toggleLineNumbers() {
81 this.showLineNumbers = !this.showLineNumbers;
82 }
83
84 toggleLigatures() {
85 this.showLigatures = !this.showLigatures;
86 }
87}
diff --git a/language-web/src/main/js/editor/EditorStore.ts b/language-web/src/main/js/editor/EditorStore.ts
new file mode 100644
index 00000000..167e1ade
--- /dev/null
+++ b/language-web/src/main/js/editor/EditorStore.ts
@@ -0,0 +1,127 @@
1import { Editor, EditorConfiguration } from 'codemirror';
2import {
3 createAtom,
4 makeAutoObservable,
5 observable,
6} from 'mobx';
7import 'mode-problem';
8import {
9 IXtextOptions,
10 IXtextServices,
11 createServices,
12 removeServices,
13} from 'xtext/xtext-codemirror';
14
15const xtextLang = 'problem';
16
17const xtextOptions: IXtextOptions = {
18 xtextLang,
19 enableFormattingAction: true,
20};
21
22const codeMirrorGlobalOptions: EditorConfiguration = {
23 mode: `xtext/${xtextLang}`,
24 indentUnit: 2,
25 theme: 'material-darker',
26};
27
28export default class EditorStore {
29 _atom;
30 editor?: Editor;
31 xtextServices?: IXtextServices;
32 value = '';
33 showLineNumbers = false;
34
35 constructor() {
36 this._atom = createAtom('EditorStore');
37 makeAutoObservable(this, {
38 _atom: false,
39 editor: observable.ref,
40 xtextServices: observable.ref,
41 });
42 }
43
44 /**
45 * Attaches a new CodeMirror instance and creates Xtext services.
46 *
47 * The store will not subscribe to any CodeMirror events. Instead,
48 * the editor component should subscribe to them and relay them to the store.
49 *
50 * @param newEditor The new CodeMirror instance
51 */
52 editorDidMount(newEditor: Editor) {
53 if (this.editor) {
54 throw new Error('CoreMirror editor mounted before unmounting');
55 }
56 this.editor = newEditor;
57 this.xtextServices = createServices(newEditor, xtextOptions);
58 }
59
60 editorWillUnmount() {
61 if (this.editor) {
62 removeServices(this.editor);
63 }
64 this.editor = undefined;
65 this.xtextServices = undefined;
66 }
67
68 /**
69 * Updates the contents of the editor.
70 *
71 * @param newValue The new contents of the editor
72 */
73 updateValue(newValue: string) {
74 this.value = newValue;
75 }
76
77 reportChanged() {
78 this._atom.reportChanged();
79 }
80
81 _observeEditorChanges() {
82 this._atom.reportObserved();
83 }
84
85 get codeMirrorOptions(): EditorConfiguration {
86 return {
87 ...codeMirrorGlobalOptions,
88 lineNumbers: this.showLineNumbers,
89 };
90 }
91
92 /**
93 * @returns `true` if there is history to undo
94 */
95 get canUndo() {
96 this._observeEditorChanges();
97 if (!this.editor) {
98 return false;
99 }
100 const { undo: undoSize } = this.editor.historySize();
101 return undoSize > 0;
102 }
103
104 undo() {
105 this.editor?.undo();
106 }
107
108 /**
109 * @returns `true` if there is history to redo
110 */
111 get canRedo() {
112 this._observeEditorChanges();
113 if (!this.editor) {
114 return false;
115 }
116 const { redo: redoSize } = this.editor.historySize();
117 return redoSize > 0;
118 }
119
120 redo() {
121 this.editor?.redo();
122 }
123
124 toggleLineNumbers() {
125 this.showLineNumbers = !this.showLineNumbers;
126 }
127}
diff --git a/language-web/src/main/js/index.jsx b/language-web/src/main/js/index.tsx
index d73ffcdd..f59b40a9 100644
--- a/language-web/src/main/js/index.jsx
+++ b/language-web/src/main/js/index.tsx
@@ -1,11 +1,11 @@
1import { CacheProvider } from "@emotion/react"; 1import { CacheProvider } from "@emotion/react";
2import React from 'react'; 2import React from 'react';
3import { render } from 'react-dom'; 3import { render } from 'react-dom';
4import CssBaseline from '@material-ui/core/CssBaseline';
4import { ThemeProvider, createTheme } from '@material-ui/core/styles'; 5import { ThemeProvider, createTheme } from '@material-ui/core/styles';
5import { getCache } from "tss-react/cache"; 6import { getCache } from "tss-react/cache";
6 7
7import App from './App'; 8import App from './App';
8import CssBaseline from '@material-ui/core/CssBaseline';
9import RootStore, { RootStoreProvider } from './RootStore'; 9import RootStore, { RootStoreProvider } from './RootStore';
10 10
11import '../css/index.scss'; 11import '../css/index.scss';
@@ -74,6 +74,6 @@ const app = (
74 </RootStoreProvider> 74 </RootStoreProvider>
75 </ThemeProvider> 75 </ThemeProvider>
76 </CacheProvider> 76 </CacheProvider>
77) 77);
78 78
79render(app, document.getElementById('app')); 79render(app, document.getElementById('app'));
diff --git a/language-web/src/main/js/makeStyles.js b/language-web/src/main/js/makeStyles.ts
index 1dee6c1f..1dee6c1f 100644
--- a/language-web/src/main/js/makeStyles.js
+++ b/language-web/src/main/js/makeStyles.ts
diff --git a/language-web/src/main/js/xtext/xtext-codemirror.d.ts b/language-web/src/main/js/xtext/xtext-codemirror.d.ts
new file mode 100644
index 00000000..fff850b8
--- /dev/null
+++ b/language-web/src/main/js/xtext/xtext-codemirror.d.ts
@@ -0,0 +1,43 @@
1import { Editor } from 'codemirror';
2
3export function createEditor(options: IXtextOptions): IXtextCodeMirrorEditor;
4
5export function createServices(editor: Editor, options: IXtextOptions): IXtextServices;
6
7export function removeServices(editor: Editor): void;
8
9export interface IXtextOptions {
10 baseUrl?: string;
11 contentType?: string;
12 dirtyElement?: string | Element;
13 dirtyStatusClass?: string;
14 document?: Document;
15 enableContentAssistService?: boolean;
16 enableCors?: boolean;
17 enableFormattingAction?: boolean;
18 enableFormattingService?: boolean;
19 enableGeneratorService?: boolean;
20 enableHighlightingService?: boolean;
21 enableOccurrencesService?: boolean;
22 enableSaveAction?: boolean;
23 enableValidationService?: boolean;
24 loadFromServer?: boolean;
25 mode?: string;
26 parent?: string | Element;
27 parentClass?: string;
28 resourceId?: string;
29 selectionUpdateDelay?: number;
30 sendFullText?: boolean;
31 serviceUrl?: string;
32 showErrorDialogs?: boolean;
33 syntaxDefinition?: string;
34 textUpdateDelay?: number;
35 xtextLang?: string;
36}
37
38export interface IXtextCodeMirrorEditor extends Editor {
39 xtextServices: IXtextServices;
40}
41
42export interface IXtextServices {
43}