|
@@ -5,22 +5,18 @@ import {
|
|
|
IDisposable
|
|
|
} from 'phosphor/lib/core/disposable';
|
|
|
|
|
|
-import {
|
|
|
- Message
|
|
|
-} from 'phosphor/lib/core/messaging';
|
|
|
-
|
|
|
import {
|
|
|
ISignal, clearSignalData, defineSignal
|
|
|
} from 'phosphor/lib/core/signaling';
|
|
|
|
|
|
-import {
|
|
|
- Widget
|
|
|
-} from 'phosphor/lib/ui/widget';
|
|
|
-
|
|
|
import {
|
|
|
IChangedArgs
|
|
|
} from '../common/interfaces';
|
|
|
|
|
|
+import {
|
|
|
+ IObservableString
|
|
|
+} from '../common/observablestring';
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* A namespace for code editors.
|
|
@@ -40,12 +36,12 @@ namespace CodeEditor {
|
|
|
/**
|
|
|
* The cursor line number.
|
|
|
*/
|
|
|
- line: number;
|
|
|
+ readonly line: number;
|
|
|
|
|
|
/**
|
|
|
* The cursor column number.
|
|
|
*/
|
|
|
- column: number;
|
|
|
+ readonly column: number;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -54,14 +50,14 @@ namespace CodeEditor {
|
|
|
export
|
|
|
interface IDimension {
|
|
|
/**
|
|
|
- * The width of an element in pixels.
|
|
|
+ * The width of an element in pixels.
|
|
|
*/
|
|
|
- width: number;
|
|
|
+ readonly width: number;
|
|
|
|
|
|
/**
|
|
|
* The height of an element in pixels.
|
|
|
*/
|
|
|
- height: number;
|
|
|
+ readonly height: number;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -102,7 +98,7 @@ namespace CodeEditor {
|
|
|
* If this position is greater than [end] then the range is considered
|
|
|
* to be backward.
|
|
|
*/
|
|
|
- start: IPosition;
|
|
|
+ readonly start: IPosition;
|
|
|
|
|
|
/**
|
|
|
* The position of the last character in the current range.
|
|
@@ -111,7 +107,7 @@ namespace CodeEditor {
|
|
|
* If this position is less than [start] then the range is considered
|
|
|
* to be backward.
|
|
|
*/
|
|
|
- end: IPosition;
|
|
|
+ readonly end: IPosition;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -138,24 +134,24 @@ namespace CodeEditor {
|
|
|
/**
|
|
|
* The uuid of the text selection owner.
|
|
|
*/
|
|
|
- uuid: string;
|
|
|
+ readonly uuid: string;
|
|
|
|
|
|
/**
|
|
|
* The style of this selection.
|
|
|
*/
|
|
|
- style?: ISelectionStyle;
|
|
|
+ readonly style?: ISelectionStyle;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* An interface to manage selections by selection owners.
|
|
|
- *
|
|
|
+ *
|
|
|
* #### Definitions
|
|
|
* - a user code that has an associated uuid is called a selection owner, see `CodeEditor.ISelectionOwner`
|
|
|
* - a selection belongs to a selection owner only if it is associated with the owner by an uuid, see `CodeEditor.ITextSelection`
|
|
|
- *
|
|
|
+ *
|
|
|
* #### Read access
|
|
|
* - any user code can observe any selection
|
|
|
- *
|
|
|
+ *
|
|
|
* #### Write access
|
|
|
* - if a user code is a selection owner then:
|
|
|
* - it can change selections beloging to it
|
|
@@ -176,12 +172,20 @@ namespace CodeEditor {
|
|
|
readonly uuids: string[];
|
|
|
|
|
|
/**
|
|
|
- * Gets the selections for all the cursors in ascending order.
|
|
|
+ * Gets the selections for all the cursors in ascending order.
|
|
|
+ *
|
|
|
+ * @param uuid - The id of the selection owner.
|
|
|
+ *
|
|
|
+ * @returns A new array of text selections.
|
|
|
*/
|
|
|
getSelections(uuid: string): ITextSelection[];
|
|
|
|
|
|
/**
|
|
|
* Sets the selections for all the cursors.
|
|
|
+ *
|
|
|
+ * @param uuid - The id of the selection owner.
|
|
|
+ *
|
|
|
+ * @param newSelections - The replacement text selections.
|
|
|
*/
|
|
|
setSelections(uuid: string, newSelections: ITextSelection[]): void;
|
|
|
}
|
|
@@ -215,8 +219,7 @@ namespace CodeEditor {
|
|
|
* Default implementation of `ISelections`.
|
|
|
*/
|
|
|
export
|
|
|
- class Selections implements ISelections {
|
|
|
-
|
|
|
+ class Selections implements ISelections, IDisposable {
|
|
|
/**
|
|
|
* A signal emitted when selections changes.
|
|
|
*/
|
|
@@ -230,7 +233,30 @@ namespace CodeEditor {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Gets the selections for all the cursors in ascending order.
|
|
|
+ * Test whether the selections are disposed.
|
|
|
+ */
|
|
|
+ get isDisposed(): boolean {
|
|
|
+ return this._isDisposed;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Dispose of the resources used by the selections.
|
|
|
+ */
|
|
|
+ dispose(): void {
|
|
|
+ if (this.isDisposed) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this._selections = {};
|
|
|
+ this._isDisposed = true;
|
|
|
+ clearSignalData(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Gets the selections for all the cursors in ascending order.
|
|
|
+ *
|
|
|
+ * @param uuid - The id of the selection owner.
|
|
|
+ *
|
|
|
+ * @returns A new array of text selections.
|
|
|
*/
|
|
|
getSelections(uuid: string): ITextSelection[] {
|
|
|
const selections = this._selections[uuid];
|
|
@@ -239,6 +265,10 @@ namespace CodeEditor {
|
|
|
|
|
|
/**
|
|
|
* Sets the selections for all the cursors.
|
|
|
+ *
|
|
|
+ * @param uuid - The id of the selection owner.
|
|
|
+ *
|
|
|
+ * @param newSelections - The replacement text selections.
|
|
|
*/
|
|
|
setSelections(uuid: string, newSelections: ITextSelection[]): void {
|
|
|
const oldSelections = this.getSelections(uuid);
|
|
@@ -268,11 +298,15 @@ namespace CodeEditor {
|
|
|
delete this._selections[uuid];
|
|
|
}
|
|
|
|
|
|
+ private _isDisposed = false;
|
|
|
private _selections: {
|
|
|
[key: string]: ITextSelection[] | null
|
|
|
} = {};
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Define the signals for the `Selections` class.
|
|
|
+ */
|
|
|
defineSignal(Selections.prototype, 'changed');
|
|
|
|
|
|
/**
|
|
@@ -280,11 +314,6 @@ namespace CodeEditor {
|
|
|
*/
|
|
|
export
|
|
|
interface IModel extends IDisposable {
|
|
|
- /**
|
|
|
- * A signal emitted when the value changes.
|
|
|
- */
|
|
|
- valueChanged: ISignal<IModel, IChangedArgs<string>>;
|
|
|
-
|
|
|
/**
|
|
|
* A signal emitted when a property changes.
|
|
|
*/
|
|
@@ -293,11 +322,11 @@ namespace CodeEditor {
|
|
|
/**
|
|
|
* The text stored in the model.
|
|
|
*/
|
|
|
- value: string; // TODO: this should be an iobservablestring.
|
|
|
+ readonly value: IObservableString;
|
|
|
|
|
|
/**
|
|
|
* A mime type of the model.
|
|
|
- *
|
|
|
+ *
|
|
|
* #### Notes
|
|
|
* It is never `null`, the default mime type is `text/plain`.
|
|
|
*/
|
|
@@ -315,16 +344,28 @@ namespace CodeEditor {
|
|
|
|
|
|
/**
|
|
|
* Returns the content for the given line number.
|
|
|
+ *
|
|
|
+ * @param line - The line of interest.
|
|
|
+ *
|
|
|
+ * @returns The value of the line.
|
|
|
*/
|
|
|
getLine(line: number): string;
|
|
|
|
|
|
/**
|
|
|
* Find an offset for the given position.
|
|
|
+ *
|
|
|
+ * @param position - The position of interest.
|
|
|
+ *
|
|
|
+ * @returns The offset at the position.
|
|
|
*/
|
|
|
getOffsetAt(position: IPosition): number;
|
|
|
|
|
|
/**
|
|
|
* Find a position for the given offset.
|
|
|
+ *
|
|
|
+ * @param offset - The offset of interest.
|
|
|
+ *
|
|
|
+ * @returns The position at the offset.
|
|
|
*/
|
|
|
getPositionAt(offset: number): IPosition;
|
|
|
|
|
@@ -353,37 +394,58 @@ namespace CodeEditor {
|
|
|
* The uuid of this selection owner.
|
|
|
*/
|
|
|
readonly uuid: string;
|
|
|
+
|
|
|
/**
|
|
|
* Returns the primary position of the cursor, never `null`.
|
|
|
*/
|
|
|
getCursorPosition(): IPosition;
|
|
|
+
|
|
|
/**
|
|
|
- * Set the primary position of the cursor. This will remove any secondary cursors.
|
|
|
+ * Set the primary position of the cursor.
|
|
|
+ *
|
|
|
+ * @param position - The new primary position.
|
|
|
+ *
|
|
|
+ * #### Notes
|
|
|
+ * This will remove any secondary cursors.
|
|
|
*/
|
|
|
setCursorPosition(position: IPosition): void;
|
|
|
+
|
|
|
/**
|
|
|
* Returns the primary selection, never `null`.
|
|
|
*/
|
|
|
getSelection(): IRange;
|
|
|
+
|
|
|
/**
|
|
|
- * Set the primary selection. This will remove any secondary cursors.
|
|
|
+ * Set the primary selection.
|
|
|
+ *
|
|
|
+ * @param selection - The desired selection range.
|
|
|
+ *
|
|
|
+ * #### Notes
|
|
|
+ * This will remove any secondary cursors.
|
|
|
*/
|
|
|
setSelection(selection: IRange): void;
|
|
|
+
|
|
|
/**
|
|
|
* Gets the selections for all the cursors, never `null` or empty.
|
|
|
*/
|
|
|
getSelections(): IRange[];
|
|
|
+
|
|
|
/**
|
|
|
* Sets the selections for all the cursors.
|
|
|
+ *
|
|
|
+ * @param selections - The new selections.
|
|
|
+ *
|
|
|
+ * #### Notes
|
|
|
* Cursors will be removed or added, as necessary.
|
|
|
- * Passing an empty array resets a cursor position to the start of a document.
|
|
|
+ * Passing an empty array resets a cursor position to the start of a
|
|
|
+ * document.
|
|
|
*/
|
|
|
setSelections(selections: IRange[]): void;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* A keydown handler type.
|
|
|
- *
|
|
|
+ *
|
|
|
* #### Notes
|
|
|
* Return `true` to prevent the default handling of the event by the
|
|
|
* editor.
|
|
@@ -442,30 +504,40 @@ namespace CodeEditor {
|
|
|
hasFocus(): boolean;
|
|
|
|
|
|
/**
|
|
|
- * Repaint editor.
|
|
|
+ * Repaint the editor.
|
|
|
*/
|
|
|
refresh(): void;
|
|
|
|
|
|
/**
|
|
|
- * Sets the size of the editor.
|
|
|
- *
|
|
|
+ * Set the size of the editor.
|
|
|
+ *
|
|
|
+ * @param size - The desired size.
|
|
|
+ *
|
|
|
* #### Notes
|
|
|
- * Sets null if the size is unknown.
|
|
|
+ * Use `null` if the size is unknown.
|
|
|
*/
|
|
|
setSize(size: IDimension | null): void;
|
|
|
|
|
|
/**
|
|
|
* Reveals the given position in the editor.
|
|
|
+ *
|
|
|
+ * @param position - The desired position to reveal.
|
|
|
*/
|
|
|
revealPosition(position: IPosition): void;
|
|
|
|
|
|
/**
|
|
|
* Reveals the given selection in the editor.
|
|
|
+ *
|
|
|
+ * @param position - The desired selection to reveal.
|
|
|
*/
|
|
|
revealSelection(selection: IRange): void;
|
|
|
|
|
|
/**
|
|
|
* Get the window coordinates given a cursor position.
|
|
|
+ *
|
|
|
+ * @param position - The desired position.
|
|
|
+ *
|
|
|
+ * @returns The coordinates of the position.
|
|
|
*/
|
|
|
getCoordinate(position: IPosition): ICoordinate;
|
|
|
}
|
|
@@ -476,17 +548,17 @@ namespace CodeEditor {
|
|
|
export
|
|
|
interface IOptions {
|
|
|
/**
|
|
|
- * Whether line numbers should be displayed. Defaults to false.
|
|
|
+ * Whether line numbers should be displayed. Defaults to `false`.
|
|
|
*/
|
|
|
lineNumbers?: boolean;
|
|
|
|
|
|
/**
|
|
|
- * Set to false for horizontal scrolling. Defaults to true.
|
|
|
+ * Set to false for horizontal scrolling. Defaults to `true`.
|
|
|
*/
|
|
|
wordWrap?: boolean;
|
|
|
|
|
|
/**
|
|
|
- * Whether the editor is read-only. Defaults to false.
|
|
|
+ * Whether the editor is read-only. Defaults to `false`.
|
|
|
*/
|
|
|
readOnly?: boolean;
|
|
|
|
|
@@ -495,358 +567,4 @@ namespace CodeEditor {
|
|
|
*/
|
|
|
extra?: { [key: string]: any };
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * The default implementation of the code editor model.
|
|
|
- */
|
|
|
- export
|
|
|
- class Model implements IModel {
|
|
|
- /**
|
|
|
- * A signal emitted when a content of the model changed.
|
|
|
- */
|
|
|
- valueChanged: ISignal<this, IChangedArgs<string>>;
|
|
|
-
|
|
|
- /**
|
|
|
- * A signal emitted when a mimetype changes.
|
|
|
- */
|
|
|
- mimeTypeChanged: ISignal<this, IChangedArgs<string>>;
|
|
|
-
|
|
|
- readonly selections = new Selections();
|
|
|
-
|
|
|
- /**
|
|
|
- * Whether the model is disposed.
|
|
|
- */
|
|
|
- get isDisposed(): boolean {
|
|
|
- return this._isDisposed;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Dipose of the resources used by the model.
|
|
|
- */
|
|
|
- dispose(): void {
|
|
|
- if (this._isDisposed) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this._isDisposed = true;
|
|
|
- clearSignalData(this);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * A mime type of the model.
|
|
|
- */
|
|
|
- get mimeType(): string {
|
|
|
- return this._mimetype;
|
|
|
- }
|
|
|
- set mimeType(newValue: string) {
|
|
|
- let oldValue = this._mimetype;
|
|
|
- if (oldValue === newValue) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this._mimetype = newValue;
|
|
|
- this.mimeTypeChanged.emit({
|
|
|
- name: 'mimeType',
|
|
|
- oldValue,
|
|
|
- newValue
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * The text stored in the model.
|
|
|
- */
|
|
|
- get value(): string {
|
|
|
- return this._value;
|
|
|
- }
|
|
|
- set value(newValue: string) {
|
|
|
- let oldValue = this._value;
|
|
|
- if (oldValue === newValue) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this._value = newValue;
|
|
|
- this.valueChanged.emit({
|
|
|
- name: 'value',
|
|
|
- oldValue,
|
|
|
- newValue
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the number of lines in the model.
|
|
|
- */
|
|
|
- get lineCount(): number {
|
|
|
- return this._value.split('\n').length;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the content for the given line number.
|
|
|
- */
|
|
|
- getLine(line: number): string {
|
|
|
- return this._value.split('\n')[line];
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Find an offset for the given position.
|
|
|
- */
|
|
|
- getOffsetAt(position: CodeEditor.IPosition): number {
|
|
|
- let lines = this._value.split('\n');
|
|
|
- let before = lines.slice(0, position.line).join('\n').length;
|
|
|
- return before + position.column;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Find a position fot the given offset.
|
|
|
- */
|
|
|
- getPositionAt(offset: number): CodeEditor.IPosition {
|
|
|
- let text = this._value.slice(0, offset);
|
|
|
- let lines = text.split('\n');
|
|
|
- let column = lines[lines.length - 1].length;
|
|
|
- return { line: lines.length - 1, column };
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Undo one edit (if any undo events are stored).
|
|
|
- */
|
|
|
- undo(): void { /* no-op */ }
|
|
|
-
|
|
|
- /**
|
|
|
- * Redo one undone edit.
|
|
|
- */
|
|
|
- redo(): void { /* no-op */ }
|
|
|
-
|
|
|
- /**
|
|
|
- * Clear the undo history.
|
|
|
- */
|
|
|
- clearHistory(): void { /* no-op */ }
|
|
|
-
|
|
|
- private _mimetype = '';
|
|
|
- private _value = '';
|
|
|
- private _isDisposed = false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-defineSignal(CodeEditor.Model.prototype, 'valueChanged');
|
|
|
-defineSignal(CodeEditor.Model.prototype, 'mimeTypeChanged');
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * An implementation of an editor for an html text area.
|
|
|
- */
|
|
|
-class TextAreaEditor extends Widget implements CodeEditor.IEditor {
|
|
|
- readonly uuid = '1';
|
|
|
- /**
|
|
|
- * Construct a new text editor.
|
|
|
- */
|
|
|
- constructor(options: CodeEditor.IOptions, model: CodeEditor.IModel) {
|
|
|
- super({ node: document.createElement('textarea') });
|
|
|
- this._model = model;
|
|
|
- let node = this.node as HTMLTextAreaElement;
|
|
|
- node.readOnly = options.readOnly || false;
|
|
|
- node.wrap = options.wordWrap ? 'hard' : 'soft';
|
|
|
- model.selections.changed.connect(this.onModelSelectionsChanged, this);
|
|
|
- model.valueChanged.connect(this.onModelValueChanged, this);
|
|
|
- this.updateSelections();
|
|
|
- }
|
|
|
-
|
|
|
- get lineNumbers(): boolean {
|
|
|
- return false;
|
|
|
- }
|
|
|
- set lineNumbers(value: boolean) {
|
|
|
- /* no-op*/
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set to false for horizontal scrolling. Defaults to true.
|
|
|
- */
|
|
|
- get wordWrap(): boolean {
|
|
|
- return (this.node as HTMLTextAreaElement).wrap === 'hard';
|
|
|
- }
|
|
|
- set wordWrap(value: boolean) {
|
|
|
- (this.node as HTMLTextAreaElement).wrap = value ? 'hard' : 'soft';
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Whether the editor is read-only. Defaults to false.
|
|
|
- */
|
|
|
- get readOnly(): boolean {
|
|
|
- return (this.node as HTMLTextAreaElement).readOnly;
|
|
|
- }
|
|
|
- set readOnly(value: boolean) {
|
|
|
- (this.node as HTMLTextAreaElement).readOnly = value;
|
|
|
- }
|
|
|
-
|
|
|
- get model(): CodeEditor.IModel {
|
|
|
- return this._model;
|
|
|
- }
|
|
|
-
|
|
|
- get onKeyDown(): CodeEditor.KeydownHandler | null {
|
|
|
- return this._handler;
|
|
|
- }
|
|
|
- set onKeyDown(value: CodeEditor.KeydownHandler | null) {
|
|
|
- this._handler = value;
|
|
|
- }
|
|
|
-
|
|
|
- get charWidth(): number {
|
|
|
- // TODO css measurement
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- get lineHeight(): number {
|
|
|
- // TODO css measurement
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Brings browser focus to this editor text.
|
|
|
- */
|
|
|
- focus(): void {
|
|
|
- this.node.focus();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Test whether the editor has keyboard focus.
|
|
|
- */
|
|
|
- hasFocus(): boolean {
|
|
|
- return document.activeElement === this.node;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Repaint the editor.
|
|
|
- */
|
|
|
- refresh(): void { /* no-op */ }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the size of the editor in pixels.
|
|
|
- */
|
|
|
- setSize(dimension: CodeEditor.IDimension | null): void {
|
|
|
- // override css here
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Scroll the given cursor position into view.
|
|
|
- */
|
|
|
- revealPosition(pos: CodeEditor.IPosition): void {
|
|
|
- // set node scroll position here.
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Scroll the given cursor position into view.
|
|
|
- */
|
|
|
- revealSelection(selection: CodeEditor.IRange): void {
|
|
|
- // set node scroll position here.
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the window coordinates given a cursor position.
|
|
|
- */
|
|
|
- getCoordinate(position: CodeEditor.IPosition): CodeEditor.ICoordinate {
|
|
|
- // more css measurements required
|
|
|
- return void 0;
|
|
|
- }
|
|
|
-
|
|
|
- handleEvent(event: Event): void {
|
|
|
- switch (event.type) {
|
|
|
- case 'keydown':
|
|
|
- this._evtKeydown(event as KeyboardEvent);
|
|
|
- break;
|
|
|
- case 'mouseup':
|
|
|
- this._evtMouseUp(event as MouseEvent);
|
|
|
- break;
|
|
|
- case 'input':
|
|
|
- this._evtInput(event);
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected onAfterAttach(msg: Message): void {
|
|
|
- super.onAfterAttach(msg);
|
|
|
- this.node.addEventListener('keydown', this);
|
|
|
- this.node.addEventListener('mouseup', this);
|
|
|
- this.node.addEventListener('input', this);
|
|
|
- }
|
|
|
-
|
|
|
- protected onBeforeDetach(msg: Message): void {
|
|
|
- this.node.removeEventListener('keydown', this);
|
|
|
- this.node.removeEventListener('mouseup', this);
|
|
|
- this.node.removeEventListener('input', this);
|
|
|
- }
|
|
|
-
|
|
|
- protected onModelValueChanged(sender: CodeEditor.IModel, args: IChangedArgs<string>): void {
|
|
|
- if (this._changeGuard) {
|
|
|
- return;
|
|
|
- }
|
|
|
- (this.node as HTMLTextAreaElement).value = args.newValue;
|
|
|
- }
|
|
|
-
|
|
|
- setCursorPosition(position: CodeEditor.IPosition): void {
|
|
|
- this.setSelection({
|
|
|
- start: position,
|
|
|
- end: position
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- getCursorPosition(): CodeEditor.IPosition {
|
|
|
- return this.getSelection().start;
|
|
|
- }
|
|
|
-
|
|
|
- setSelection(selection: CodeEditor.IRange | null): void {
|
|
|
- const node = this.node as HTMLTextAreaElement;
|
|
|
- if (selection) {
|
|
|
- const start = this.model.getOffsetAt(selection.start);
|
|
|
- const end = this.model.getOffsetAt(selection.end);
|
|
|
- node.setSelectionRange(start, end);
|
|
|
- } else {
|
|
|
- node.setSelectionRange(0, 0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- getSelection(): CodeEditor.ITextSelection {
|
|
|
- const node = this.node as HTMLTextAreaElement;
|
|
|
- return {
|
|
|
- uuid: this.uuid,
|
|
|
- start: this.model.getPositionAt(node.selectionStart),
|
|
|
- end: this.model.getPositionAt(node.selectionEnd)
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- getSelections(): CodeEditor.ITextSelection[] {
|
|
|
- return [this.getSelection()];
|
|
|
- }
|
|
|
-
|
|
|
- setSelections(selections: CodeEditor.IRange[]): void {
|
|
|
- this.setSelection(selections.length > 0 ? selections[0] : null);
|
|
|
- }
|
|
|
-
|
|
|
- protected onModelSelectionsChanged(sender: CodeEditor.ISelections, args: CodeEditor.ISelections.IChangedArgs) {
|
|
|
- // display foreign cursors
|
|
|
- }
|
|
|
-
|
|
|
- private _evtKeydown(event: KeyboardEvent): void {
|
|
|
- let handler = this._handler;
|
|
|
- if (handler) {
|
|
|
- handler(this, event);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private _evtMouseUp(event: MouseEvent): void {
|
|
|
- this.updateSelections();
|
|
|
- }
|
|
|
-
|
|
|
- protected updateSelections() {
|
|
|
- this._changeGuard = true;
|
|
|
- const selections = this.getSelections();
|
|
|
- this._model.selections.setSelections(this.uuid, selections);
|
|
|
- this._changeGuard = false;
|
|
|
- }
|
|
|
-
|
|
|
- private _evtInput(event: Event): void {
|
|
|
- let node = this.node as HTMLTextAreaElement;
|
|
|
- this._changeGuard = true;
|
|
|
- this.model.value = node.value;
|
|
|
- this._changeGuard = false;
|
|
|
- }
|
|
|
-
|
|
|
- private _model: CodeEditor.IModel;
|
|
|
- private _handler: CodeEditor.KeydownHandler | null = null;
|
|
|
- private _changeGuard = false;
|
|
|
}
|