mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge pull request #2238 from Tyriar/selection_layering
Move SelectionModel to browser
This commit is contained in:
@@ -5,13 +5,12 @@
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { SelectionManager, SelectionMode } from './SelectionManager';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { BufferSet } from 'common/buffer/BufferSet';
|
||||
import { SelectionModel } from 'browser/selection/SelectionModel';
|
||||
import { ITerminal } from './Types';
|
||||
import { IBuffer } from 'common/buffer/Types';
|
||||
import { IBufferLine } from 'common/Types';
|
||||
import { MockTerminal } from './TestUtils.test';
|
||||
import { MockOptionsService, MockBufferService } from 'common/TestUtils.test';
|
||||
import { MockBufferService } from 'common/TestUtils.test';
|
||||
import { BufferLine } from 'common/buffer/BufferLine';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { MockCharSizeService, MockMouseService } from 'browser/TestUtils.test';
|
||||
@@ -52,10 +51,7 @@ describe('SelectionManager', () => {
|
||||
beforeEach(() => {
|
||||
terminal = new TestMockTerminal();
|
||||
bufferService = new MockBufferService(20, 20);
|
||||
terminal.buffers = new BufferSet(
|
||||
new MockOptionsService({ scrollback: 100 }),
|
||||
bufferService
|
||||
);
|
||||
terminal.buffers = bufferService.buffers;
|
||||
terminal.cols = 20;
|
||||
terminal.rows = 20;
|
||||
terminal.buffer = terminal.buffers.active;
|
||||
@@ -366,14 +362,13 @@ describe('SelectionManager', () => {
|
||||
|
||||
describe('selectAll', () => {
|
||||
it('should select the entire buffer, beyond the viewport', () => {
|
||||
buffer.lines.length = 5;
|
||||
bufferService.resize(20, 5);
|
||||
buffer.lines.set(0, stringToRow('1'));
|
||||
buffer.lines.set(1, stringToRow('2'));
|
||||
buffer.lines.set(2, stringToRow('3'));
|
||||
buffer.lines.set(3, stringToRow('4'));
|
||||
buffer.lines.set(4, stringToRow('5'));
|
||||
selectionManager.selectAll();
|
||||
terminal.buffer.ybase = buffer.lines.length - bufferService.rows;
|
||||
assert.equal(selectionManager.selectionText, '1\n2\n3\n4\n5');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ITerminal, ISelectionManager, ISelectionRedrawRequestEvent } from './Ty
|
||||
import { IBuffer } from 'common/buffer/Types';
|
||||
import { IBufferLine } from 'common/Types';
|
||||
import * as Browser from 'common/Platform';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { SelectionModel } from 'browser/selection/SelectionModel';
|
||||
import { AltClickHandler } from './handlers/AltClickHandler';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { IDisposable } from 'xterm';
|
||||
@@ -126,7 +126,7 @@ export class SelectionManager implements ISelectionManager {
|
||||
this._initListeners();
|
||||
this.enable();
|
||||
|
||||
this._model = new SelectionModel(_terminal, bufferService);
|
||||
this._model = new SelectionModel(bufferService);
|
||||
this._activeSelectionMode = SelectionMode.NORMAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,36 +4,15 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { BufferSet } from 'common/buffer/BufferSet';
|
||||
import { MockTerminal } from './TestUtils.test';
|
||||
import { MockOptionsService, MockBufferService } from 'common/TestUtils.test';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { MockBufferService } from 'common/TestUtils.test';
|
||||
|
||||
class TestSelectionModel extends SelectionModel {
|
||||
constructor(
|
||||
terminal: ITerminal,
|
||||
bufferService: IBufferService
|
||||
) {
|
||||
super(terminal, bufferService);
|
||||
}
|
||||
}
|
||||
|
||||
describe('SelectionManager', () => {
|
||||
let terminal: ITerminal;
|
||||
let model: TestSelectionModel;
|
||||
describe('SelectionModel', () => {
|
||||
let model: SelectionModel;
|
||||
|
||||
beforeEach(() => {
|
||||
terminal = new MockTerminal();
|
||||
const bufferService = new MockBufferService(80, 2);
|
||||
terminal.buffers = new BufferSet(
|
||||
new MockOptionsService({ scrollback: 10 }),
|
||||
bufferService
|
||||
);
|
||||
terminal.buffer = terminal.buffers.active;
|
||||
|
||||
model = new TestSelectionModel(terminal, bufferService);
|
||||
model = new SelectionModel(bufferService);
|
||||
});
|
||||
|
||||
describe('clearSelection', () => {
|
||||
@@ -43,8 +22,8 @@ describe('SelectionManager', () => {
|
||||
assert.deepEqual(model.finalSelectionStart, [0, 0]);
|
||||
assert.deepEqual(model.finalSelectionEnd, [10, 2]);
|
||||
model.clearSelection();
|
||||
assert.deepEqual(model.finalSelectionStart, null);
|
||||
assert.deepEqual(model.finalSelectionEnd, null);
|
||||
assert.deepEqual(model.finalSelectionStart, undefined);
|
||||
assert.deepEqual(model.finalSelectionEnd, undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,8 +61,8 @@ describe('SelectionManager', () => {
|
||||
model.selectionStart = [0, 0];
|
||||
model.selectionEnd = [10, 0];
|
||||
model.onTrim(1);
|
||||
assert.deepEqual(model.finalSelectionStart, null);
|
||||
assert.deepEqual(model.finalSelectionEnd, null);
|
||||
assert.deepEqual(model.finalSelectionStart, undefined);
|
||||
assert.deepEqual(model.finalSelectionEnd, undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,9 +90,9 @@ describe('SelectionManager', () => {
|
||||
assert.deepEqual(model.finalSelectionEnd, [80, 1]);
|
||||
});
|
||||
it('should return null if there is no selection start', () => {
|
||||
assert.equal(model.finalSelectionEnd, null);
|
||||
assert.equal(model.finalSelectionEnd, undefined);
|
||||
model.selectionEnd = [1, 2];
|
||||
assert.equal(model.finalSelectionEnd, null);
|
||||
assert.equal(model.finalSelectionEnd, undefined);
|
||||
});
|
||||
it('should return selection start + length if there is no selection end', () => {
|
||||
model.selectionStart = [2, 2];
|
||||
@@ -3,7 +3,6 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal } from './Types';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
|
||||
/**
|
||||
@@ -14,38 +13,36 @@ export class SelectionModel {
|
||||
/**
|
||||
* Whether select all is currently active.
|
||||
*/
|
||||
public isSelectAllActive: boolean;
|
||||
|
||||
/**
|
||||
* The [x, y] position the selection starts at.
|
||||
*/
|
||||
public selectionStart: [number, number];
|
||||
public isSelectAllActive: boolean = false;
|
||||
|
||||
/**
|
||||
* The minimal length of the selection from the start position. When double
|
||||
* clicking on a word, the word will be selected which makes the selection
|
||||
* start at the start of the word and makes this variable the length.
|
||||
*/
|
||||
public selectionStartLength: number;
|
||||
public selectionStartLength: number = 0;
|
||||
|
||||
/**
|
||||
* The [x, y] position the selection starts at.
|
||||
*/
|
||||
public selectionStart: [number, number] | undefined;
|
||||
|
||||
/**
|
||||
* The [x, y] position the selection ends at.
|
||||
*/
|
||||
public selectionEnd: [number, number];
|
||||
public selectionEnd: [number, number] | undefined;
|
||||
|
||||
constructor(
|
||||
private _terminal: ITerminal,
|
||||
private _bufferService: IBufferService
|
||||
) {
|
||||
this.clearSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the current selection.
|
||||
*/
|
||||
public clearSelection(): void {
|
||||
this.selectionStart = null;
|
||||
this.selectionEnd = null;
|
||||
this.selectionStart = undefined;
|
||||
this.selectionEnd = undefined;
|
||||
this.isSelectAllActive = false;
|
||||
this.selectionStartLength = 0;
|
||||
}
|
||||
@@ -53,7 +50,7 @@ export class SelectionModel {
|
||||
/**
|
||||
* The final selection start, taking into consideration select all.
|
||||
*/
|
||||
public get finalSelectionStart(): [number, number] {
|
||||
public get finalSelectionStart(): [number, number] | undefined {
|
||||
if (this.isSelectAllActive) {
|
||||
return [0, 0];
|
||||
}
|
||||
@@ -69,13 +66,13 @@ export class SelectionModel {
|
||||
* The final selection end, taking into consideration select all, double click
|
||||
* word selection and triple click line selection.
|
||||
*/
|
||||
public get finalSelectionEnd(): [number, number] {
|
||||
public get finalSelectionEnd(): [number, number] | undefined {
|
||||
if (this.isSelectAllActive) {
|
||||
return [this._bufferService.cols, this._terminal.buffer.ybase + this._bufferService.rows - 1];
|
||||
return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];
|
||||
}
|
||||
|
||||
if (!this.selectionStart) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Use the selection start + length if the end doesn't exist or they're reversed
|
||||
@@ -8,14 +8,18 @@ import { IEvent, EventEmitter } from 'common/EventEmitter';
|
||||
import { clone } from 'common/Clone';
|
||||
import { DEFAULT_OPTIONS } from 'common/services/OptionsService';
|
||||
import { IBufferSet, IBuffer } from 'common/buffer/Types';
|
||||
import { BufferSet } from 'common/buffer/BufferSet';
|
||||
|
||||
export class MockBufferService implements IBufferService {
|
||||
public buffer: IBuffer = {} as any;
|
||||
public get buffer(): IBuffer { return this.buffers.active; }
|
||||
public buffers: IBufferSet = {} as any;
|
||||
constructor(
|
||||
public cols: number,
|
||||
public rows: number
|
||||
) {}
|
||||
public rows: number,
|
||||
optionsService: IOptionsService = new MockOptionsService()
|
||||
) {
|
||||
this.buffers = new BufferSet(optionsService, this);
|
||||
}
|
||||
resize(cols: number, rows: number): void {
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
@@ -26,8 +30,10 @@ export class MockBufferService implements IBufferService {
|
||||
export class MockOptionsService implements IOptionsService {
|
||||
options: ITerminalOptions = clone(DEFAULT_OPTIONS);
|
||||
onOptionChange: IEvent<string> = new EventEmitter<string>().event;
|
||||
constructor(testOptions: IPartialTerminalOptions) {
|
||||
Object.keys(testOptions).forEach(key => this.options[key] = (<any>testOptions)[key]);
|
||||
constructor(testOptions?: IPartialTerminalOptions) {
|
||||
if (testOptions) {
|
||||
Object.keys(testOptions).forEach(key => this.options[key] = (<any>testOptions)[key]);
|
||||
}
|
||||
}
|
||||
setOption<T>(key: string, value: T): void {
|
||||
throw new Error('Method not implemented.');
|
||||
|
||||
Reference in New Issue
Block a user