@@ -12,7 +12,7 @@ import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
1212import { StyleMutator } from 'vs/base/browser/styleMutator' ;
1313import { GlobalScreenReaderNVDA } from 'vs/editor/common/config/commonEditorConfig' ;
1414import { TextAreaHandler } from 'vs/editor/common/controller/textAreaHandler' ;
15- import { IClipboardEvent , IKeyboardEventWrapper , ITextAreaWrapper , TextAreaStrategy } from 'vs/editor/common/controller/textAreaState' ;
15+ import { IClipboardEvent , ICompositionEvent , IKeyboardEventWrapper , ITextAreaWrapper , TextAreaStrategy } from 'vs/editor/common/controller/textAreaState' ;
1616import { Range } from 'vs/editor/common/core/range' ;
1717import * as editorCommon from 'vs/editor/common/editorCommon' ;
1818import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler' ;
@@ -114,11 +114,14 @@ class TextAreaWrapper extends Disposable implements ITextAreaWrapper {
114114 private _onKeyPress = this . _register ( new Emitter < IKeyboardEventWrapper > ( ) ) ;
115115 public onKeyPress : Event < IKeyboardEventWrapper > = this . _onKeyPress . event ;
116116
117- private _onCompositionStart = this . _register ( new Emitter < void > ( ) ) ;
118- public onCompositionStart : Event < void > = this . _onCompositionStart . event ;
117+ private _onCompositionStart = this . _register ( new Emitter < ICompositionEvent > ( ) ) ;
118+ public onCompositionStart : Event < ICompositionEvent > = this . _onCompositionStart . event ;
119119
120- private _onCompositionEnd = this . _register ( new Emitter < void > ( ) ) ;
121- public onCompositionEnd : Event < void > = this . _onCompositionEnd . event ;
120+ private _onCompositionUpdate = this . _register ( new Emitter < ICompositionEvent > ( ) ) ;
121+ public onCompositionUpdate : Event < ICompositionEvent > = this . _onCompositionUpdate . event ;
122+
123+ private _onCompositionEnd = this . _register ( new Emitter < ICompositionEvent > ( ) ) ;
124+ public onCompositionEnd : Event < ICompositionEvent > = this . _onCompositionEnd . event ;
122125
123126 private _onInput = this . _register ( new Emitter < void > ( ) ) ;
124127 public onInput : Event < void > = this . _onInput . event ;
@@ -139,8 +142,9 @@ class TextAreaWrapper extends Disposable implements ITextAreaWrapper {
139142 this . _register ( dom . addStandardDisposableListener ( this . _textArea , 'keydown' , ( e ) => this . _onKeyDown . fire ( new KeyboardEventWrapper ( e ) ) ) ) ;
140143 this . _register ( dom . addStandardDisposableListener ( this . _textArea , 'keyup' , ( e ) => this . _onKeyUp . fire ( new KeyboardEventWrapper ( e ) ) ) ) ;
141144 this . _register ( dom . addStandardDisposableListener ( this . _textArea , 'keypress' , ( e ) => this . _onKeyPress . fire ( new KeyboardEventWrapper ( e ) ) ) ) ;
142- this . _register ( dom . addDisposableListener ( this . _textArea , 'compositionstart' , ( e ) => this . _onCompositionStart . fire ( ) ) ) ;
143- this . _register ( dom . addDisposableListener ( this . _textArea , 'compositionend' , ( e ) => this . _onCompositionEnd . fire ( ) ) ) ;
145+ this . _register ( dom . addDisposableListener ( this . _textArea , 'compositionstart' , ( e ) => this . _onCompositionStart . fire ( e ) ) ) ;
146+ this . _register ( dom . addDisposableListener ( this . _textArea , 'compositionupdate' , ( e ) => this . _onCompositionUpdate . fire ( e ) ) ) ;
147+ this . _register ( dom . addDisposableListener ( this . _textArea , 'compositionend' , ( e ) => this . _onCompositionEnd . fire ( e ) ) ) ;
144148 this . _register ( dom . addDisposableListener ( this . _textArea , 'input' , ( e ) => this . _onInput . fire ( ) ) ) ;
145149 this . _register ( dom . addDisposableListener ( this . _textArea , 'cut' , ( e :ClipboardEvent ) => this . _onCut . fire ( new ClipboardEventWrapper ( e ) ) ) ) ;
146150 this . _register ( dom . addDisposableListener ( this . _textArea , 'copy' , ( e :ClipboardEvent ) => this . _onCopy . fire ( new ClipboardEventWrapper ( e ) ) ) ) ;
@@ -213,6 +217,8 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
213217 private contentWidth :number ;
214218 private scrollLeft :number ;
215219
220+ private visibleRange :VisibleRange ;
221+
216222 constructor ( context :ViewContext , viewController :IViewController , viewHelper :IKeyboardHandlerHelper ) {
217223 super ( ) ;
218224
@@ -252,11 +258,11 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
252258 this . _context . privateViewEventBus . emit ( editorCommon . ViewEventNames . RevealRangeEvent , revealPositionEvent ) ;
253259
254260 // Find range pixel position
255- let visibleRange = this . viewHelper . visibleRangeForPositionRelativeToEditor ( lineNumber , column ) ;
261+ this . visibleRange = this . viewHelper . visibleRangeForPositionRelativeToEditor ( lineNumber , column ) ;
256262
257- if ( visibleRange ) {
258- StyleMutator . setTop ( this . textArea . actual , visibleRange . top ) ;
259- StyleMutator . setLeft ( this . textArea . actual , this . contentLeft + visibleRange . left - this . scrollLeft ) ;
263+ if ( this . visibleRange ) {
264+ StyleMutator . setTop ( this . textArea . actual , this . visibleRange . top ) ;
265+ StyleMutator . setLeft ( this . textArea . actual , this . contentLeft + this . visibleRange . left - this . scrollLeft ) ;
260266 }
261267
262268 if ( browser . isIE11orEarlier ) {
@@ -267,12 +273,24 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
267273 StyleMutator . setHeight ( this . textArea . actual , this . _context . configuration . editor . lineHeight ) ;
268274 dom . addClass ( this . viewHelper . viewDomNode , 'ime-input' ) ;
269275 } ) ) ;
276+
277+ this . _toDispose . push ( this . textAreaHandler . onCompositionUpdate ( ( e ) => {
278+ // adjust width by its size
279+ let canvasElem = < HTMLCanvasElement > document . createElement ( 'canvas' ) ;
280+ let context = canvasElem . getContext ( '2d' ) ;
281+ context . font = window . getComputedStyle ( this . textArea . actual ) . font ;
282+ let metrics = context . measureText ( e . data ) ;
283+ StyleMutator . setWidth ( this . textArea . actual , metrics . width ) ;
284+ } ) ) ;
285+
270286 this . _toDispose . push ( this . textAreaHandler . onCompositionEnd ( ( e ) => {
271287 this . textArea . actual . style . height = '' ;
272288 this . textArea . actual . style . width = '' ;
273289 StyleMutator . setLeft ( this . textArea . actual , 0 ) ;
274290 StyleMutator . setTop ( this . textArea . actual , 0 ) ;
275291 dom . removeClass ( this . viewHelper . viewDomNode , 'ime-input' ) ;
292+
293+ this . visibleRange = null ;
276294 } ) ) ;
277295 this . _toDispose . push ( GlobalScreenReaderNVDA . onChange ( ( value ) => {
278296 this . textAreaHandler . setStrategy ( this . _getStrategy ( ) ) ;
@@ -316,6 +334,10 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
316334
317335 public onScrollChanged ( e :editorCommon . IScrollEvent ) : boolean {
318336 this . scrollLeft = e . scrollLeft ;
337+ if ( this . visibleRange ) {
338+ StyleMutator . setTop ( this . textArea . actual , this . visibleRange . top ) ;
339+ StyleMutator . setLeft ( this . textArea . actual , this . contentLeft + this . visibleRange . left - this . scrollLeft ) ;
340+ }
319341 return false ;
320342 }
321343
0 commit comments