diff --git a/src/controller/__tests__/editor.test.ts b/src/controller/__tests__/editor.test.ts new file mode 100644 index 000000000..42dc1e35a --- /dev/null +++ b/src/controller/__tests__/editor.test.ts @@ -0,0 +1,83 @@ +import 'reflect-metadata'; +import { container } from 'tsyringe'; +import { EditorService, StatusBarService, BuiltinService } from 'mo/services'; +import { EditorController } from '../editor'; +import { editor as MonacoEditor, IDisposable, Position } from 'mo/monaco'; + +const editorController = container.resolve(EditorController); +const editorService = container.resolve(EditorService); +const statusBarService = container.resolve(StatusBarService); +const builtinService = container.resolve(BuiltinService); + +describe('The ediotr controller', () => { + test('The initEditorEvents method', () => { + const editorInstance = {} as MonacoEditor.IStandaloneCodeEditor; + const position = { lineNumber: 1, column: 1 } as Position; + let contentListener; + let focusListener; + let cursorListener; + let blurListener; + + editorInstance.onDidChangeModelContent = jest.fn((listener) => { + contentListener = listener; + return {} as IDisposable; + }); + editorInstance.onDidFocusEditorText = jest.fn((listener) => { + focusListener = listener; + return {} as IDisposable; + }); + editorInstance.onDidChangeCursorSelection = jest.fn((listener) => { + cursorListener = listener; + return {} as IDisposable; + }); + editorInstance.onDidBlurEditorText = jest.fn((listener) => { + blurListener = listener; + return {} as IDisposable; + }); + editorInstance.getPosition = jest.fn(() => position); + + const testTab = { + id: 'testTab', + name: 'testTab', + }; + editorService.open(testTab); + const { current } = editorService.getState(); + editorController.initEditorEvents(editorInstance, current?.id!); + + // focus + focusListener?.(); + expect(editorService.getState().current?.tab?.id).toEqual(testTab.id); + + // change content + editorInstance.getModel = jest.fn(() => { + return { getValue: () => 'newValue' } as MonacoEditor.ITextModel; + }); + contentListener?.(); + expect(editorService.getState().current?.tab?.data?.value).toEqual( + 'newValue' + ); + + // change cursor + const { STATUS_EDITOR_INFO } = builtinService.getModules(); + statusBarService.setState({ rightItems: [STATUS_EDITOR_INFO] }); + cursorListener?.(); + expect(statusBarService.getState().rightItems[0]?.data).toEqual({ + ln: 1, + col: 1, + }); + + // blur + const viewState = { + viewState: { scrollTop: 10 }, + } as MonacoEditor.ICodeEditorViewState; + editorInstance.saveViewState = jest.fn(() => viewState); + blurListener?.(); + expect( + editorController.getViewState(current?.tab?.id?.toString()!) + ).toEqual(viewState); + + // reset services + statusBarService.reset(); + editorService.setState({ current: null, groups: [] }); + }); +}); diff --git a/src/controller/editor.tsx b/src/controller/editor.tsx index 703a88f4a..edf375436 100644 --- a/src/controller/editor.tsx +++ b/src/controller/editor.tsx @@ -46,6 +46,11 @@ export interface IEditorController extends Partial { onClickActions: (action: IEditorActionsProps) => void; onUpdateEditorIns?: (editorInstance: any, groupId: UniqueId) => void; onPaneSizeChange?: (newSize: number[]) => void; + initEditorEvents?: ( + editorInstance: MonacoEditor.IStandaloneCodeEditor, + groupId: UniqueId + ) => void; + getViewState?: (id: UniqueId) => MonacoEditor.ICodeEditorViewState; } @singleton() export class EditorController extends Controller implements IEditorController { @@ -239,7 +244,7 @@ export class EditorController extends Controller implements IEditorController { this.layoutService.setGroupSplitSize(newSize); }; - private initEditorEvents( + public initEditorEvents( editorInstance: MonacoEditor.IStandaloneCodeEditor, groupId: UniqueId ) { @@ -273,8 +278,21 @@ export class EditorController extends Controller implements IEditorController { editorInstance.onDidChangeCursorSelection(() => { this.updateEditorLineColumnInfo(editorInstance); }); + + editorInstance.onDidBlurEditorText(() => { + const { current } = this.editorService.getState(); + const tab = current?.tab; + if (tab?.id) { + const viewState = editorInstance?.saveViewState(); + this.editorStates.set(tab.id?.toString(), viewState); + } + }); } + public getViewState = (id: UniqueId) => { + return this.editorStates.get(id); + }; + /** * Called when Editor props changed */