mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into strikethrough
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
"readonly": "generic"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/consistent-type-assertions": "warn",
|
||||
"@typescript-eslint/consistent-type-definitions": "warn",
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"warn",
|
||||
|
||||
@@ -143,7 +143,6 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
||||
- [**cPanel & WHM**](https://cpanel.com): The hosting platform of choice.
|
||||
- [**Nutanix**](https://github.com/nutanix): Nutanix Enterprise Cloud uses xterm in the webssh functionality within Nutanix Calm, and is also looking to move our old noserial (termjs) functionality to xterm.js.
|
||||
- [**SSH Web Client**](https://github.com/roke22/PHP-SSH2-Web-Client): SSH Web Client with PHP.
|
||||
- [**Shellvault**](https://www.shellvault.io): The cloud-based SSH terminal you can access from anywhere.
|
||||
- [**Juno**](http://junolab.org/): A flexible Julia IDE, based on Atom.
|
||||
- [**webssh**](https://github.com/huashengdun/webssh): Web based ssh client.
|
||||
- [**info-beamer hosted**](https://info-beamer.com): Uses xterm.js to manage digital signage devices from the web dashboard.
|
||||
|
||||
@@ -20,7 +20,7 @@ export class AttachAddon implements ITerminalAddon {
|
||||
this._socket = socket;
|
||||
// always set binary type to arraybuffer, we do not handle blobs
|
||||
this._socket.binaryType = 'arraybuffer';
|
||||
this._bidirectional = (options && options.bidirectional === false) ? false : true;
|
||||
this._bidirectional = !(options && options.bidirectional === false);
|
||||
}
|
||||
|
||||
public activate(terminal: Terminal): void {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xterm-addon-ligatures",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.1",
|
||||
"description": "Add support for programming ligatures to xterm.js",
|
||||
"author": {
|
||||
"name": "The xterm.js authors",
|
||||
|
||||
@@ -37,7 +37,7 @@ export default async function load(fontFamily: string, cacheSize: number): Promi
|
||||
// Web environment that supports font access API
|
||||
if (typeof navigator !== 'undefined' && 'fonts' in navigator) {
|
||||
try {
|
||||
const status = await (navigator as IFontAccessNavigator).permissions.request?.({
|
||||
const status = await (navigator as unknown as IFontAccessNavigator).permissions.request?.({
|
||||
name: 'local-fonts'
|
||||
});
|
||||
if (status && status.state !== 'granted') {
|
||||
@@ -53,7 +53,7 @@ export default async function load(fontFamily: string, cacheSize: number): Promi
|
||||
}
|
||||
const fonts: Record<string, IFontMetadata[]> = {};
|
||||
try {
|
||||
const fontsIterator = await (navigator as IFontAccessNavigator).fonts.query();
|
||||
const fontsIterator = await (navigator as unknown as IFontAccessNavigator).fonts.query();
|
||||
for (const metadata of fontsIterator) {
|
||||
if (!fonts.hasOwnProperty(metadata.family)) {
|
||||
fonts[metadata.family] = [];
|
||||
|
||||
@@ -394,7 +394,7 @@ export class SearchAddon implements ITerminalAddon {
|
||||
// If it is not in the viewport then we scroll else it just gets selected
|
||||
if (result.row >= (terminal.buffer.active.viewportY + terminal.rows) || result.row < terminal.buffer.active.viewportY) {
|
||||
let scroll = result.row - terminal.buffer.active.viewportY;
|
||||
scroll = scroll - Math.floor(terminal.rows / 2);
|
||||
scroll -= Math.floor(terminal.rows / 2);
|
||||
terminal.scrollLines(scroll);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -487,9 +487,9 @@ function newArray<T>(initial: T | ((index: number) => T), count: number): T[] {
|
||||
const array: T[] = new Array<T>(count);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (typeof initial === 'function') {
|
||||
array[i] = (<(index: number) => T>initial)(i);
|
||||
array[i] = (initial as (index: number) => T)(i);
|
||||
} else {
|
||||
array[i] = <T>initial;
|
||||
array[i] = initial as T;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
|
||||
@@ -263,7 +263,7 @@ export class GlyphRenderer {
|
||||
// Get attributes from fg (excluding inverse) and resolve inverse by pullibng rgb colors
|
||||
// from bg. This is needed since the inverse fg color should be based on the original bg
|
||||
// color, not on the selection color
|
||||
fg = (fg & ~(Attributes.CM_MASK | Attributes.RGB_MASK | FgFlags.INVERSE));
|
||||
fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK | FgFlags.INVERSE);
|
||||
switch (workCell.getBgColorMode()) {
|
||||
case Attributes.CM_P16:
|
||||
case Attributes.CM_P256:
|
||||
|
||||
@@ -24,9 +24,9 @@ export class WebglAddon implements ITerminalAddon {
|
||||
throw new Error('Cannot activate WebglAddon before Terminal.open');
|
||||
}
|
||||
this._terminal = terminal;
|
||||
const renderService: IRenderService = (<any>terminal)._core._renderService;
|
||||
const characterJoinerService: ICharacterJoinerService = (<any>terminal)._core._characterJoinerService;
|
||||
const colors: IColorSet = (<any>terminal)._core._colorManager.colors;
|
||||
const renderService: IRenderService = (terminal as any)._core._renderService;
|
||||
const characterJoinerService: ICharacterJoinerService = (terminal as any)._core._characterJoinerService;
|
||||
const colors: IColorSet = (terminal as any)._core._colorManager.colors;
|
||||
this._renderer = new WebglRenderer(terminal, colors, characterJoinerService, this._preserveDrawingBuffer);
|
||||
this._renderer.onContextLoss(() => this._onContextLoss.fire());
|
||||
renderService.setRenderer(this._renderer);
|
||||
|
||||
@@ -342,7 +342,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
|
||||
// Flag combined chars with a bit mask so they're easily identifiable
|
||||
if (chars.length > 1) {
|
||||
code = code | COMBINED_CHAR_BIT_MASK;
|
||||
code |= COMBINED_CHAR_BIT_MASK;
|
||||
}
|
||||
|
||||
// Cache the results in the model
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "xterm",
|
||||
"description": "Full xterm terminal, in your browser",
|
||||
"version": "4.12.0",
|
||||
"version": "4.13.0",
|
||||
"main": "lib/xterm.js",
|
||||
"style": "css/xterm.css",
|
||||
"types": "typings/xterm.d.ts",
|
||||
|
||||
@@ -112,7 +112,7 @@ export class AccessibilityManager extends Disposable {
|
||||
}
|
||||
|
||||
private _onBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {
|
||||
const boundaryElement = <HTMLElement>e.target;
|
||||
const boundaryElement = e.target as HTMLElement;
|
||||
const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];
|
||||
|
||||
// Don't scroll if the buffer top has reached the end in that direction
|
||||
|
||||
@@ -17,7 +17,7 @@ describe('ColorManager', () => {
|
||||
dom = new jsdom.JSDOM('');
|
||||
window = dom.window;
|
||||
document = window.document;
|
||||
(<any>window).HTMLCanvasElement.prototype.getContext = () => ({
|
||||
(window as any).HTMLCanvasElement.prototype.getContext = () => ({
|
||||
createLinearGradient(): any {
|
||||
return null;
|
||||
},
|
||||
@@ -36,7 +36,7 @@ describe('ColorManager', () => {
|
||||
for (const key of Object.keys(cm.colors)) {
|
||||
if (key !== 'ansi' && key !== 'contrastCache') {
|
||||
// A #rrggbb or rgba(...)
|
||||
assert.ok((<any>cm.colors)[key].css.length >= 7);
|
||||
assert.ok((cm.colors as any)[key].css.length >= 7);
|
||||
}
|
||||
}
|
||||
assert.equal(cm.colors.ansi.length, 256);
|
||||
|
||||
@@ -174,7 +174,7 @@ describe('Linkifier', () => {
|
||||
assert.equal(mouseZoneManager.zones[0].y1, 1);
|
||||
assert.equal(mouseZoneManager.zones[0].y2, 1);
|
||||
// Fires done()
|
||||
mouseZoneManager.zones[0].clickCallback(<any>{});
|
||||
mouseZoneManager.zones[0].clickCallback({} as any);
|
||||
}
|
||||
});
|
||||
linkifier.linkifyRows();
|
||||
@@ -210,7 +210,7 @@ describe('Linkifier', () => {
|
||||
let count = 0;
|
||||
linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
|
||||
validationCallback: (url, cb) => {
|
||||
count += 1;
|
||||
count++;
|
||||
if (count === 2) {
|
||||
done();
|
||||
}
|
||||
|
||||
@@ -89,7 +89,9 @@ export class Linkifier implements ILinkifier {
|
||||
if (this._rowsTimeoutId) {
|
||||
clearTimeout(this._rowsTimeoutId);
|
||||
}
|
||||
this._rowsTimeoutId = <number><any>setTimeout(() => this._linkifyRows(), Linkifier._timeBeforeLatency);
|
||||
|
||||
// Cannot use window.setTimeout since tests need to run in node
|
||||
this._rowsTimeoutId = setTimeout(() => this._linkifyRows(), Linkifier._timeBeforeLatency) as any as number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,10 +29,10 @@ describe('Terminal', () => {
|
||||
beforeEach(() => {
|
||||
term = new TestTerminal(termOptions);
|
||||
term.refresh = () => { };
|
||||
(<any>term).renderer = new MockRenderer();
|
||||
(term as any).renderer = new MockRenderer();
|
||||
term.viewport = new MockViewport();
|
||||
(<any>term)._compositionHelper = new MockCompositionHelper();
|
||||
(<any>term).element = {
|
||||
(term as any)._compositionHelper = new MockCompositionHelper();
|
||||
(term as any).element = {
|
||||
classList: {
|
||||
toggle: () => { },
|
||||
remove: () => { }
|
||||
@@ -86,12 +86,12 @@ describe('Terminal', () => {
|
||||
assert.equal(e.domEvent instanceof Object, true);
|
||||
done();
|
||||
});
|
||||
const evKeyPress = <KeyboardEvent>{
|
||||
const evKeyPress = {
|
||||
preventDefault: () => { },
|
||||
stopPropagation: () => { },
|
||||
type: 'keypress',
|
||||
keyCode: 13
|
||||
};
|
||||
} as KeyboardEvent;
|
||||
term.keyPress(evKeyPress);
|
||||
});
|
||||
it('should fire a key event after a keydown DOM event', (done) => {
|
||||
@@ -100,13 +100,13 @@ describe('Terminal', () => {
|
||||
assert.equal(e.domEvent instanceof Object, true);
|
||||
done();
|
||||
});
|
||||
(<any>term).textarea = { value: '' };
|
||||
const evKeyDown = <KeyboardEvent>{
|
||||
(term as any).textarea = { value: '' };
|
||||
const evKeyDown = {
|
||||
preventDefault: () => { },
|
||||
stopPropagation: () => { },
|
||||
type: 'keydown',
|
||||
keyCode: 13
|
||||
};
|
||||
} as KeyboardEvent;
|
||||
term.keyDown(evKeyDown);
|
||||
});
|
||||
it('should fire the onResize event', (done) => {
|
||||
@@ -140,18 +140,18 @@ describe('Terminal', () => {
|
||||
});
|
||||
|
||||
describe('attachCustomKeyEventHandler', () => {
|
||||
const evKeyDown = <KeyboardEvent>{
|
||||
const evKeyDown = {
|
||||
preventDefault: () => { },
|
||||
stopPropagation: () => { },
|
||||
type: 'keydown',
|
||||
keyCode: 77
|
||||
};
|
||||
const evKeyPress = <KeyboardEvent>{
|
||||
} as KeyboardEvent;
|
||||
const evKeyPress = {
|
||||
preventDefault: () => { },
|
||||
stopPropagation: () => { },
|
||||
type: 'keypress',
|
||||
keyCode: 77
|
||||
};
|
||||
} as KeyboardEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
term.clearSelection = () => { };
|
||||
@@ -374,13 +374,13 @@ describe('Terminal', () => {
|
||||
|
||||
describe('keyPress', () => {
|
||||
it('should scroll down, when a key is pressed and terminal is scrolled up', () => {
|
||||
const event = <KeyboardEvent>{
|
||||
const event = {
|
||||
type: 'keydown',
|
||||
key: 'a',
|
||||
keyCode: 65,
|
||||
preventDefault: () => { },
|
||||
stopPropagation: () => { }
|
||||
};
|
||||
} as KeyboardEvent;
|
||||
|
||||
term.buffer.ydisp = 0;
|
||||
term.buffer.ybase = 40;
|
||||
@@ -403,7 +403,7 @@ describe('Terminal', () => {
|
||||
assert.equal(term.buffer.ydisp, startYDisp);
|
||||
term.scrollLines(-1);
|
||||
assert.equal(term.buffer.ydisp, startYDisp - 1);
|
||||
term.keyPress(<KeyboardEvent>{ keyCode: 0 });
|
||||
term.keyPress({ keyCode: 0 });
|
||||
assert.equal(term.buffer.ydisp, startYDisp - 1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
|
||||
// private _visualBellTimer: number;
|
||||
|
||||
public browser: IBrowser = <any>Browser;
|
||||
public browser: IBrowser = Browser as any;
|
||||
|
||||
// TODO: We should remove options once components adopt optionsService
|
||||
public get options(): IInitializedTerminalOptions { return this.optionsService.options; }
|
||||
@@ -601,7 +601,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
|
||||
let but: CoreMouseButton;
|
||||
let action: CoreMouseAction | undefined;
|
||||
switch ((<any>ev).overrideType || ev.type) {
|
||||
switch ((ev as any).overrideType || ev.type) {
|
||||
case 'mousemove':
|
||||
action = CoreMouseAction.MOVE;
|
||||
if (ev.buttons === undefined) {
|
||||
|
||||
@@ -17,6 +17,7 @@ const ROWS = 25;
|
||||
|
||||
const TESTFILES = glob.sync('**/escape_sequence_files/*.in', { cwd: path.join(__dirname, '../..')});
|
||||
const SKIP_FILES = [
|
||||
't0055-EL.in', // EL/ED handle cursor at cols differently (see #3362)
|
||||
't0084-CBT.in',
|
||||
't0101-NLM.in',
|
||||
't0103-reverse_wrap.in', // not comparable, we deviate from xterm reverse wrap on purpose
|
||||
@@ -105,7 +106,7 @@ function formatError(input: string, output: string, expected: string): string {
|
||||
function addLineNumber(start: number, color: string): (s: string) => string {
|
||||
let counter = start || 0;
|
||||
return (s: string): string => {
|
||||
counter += 1;
|
||||
counter++;
|
||||
return '\x1b[33m' + (' ' + counter).slice(-2) + color + s;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ export class MockTerminal implements ITerminal {
|
||||
public textarea!: HTMLTextAreaElement;
|
||||
public rows!: number;
|
||||
public cols!: number;
|
||||
public browser: IBrowser = <any>Browser;
|
||||
public browser: IBrowser = Browser as any;
|
||||
public writeBuffer!: string[];
|
||||
public children!: HTMLElement[];
|
||||
public cursorHidden!: boolean;
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert simple characters', (done) => {
|
||||
// First character 'ㅇ'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent><CompositionEvent>{ data: 'ㅇ' });
|
||||
compositionHelper.compositionupdate({ data: 'ㅇ' });
|
||||
textarea.value = 'ㅇ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -57,7 +57,7 @@ describe('CompositionHelper', () => {
|
||||
assert.equal(handledText, 'ㅇ');
|
||||
// Second character 'ㅇ'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent><CompositionEvent>{ data: 'ㅇ' });
|
||||
compositionHelper.compositionupdate({ data: 'ㅇ' });
|
||||
textarea.value = 'ㅇㅇ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -73,13 +73,13 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert complex characters', (done) => {
|
||||
// First character '앙'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'ㅇ' });
|
||||
compositionHelper.compositionupdate({ data: 'ㅇ' });
|
||||
textarea.value = 'ㅇ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
|
||||
compositionHelper.compositionupdate({ data: '아' });
|
||||
textarea.value = '아';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '앙' });
|
||||
compositionHelper.compositionupdate({ data: '앙' });
|
||||
textarea.value = '앙';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -87,13 +87,13 @@ describe('CompositionHelper', () => {
|
||||
assert.equal(handledText, '앙');
|
||||
// Second character '앙'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'ㅇ' });
|
||||
compositionHelper.compositionupdate({ data: 'ㅇ' });
|
||||
textarea.value = '앙ㅇ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
|
||||
compositionHelper.compositionupdate({ data: '아' });
|
||||
textarea.value = '앙아';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '앙' });
|
||||
compositionHelper.compositionupdate({ data: '앙' });
|
||||
textarea.value = '앙앙';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -113,19 +113,19 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert complex characters that change with following character', (done) => {
|
||||
// First character '아'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'ㅇ' });
|
||||
compositionHelper.compositionupdate({ data: 'ㅇ' });
|
||||
textarea.value = 'ㅇ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
|
||||
compositionHelper.compositionupdate({ data: '아' });
|
||||
textarea.value = '아';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
// Start second character '아' in first character
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '앙' });
|
||||
compositionHelper.compositionupdate({ data: '앙' });
|
||||
textarea.value = '앙';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
|
||||
compositionHelper.compositionupdate({ data: '아' });
|
||||
textarea.value = '아아';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -142,14 +142,14 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert multi-characters compositions', (done) => {
|
||||
// First character 'だ'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'd' });
|
||||
compositionHelper.compositionupdate({ data: 'd' });
|
||||
textarea.value = 'd';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だ' });
|
||||
compositionHelper.compositionupdate({ data: 'だ' });
|
||||
textarea.value = 'だ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
// Second character 'あ'
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だあ' });
|
||||
compositionHelper.compositionupdate({ data: 'だあ' });
|
||||
textarea.value = 'だあ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -165,18 +165,18 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert multi-character compositions that are converted to other characters with the same length', (done) => {
|
||||
// First character 'だ'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'd' });
|
||||
compositionHelper.compositionupdate({ data: 'd' });
|
||||
textarea.value = 'd';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だ' });
|
||||
compositionHelper.compositionupdate({ data: 'だ' });
|
||||
textarea.value = 'だ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
// Second character 'ー'
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だー' });
|
||||
compositionHelper.compositionupdate({ data: 'だー' });
|
||||
textarea.value = 'だー';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
// Convert to katakana 'ダー'
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'ダー' });
|
||||
compositionHelper.compositionupdate({ data: 'ダー' });
|
||||
textarea.value = 'ダー';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -193,18 +193,18 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert multi-character compositions that are converted to other characters with different lengths', (done) => {
|
||||
// First character 'い'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'い' });
|
||||
compositionHelper.compositionupdate({ data: 'い' });
|
||||
textarea.value = 'い';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
// Second character 'ま'
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'いm' });
|
||||
compositionHelper.compositionupdate({ data: 'いm' });
|
||||
textarea.value = 'いm';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'いま' });
|
||||
compositionHelper.compositionupdate({ data: 'いま' });
|
||||
textarea.value = 'いま';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
// Convert to kanji '今'
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: '今' });
|
||||
compositionHelper.compositionupdate({ data: '今' });
|
||||
textarea.value = '今';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
@@ -221,7 +221,7 @@ describe('CompositionHelper', () => {
|
||||
it('Should insert non-composition characters input immediately after composition characters', (done) => {
|
||||
// First character 'ㅇ'
|
||||
compositionHelper.compositionstart();
|
||||
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'ㅇ' });
|
||||
compositionHelper.compositionupdate({ data: 'ㅇ' });
|
||||
textarea.value = 'ㅇ';
|
||||
setTimeout(() => { // wait for any textarea updates
|
||||
compositionHelper.compositionend();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user