diff --git a/src/xterm.js b/src/xterm.js index 0bff3e6d..b34c7503 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -230,7 +230,6 @@ setTimeout(function () { // Ensure that the input has not already been sent if (self.isSendingComposition) { - console.log('send input ' + input + ' delayed'); self.isSendingComposition = false; var input = self.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end); self.terminal.handler(input); @@ -260,8 +259,8 @@ */ CompositionHelper.prototype.updateCompositionViewPosition = function() { var cursor = this.terminal.element.querySelector('.terminal-cursor'); - term.compositionView.style.left = cursor.offsetLeft + 'px'; - term.compositionView.style.top = cursor.offsetTop + 'px'; + this.compositionView.style.left = cursor.offsetLeft + 'px'; + this.compositionView.style.top = cursor.offsetTop + 'px'; }; @@ -5226,6 +5225,7 @@ */ Terminal.EventEmitter = EventEmitter; + Terminal.CompositionHelper = CompositionHelper; Terminal.inherits = inherits; /** diff --git a/test/composition-helper-test.js b/test/composition-helper-test.js new file mode 100644 index 00000000..502d72cf --- /dev/null +++ b/test/composition-helper-test.js @@ -0,0 +1,170 @@ +var assert = require('chai').assert; +var Terminal = require('../src/xterm'); + +describe('CompositionHelper', function () { + var terminal; + var compositionHelper; + var compositionView; + var textarea; + var handledText; + + beforeEach(function () { + compositionView = { + classList: { + add: function () {}, + remove: function () {}, + }, + style: { + left: 0, + top: 0 + }, + textContent: '' + } + textarea = { + value: '' + } + terminal = { + element: { + querySelector: function () { + return { offsetLeft: 0, offsetTop: 0 }; + } + }, + handler: function (text) { + handledText += text; + console.log('handler - ' + text); + } + } + handledText = ''; + compositionHelper = new Terminal.CompositionHelper(textarea, compositionView, terminal); + }); + + describe('Public API', function () { + it('should define CompositionHelper.prototype.compositionstart', function () { + assert.isDefined(Terminal.CompositionHelper.prototype.compositionstart); + }); + it('should define CompositionHelper.prototype.compositionupdate', function () { + assert.isDefined(Terminal.CompositionHelper.prototype.compositionupdate); + }); + it('should define CompositionHelper.prototype.compositionend', function () { + assert.isDefined(Terminal.CompositionHelper.prototype.compositionend); + }); + it('should define CompositionHelper.prototype.finalizeComposition', function () { + assert.isDefined(Terminal.CompositionHelper.prototype.finalizeComposition); + }); + it('should define CompositionHelper.prototype.handleAnyTextareaChanges', function () { + assert.isDefined(Terminal.CompositionHelper.prototype.handleAnyTextareaChanges); + }); + it('should define CompositionHelper.prototype.updateCompositionViewPosition', function () { + assert.isDefined(Terminal.CompositionHelper.prototype.updateCompositionViewPosition); + }); + it('should define CompositionHelper.isComposing', function () { + assert.isDefined(compositionHelper.isComposing); + }); + it('should define CompositionHelper.isSendingComposition', function () { + assert.isDefined(compositionHelper.isSendingComposition); + }); + }); + + describe('Input', function () { + it('Should insert simple characters', function (done) { + // First character + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(function() { // wait for any textarea updates + assert.equal(handledText, 'ㅇ'); + // Second character + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇㅇ'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(function() { // wait for any textarea updates + assert.equal(handledText, 'ㅇㅇ'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert complex characters', function (done) { + // First character + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '아'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '앙' }); + textarea.value = '앙'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(function() { // wait for any textarea updates + assert.equal(handledText, '앙'); + // Second character + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = '앙ㅇ'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '앙아'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '앙' }); + textarea.value = '앙앙'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(function() { // wait for any textarea updates + assert.equal(handledText, '앙앙'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert complex characters that change with following character', function (done) { + // First character + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '아'; + setTimeout(function() { // wait for any textarea updates + // Start second character in first character + compositionHelper.compositionupdate({ data: '앙' }); + textarea.value = '앙'; + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionend(); + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '아아' + setTimeout(function() { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(function() { // wait for any textarea updates + assert.equal(handledText, '아아'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert multi-line charcters', function () { + // TODO: Implement a hiragana example + }); + + it('Should insert multi-line charcters that are converted to other characters', function () { + // TODO: Implement a hiragana -> kanji example + }); + }); +});