function TextAreaInput(host, textArea) {
            var _this = _super.call(this) || this;
            _this._onFocus = _this._register(new event_1.Emitter());
            _this.onFocus = _this._onFocus.event;
            _this._onBlur = _this._register(new event_1.Emitter());
            _this.onBlur = _this._onBlur.event;
            _this._onKeyDown = _this._register(new event_1.Emitter());
            _this.onKeyDown = _this._onKeyDown.event;
            _this._onKeyUp = _this._register(new event_1.Emitter());
            _this.onKeyUp = _this._onKeyUp.event;
            _this._onCut = _this._register(new event_1.Emitter());
            _this.onCut = _this._onCut.event;
            _this._onPaste = _this._register(new event_1.Emitter());
            _this.onPaste = _this._onPaste.event;
            _this._onType = _this._register(new event_1.Emitter());
            _this.onType = _this._onType.event;
            _this._onCompositionStart = _this._register(new event_1.Emitter());
            _this.onCompositionStart = _this._onCompositionStart.event;
            _this._onCompositionUpdate = _this._register(new event_1.Emitter());
            _this.onCompositionUpdate = _this._onCompositionUpdate.event;
            _this._onCompositionEnd = _this._register(new event_1.Emitter());
            _this.onCompositionEnd = _this._onCompositionEnd.event;
            _this._host = host;
            _this._textArea = _this._register(new TextAreaWrapper(textArea));
            _this._asyncTriggerCut = _this._register(new async_1.RunOnceScheduler(function () { return _this._onCut.fire(); }, 0));
            _this._textAreaState = textAreaState_1.TextAreaState.EMPTY;
            _this.writeScreenReaderContent('ctor');
            _this._hasFocus = false;
            _this._isDoingComposition = false;
            _this._nextCommand = 0 /* Type */;
            _this._register(dom.addStandardDisposableListener(textArea.domNode, 'keydown', function (e) {
                if (_this._isDoingComposition && e.equals(109 /* KEY_IN_COMPOSITION */)) {
                    // Stop propagation for keyDown events if the IME is processing key input
                    e.stopPropagation();
                }
                if (e.equals(9 /* Escape */)) {
                    // Prevent default always for `Esc`, otherwise it will generate a keypress
                    // See https://msdn.microsoft.com/en-us/library/ie/ms536939(v=vs.85).aspx
                    e.preventDefault();
                }
                _this._onKeyDown.fire(e);
            }));
            _this._register(dom.addStandardDisposableListener(textArea.domNode, 'keyup', function (e) {
                _this._onKeyUp.fire(e);
            }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'compositionstart', function (e) {
                if (_this._isDoingComposition) {
                    return;
                }
                _this._isDoingComposition = true;
                // In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled.
                if (!browser.isEdgeOrIE) {
                    _this._setAndWriteTextAreaState('compositionstart', textAreaState_1.TextAreaState.EMPTY);
                }
                _this._onCompositionStart.fire();
            }));
            /**
             * Deduce the typed input from a text area's value and the last observed state.
             */
            var deduceInputFromTextAreaValue = function (couldBeEmojiInput) {
                var oldState = _this._textAreaState;
                var newState = _this._textAreaState.readFromTextArea(_this._textArea);
                return [newState, textAreaState_1.TextAreaState.deduceInput(oldState, newState, couldBeEmojiInput)];
            };
            /**
             * Deduce the composition input from a string.
             */
            var deduceComposition = function (text) {
                var oldState = _this._textAreaState;
                var newState = textAreaState_1.TextAreaState.selectedText(text);
                var typeInput = {
                    text: newState.value,
                    replaceCharCnt: oldState.selectionEnd - oldState.selectionStart
                };
                return [newState, typeInput];
            };
            _this._register(dom.addDisposableListener(textArea.domNode, 'compositionupdate', function (e) {
                if (browser.isChromev56) {
                    // See https://github.com/Microsoft/monaco-editor/issues/320
                    // where compositionupdate .data is broken in Chrome v55 and v56
                    // See https://bugs.chromium.org/p/chromium/issues/detail?id=677050#c9
                    // The textArea doesn't get the composition update yet, the value of textarea is still obsolete
                    // so we can't correct e at this moment.
                    return;
                }
                if (browser.isEdgeOrIE && e.locale === 'ja') {
                    // https://github.com/Microsoft/monaco-editor/issues/339
                    // Multi-part Japanese compositions reset cursor in Edge/IE, Chinese and Korean IME don't have this issue.
                    // The reason that we can't use this path for all CJK IME is IE and Edge behave differently when handling Korean IME,
                    // which breaks this path of code.
                    var _a = deduceInputFromTextAreaValue(/*couldBeEmojiInput*/ false), newState_1 = _a[0], typeInput_1 = _a[1];
                    _this._textAreaState = newState_1;
                    _this._onType.fire(typeInput_1);
                    _this._onCompositionUpdate.fire(e);
                    return;
                }
                var _b = deduceComposition(e.data), newState = _b[0], typeInput = _b[1];
                _this._textAreaState = newState;
                _this._onType.fire(typeInput);
                _this._onCompositionUpdate.fire(e);
            }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'compositionend', function (e) {
                if (browser.isEdgeOrIE && e.locale === 'ja') {
                    // https://github.com/Microsoft/monaco-editor/issues/339
                    var _a = deduceInputFromTextAreaValue(/*couldBeEmojiInput*/ false), newState = _a[0], typeInput = _a[1];
                    _this._textAreaState = newState;
                    _this._onType.fire(typeInput);
                }
                else {
                    var _b = deduceComposition(e.data), newState = _b[0], typeInput = _b[1];
                    _this._textAreaState = newState;
                    _this._onType.fire(typeInput);
                }
                // Due to isEdgeOrIE (where the textarea was not cleared initially) and isChrome (the textarea is not updated correctly when composition ends)
                // we cannot assume the text at the end consists only of the composited text
                if (browser.isEdgeOrIE || browser.isChrome) {
                    _this._textAreaState = _this._textAreaState.readFromTextArea(_this._textArea);
                }
                if (!_this._isDoingComposition) {
                    return;
                }
                _this._isDoingComposition = false;
                _this._onCompositionEnd.fire();
            }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'input', function () {
                if (_this._isDoingComposition) {
                    // See https://github.com/Microsoft/monaco-editor/issues/320
                    if (browser.isChromev56) {
                        var _a = deduceComposition(_this._textArea.getValue()), newState_2 = _a[0], typeInput_2 = _a[1];
                        _this._textAreaState = newState_2;
                        _this._onType.fire(typeInput_2);
                        var e = {
                            data: typeInput_2.text
                        };
                        _this._onCompositionUpdate.fire(e);
                    }
                    return;
                }
                var _b = deduceInputFromTextAreaValue(/*couldBeEmojiInput*/ platform.isMacintosh), newState = _b[0], typeInput = _b[1];
                if (typeInput.replaceCharCnt === 0 && typeInput.text.length === 1 && strings.isHighSurrogate(typeInput.text.charCodeAt(0))) {
                    // Ignore invalid input but keep it around for next time
                    return;
                }
                _this._textAreaState = newState;
                // console.log('==> DEDUCED INPUT: ' + JSON.stringify(typeInput));
                if (_this._nextCommand === 0 /* Type */) {
                    if (typeInput.text !== '') {
                        _this._onType.fire(typeInput);
                    }
                }
                else {
                    if (typeInput.text !== '') {
                        _this._onPaste.fire({
                            text: typeInput.text
                        });
                    }
                    _this._nextCommand = 0 /* Type */;
                }
            }));
            // --- Clipboard operations
            _this._register(dom.addDisposableListener(textArea.domNode, 'cut', function (e) {
                _this._ensureClipboardGetsEditorSelection(e);
                _this._asyncTriggerCut.schedule();
            }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'copy', function (e) {
                _this._ensureClipboardGetsEditorSelection(e);
            }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'paste', function (e) {
                if (ClipboardEventUtils.canUseTextData(e)) {
                    var pastePlainText = ClipboardEventUtils.getTextData(e);
                    if (pastePlainText !== '') {
                        _this._onPaste.fire({
                            text: pastePlainText
                        });
                    }
                }
                else {
                    if (_this._textArea.getSelectionStart() !== _this._textArea.getSelectionEnd()) {
                        // Clean up the textarea, to get a clean paste
                        _this._setAndWriteTextAreaState('paste', textAreaState_1.TextAreaState.EMPTY);
                    }
                    _this._nextCommand = 1 /* Paste */;
                }
            }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'focus', function () { return _this._setHasFocus(true); }));
            _this._register(dom.addDisposableListener(textArea.domNode, 'blur', function () { return _this._setHasFocus(false); }));
            return _this;
        }
Writes screen reader content to the textarea and is able to analyze its input events to generate:
 - onCut
 - onPaste
 - onType

Composition events are generated for presentation purposes (composition input is reflected in onType).