aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/editor/EditorArea.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src/main/js/editor/EditorArea.tsx')
-rw-r--r--language-web/src/main/js/editor/EditorArea.tsx49
1 files changed, 35 insertions, 14 deletions
diff --git a/language-web/src/main/js/editor/EditorArea.tsx b/language-web/src/main/js/editor/EditorArea.tsx
index 58d65184..460005ce 100644
--- a/language-web/src/main/js/editor/EditorArea.tsx
+++ b/language-web/src/main/js/editor/EditorArea.tsx
@@ -1,8 +1,14 @@
1import { Command, EditorView } from '@codemirror/view'; 1import { Command, EditorView } from '@codemirror/view';
2import { closeSearchPanel, openSearchPanel } from '@codemirror/search'; 2import { closeSearchPanel, openSearchPanel } from '@codemirror/search';
3import { closeLintPanel, openLintPanel } from '@codemirror/lint'; 3import { closeLintPanel, openLintPanel } from '@codemirror/lint';
4
4import { observer } from 'mobx-react-lite'; 5import { observer } from 'mobx-react-lite';
5import React, { useEffect, useRef, useState } from 'react'; 6import React, {
7 useCallback,
8 useEffect,
9 useRef,
10 useState,
11} from 'react';
6 12
7import { EditorParent } from './EditorParent'; 13import { EditorParent } from './EditorParent';
8import { getLogger } from '../logging'; 14import { getLogger } from '../logging';
@@ -11,36 +17,49 @@ import { useRootStore } from '../RootStore';
11const log = getLogger('EditorArea'); 17const log = getLogger('EditorArea');
12 18
13function usePanel( 19function usePanel(
14 label: string, 20 panelId: string,
15 stateToSet: boolean, 21 stateToSet: boolean,
16 editorView: EditorView | null, 22 editorView: EditorView | null,
17 openCommand: Command, 23 openCommand: Command,
18 closeCommand: Command, 24 closeCommand: Command,
25 closeCallback: () => void,
19) { 26) {
20 const [cachedViewState, setCachedViewState] = useState<boolean>(false); 27 const [cachedViewState, setCachedViewState] = useState<boolean>(false);
21 useEffect(() => { 28 useEffect(() => {
22 if (editorView === null || cachedViewState === stateToSet) { 29 if (editorView === null || cachedViewState === stateToSet) {
23 return; 30 return;
24 } 31 }
25 const success = stateToSet ? openCommand(editorView) : closeCommand(editorView); 32 if (stateToSet) {
26 if (!success) { 33 openCommand(editorView);
27 log.error( 34 const buttonQuery = `.cm-${panelId}.cm-panel button[name="close"]`;
28 'Failed to synchronize', 35 const closeButton = editorView.dom.querySelector(buttonQuery);
29 label, 36 if (closeButton) {
30 'panel state - store state:', 37 log.debug('Addig close button callback to', panelId, 'panel');
31 cachedViewState, 38 // We must remove the event listener added by CodeMirror from the button
32 'view state:', 39 // that dispatches a transaction without going through `EditorStorre`.
33 stateToSet, 40 // Cloning a DOM node removes event listeners,
34 ); 41 // see https://stackoverflow.com/a/9251864
42 const closeButtonWithoutListeners = closeButton.cloneNode(true);
43 closeButtonWithoutListeners.addEventListener('click', (event) => {
44 closeCallback();
45 event.preventDefault();
46 });
47 closeButton.replaceWith(closeButtonWithoutListeners);
48 } else {
49 log.error('Opened', panelId, 'panel has no close button');
50 }
51 } else {
52 closeCommand(editorView);
35 } 53 }
36 setCachedViewState(stateToSet); 54 setCachedViewState(stateToSet);
37 }, [ 55 }, [
38 stateToSet, 56 stateToSet,
39 editorView, 57 editorView,
40 cachedViewState, 58 cachedViewState,
41 label, 59 panelId,
42 openCommand, 60 openCommand,
43 closeCommand, 61 closeCommand,
62 closeCallback,
44 ]); 63 ]);
45 return setCachedViewState; 64 return setCachedViewState;
46} 65}
@@ -56,14 +75,16 @@ export const EditorArea = observer(() => {
56 editorViewState, 75 editorViewState,
57 openSearchPanel, 76 openSearchPanel,
58 closeSearchPanel, 77 closeSearchPanel,
78 useCallback(() => editorStore.setSearchPanelOpen(false), [editorStore]),
59 ); 79 );
60 80
61 const setLintPanelOpen = usePanel( 81 const setLintPanelOpen = usePanel(
62 'lint', 82 'panel-lint',
63 editorStore.showLintPanel, 83 editorStore.showLintPanel,
64 editorViewState, 84 editorViewState,
65 openLintPanel, 85 openLintPanel,
66 closeLintPanel, 86 closeLintPanel,
87 useCallback(() => editorStore.setLintPanelOpen(false), [editorStore]),
67 ); 88 );
68 89
69 useEffect(() => { 90 useEffect(() => {