@otjs/monaco
Version:
Plain Text Editor Adapter for Monaco Editor.
243 lines (230 loc) • 9.38 kB
TypeScript
import { EditorAdapterEvent } from '@otjs/plaintext-editor';
import { Emitter } from 'mitt';
import { Handler } from 'mitt';
import { ICursor } from '@otjs/plaintext-editor';
import { IEditorAdapter } from '@otjs/plaintext-editor';
import { IPlainTextOperation } from '@otjs/plaintext';
import { ITextOperation } from '@otjs/plaintext';
import * as monaco from 'monaco-editor';
import { TEditorAdapterCursorParams } from '@otjs/plaintext-editor';
import { TEditorAdapterEventArgs } from '@otjs/plaintext-editor';
/**
* @internal
* Abstract Base Class for Event Emitter - This must be extended by Classes with a requirement to fulfill IEventEmitter interface.
*/
export declare abstract class EventEmitter<
Event extends string,
EventArgs extends Record<Event, any>,
> implements IEventEmitter<Event, EventArgs>
{
/** Event Emitter Instance that dispatces event given in the Map */
protected readonly _emitter: Emitter<EventArgs> = mitt();
on<Key extends keyof EventArgs>(
event: Key,
listener: Handler<EventArgs[Key]>,
): void {
this._emitter.on(event, listener);
}
off<Key extends keyof EventArgs>(
event: Key,
listener?: Handler<EventArgs[Key]>,
): void {
this._emitter.off(event, listener);
}
/** Trigger an event with optional payload */
protected _trigger<Key extends keyof EventArgs>(
event: Key,
payload: EventArgs[Key],
): void {
this._emitter.emit(event, payload);
}
}
/**
* Copyright © 2021 Progyan Bhattacharya
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* See LICENSE file in the root directory for more details.
*/
/**
* @internal
* Disposable Interface - Classes with side-effect should extend this interface to add additional cleanup rules.
* Applicable to the Interfaces/Objects that requires cleanup after usage.
*/
export declare interface IDisposable {
/**
* Cleanup Method.
*/
dispose(): void;
}
/**
* @internal
* Interface for Collection Class for Disposable instances to handle cross-cutting concerns of cleanup.
*/
export declare interface IDisposableCollection {
/** Returns true if all Disposables are Disposed */
disposed: boolean;
/** Pushes Disposables to the collection */
push(...disposables: IDisposable[]): void;
/** Disposes all Disposables in the collection and resets the collection */
dispose(): void;
}
/**
* @internal
* Event Emitter Interface - Generic Interface that handles raising Event to outside world.
*/
export declare interface IEventEmitter<
Event extends string,
EventArgs extends Record<Event, any>,
> {
/**
* Adds event listener.
* @param event - Event name.
* @param listener - Event handler callback.
*/
on<Key extends keyof EventArgs>(
event: Key,
listener: Handler<EventArgs[Key]>,
): void;
/**
* Removes event listener.
* @param event - Event name.
* @param listener - Event handler callback (optional).
*/
off<Key extends keyof EventArgs>(
event: Key,
listener?: Handler<EventArgs[Key]>,
): void;
}
/**
* @internal
* Augment ITextModel interface to allow direct access to undo and redo methods.
*/
export declare interface ITextModelWithUndoRedo extends monaco.editor.ITextModel {
/** Native Undo Handler for Monaco */
undo: Handler<void> | null;
/** Native Redo Handler for Monaco */
redo: Handler<void> | null;
}
/**
* @public
* Create Editor Adapter for Plain Text Editor using Monaco as Editor.
* @param constructorOptions - A Configuration Object consisting Monaco Editor Instance.
*/
export declare class MonacoAdapter extends EventEmitter<EditorAdapterEvent, TEditorAdapterEventArgs> implements IEditorAdapter {
protected readonly _toDispose: IDisposableCollection;
protected _announcementDuration: number;
protected _bindEvents: boolean;
protected _initiated: boolean;
protected _ignoreChanges: boolean;
protected _undoCallback: Handler<void> | null;
protected _redoCallback: Handler<void> | null;
protected _originalUndo: Handler<void> | null;
protected _originalRedo: Handler<void> | null;
protected _lastDocLines: string[];
protected _lastCursorRange: monaco.Selection | null;
protected _monaco: monaco.editor.IStandaloneCodeEditor;
constructor({ editor, announcementDuration, bindEvents, }: TMonacoAdapterConstructionOptions);
get events(): boolean;
set events(bindEvents: boolean);
/** Bind event handlers to Monaco instance */
protected _init(): void;
/** Dispose event handlers to Monaco instance */
protected _teardown(): void;
registerUndo(undoCallback: Handler<void>): void;
registerRedo(redoCallback: Handler<void>): void;
deregisterUndo(undoCallback?: Handler<void>): void;
deregisterRedo(redoCallback?: Handler<void>): void;
getCursor(): ICursor | null;
setCursor(cursor: ICursor): void;
setOtherCursor({ clientId, cursor, userName, userColor: cursorColor, }: TEditorAdapterCursorParams): IDisposable;
getText(): string;
setText(text: string): void;
setInitiated(): void;
applyOperation(operation: IPlainTextOperation): void;
invertOperation(operation: IPlainTextOperation): IPlainTextOperation;
dispose(): void;
/**
* Returns Text Model associated with editor instance.
*/
protected _getModel(): ITextModelWithUndoRedo | void;
/**
* Apply Edit Operations onto Monaco Model.
* @param changes - Set of Monaco Model Content Changes.
*/
protected _applyEdits(changes: monaco.editor.IIdentifiedSingleEditOperation[]): void;
/**
* Handles `Blur` event in Monaco editor.
*/
protected _onBlur(): void;
/**
* Handles `Focus` event in Monaco editor.
*/
protected _onFocus(): void;
/**
* Handles `ModelChange` event in Monaco editor.
*/
protected _onModelChange(_ev: monaco.editor.IModelChangedEvent): void;
/**
* Handles `ModelContentChange` event in Monaco editor.
*/
protected _onChange(ev: Partial<monaco.editor.IModelContentChangedEvent>): void;
/**
* Handles `CursorPositionChange` event in Monaco editor.
*/
protected _onCursorActivity(ev: monaco.editor.ICursorPositionChangedEvent): void;
/**
* Returns content from editor model for given range or whole content.
* @param range - Range of the editor to pick content from (optional).
*/
protected _getPreviousContentInRange(range?: monaco.Range): string;
/**
* Transform Monaco Content changes into pair of Text Operation that are inverse of each other.
* @param changes - Set of Changes from Monaco Model Content Change Event.
* @param contentLength - Current Size of the Content string.
*/
protected _operationFromMonacoChange(changes: monaco.editor.IModelContentChange[], contentLength: number): [operation: IPlainTextOperation, inverse: IPlainTextOperation];
/**
* Transforms Individual Text Operations into Edit Operations for Monaco.
* @param ops - List of Individual Text Operations.
* @param model - Monaco Text Model.
*/
protected _transformOpsIntoMonacoChanges(ops: IterableIterator<[index: number, operation: ITextOperation]>, model: monaco.editor.ITextModel): monaco.editor.IIdentifiedSingleEditOperation[];
/**
* Applies Edit Operations into Monaco editor model.
* @param changes - List of Edit Operations.
*/
protected _applyChangesToMonaco(changes: monaco.editor.IIdentifiedSingleEditOperation[]): void;
}
/**
* @public
* Constructor Options to instantiate a Monaco Adapter
*/
export declare type TMonacoAdapterConstructionOptions = {
/** Monaco Editor Instance. */
editor: monaco.editor.IStandaloneCodeEditor;
/**
* Duration (in ms) of User Name Announcement beside Cursor.
* Infinity means it will never be hidden. (optional, defaults to 1000)
*/
announcementDuration?: number;
/** Bind Event Handlers to Monaco (optional, defaults to `false`). */
bindEvents?: boolean;
};
export { }