/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TextAreaHandler } from 'vs/editor/common/controller/textAreaHandler';
import * as browser from 'vs/base/browser/browser';
import { TextAreaStrategy, ISimpleModel } from 'vs/editor/common/controller/textAreaState';
import { Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { TextAreaWrapper } from 'vs/editor/browser/controller/input/textAreaWrapper';
import { Position } from 'vs/editor/common/core/position';
// To run this test, open imeTester.html
class SingleLineTestModel implements ISimpleModel {
private _line: string;
private _eol: string;
constructor(line: string) {
this._line = line;
this._eol = '\n';
}
setText(text: string) {
this._line = text;
}
getLineMaxColumn(lineNumber: number): number {
return this._line.length + 1;
}
getEOL(): string {
return this._eol;
}
getValueInRange(range: editorCommon.IRange, eol: editorCommon.EndOfLinePreference): string {
return this._line.substring(range.startColumn - 1, range.endColumn - 1);
}
getModelLineContent(lineNumber: number): string {
return this._line;
}
getLineCount(): number {
return 1;
}
convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position {
return new Position(viewLineNumber, viewColumn);
}
}
class TestView {
private _model: SingleLineTestModel;
constructor(model: SingleLineTestModel) {
this._model = model;
}
public paint(output: HTMLElement) {
let r = '';
for (let i = 1; i <= this._model.getLineCount(); i++) {
let content = this._model.getModelLineContent(i);
r += content + '
';
}
output.innerHTML = r;
}
}
function doCreateTest(strategy: TextAreaStrategy, description: string, inputStr: string, expectedStr: string): HTMLElement {
let container = document.createElement('div');
container.className = 'container';
let title = document.createElement('div');
title.className = 'title';
title.innerHTML = TextAreaStrategy[strategy] + ' strategy: ' + description + '. Type ' + inputStr + '';
container.appendChild(title);
let startBtn = document.createElement('button');
startBtn.innerHTML = 'Start';
container.appendChild(startBtn);
let input = document.createElement('textarea');
input.setAttribute('rows', '10');
input.setAttribute('cols', '40');
container.appendChild(input);
let textAreaWrapper = new TextAreaWrapper(input);
let model = new SingleLineTestModel('some text');
let handler = new TextAreaHandler(browser, strategy, textAreaWrapper, model, () => { });
input.onfocus = () => {
handler.setHasFocus(true);
};
input.onblur = () => {
handler.setHasFocus(false);
};
let output = document.createElement('pre');
output.className = 'output';
container.appendChild(output);
let check = document.createElement('pre');
check.className = 'check';
container.appendChild(check);
let br = document.createElement('br');
br.style.clear = 'both';
container.appendChild(br);
let view = new TestView(model);
let cursorOffset: number;
let cursorLength: number;
let updatePosition = (off: number, len: number) => {
cursorOffset = off;
cursorLength = len;
handler.setCursorSelections(new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength), []);
handler.focusTextArea();
};
let updateModelAndPosition = (text: string, off: number, len: number) => {
model.setText(text);
updatePosition(off, len);
view.paint(output);
let expected = 'some ' + expectedStr + ' text';
if (text === expected) {
check.innerHTML = '[GOOD]';
check.className = 'check good';
} else {
check.innerHTML = '[BAD]';
check.className = 'check bad';
}
check.innerHTML += expected;
};
handler.onType((e) => {
console.log('type text: ' + e.text + ', replaceCharCnt: ' + e.replaceCharCnt);
let text = model.getModelLineContent(1);
let preText = text.substring(0, cursorOffset - e.replaceCharCnt);
let postText = text.substring(cursorOffset + cursorLength);
let midText = e.text;
updateModelAndPosition(preText + midText + postText, (preText + midText).length, 0);
});
view.paint(output);
startBtn.onclick = function () {
updateModelAndPosition('some text', 5, 0);
input.focus();
};
return container;
}
const TESTS = [
{ description: 'Japanese IME 1', in: 'sennsei [Enter]', out: 'せんせい' },
{ description: 'Japanese IME 2', in: 'konnichiha [Enter]', out: 'こんいちは' },
{ description: 'Japanese IME 3', in: 'mikann [Enter]', out: 'みかん' },
{ description: 'Korean IME 1', in: 'gksrmf [Space]', out: '한글 ' },
{ description: 'Chinese IME 1', in: '.,', out: '。,' },
{ description: 'Chinese IME 2', in: 'ni [Space] hao [Space]', out: '你好' },
{ description: 'Chinese IME 3', in: 'hazni [Space]', out: '哈祝你' },
{ description: 'Mac dead key 1', in: '`.', out: '`.' },
{ description: 'Mac hold key 1', in: 'e long press and 1', out: 'é' }
];
TESTS.forEach((t) => {
document.body.appendChild(doCreateTest(TextAreaStrategy.NVDA, t.description, t.in, t.out));
document.body.appendChild(doCreateTest(TextAreaStrategy.IENarrator, t.description, t.in, t.out));
});