lib/assets/scripts/vendor/codemirror/codemirror.js
function readInput(cm) {
    var input = cm.display.input, prevInput = cm.display.prevInput, view = cm.view, sel = view.sel;
    if (!view.focused || hasSelection(input) || isReadOnly(cm)) return false;
    var text = input.value;
    if (text == prevInput && posEq(sel.from, sel.to)) return false;
    startOperation(cm);
    view.sel.shift = false;
    var same = 0, l = Math.min(prevInput.length, text.length);
    while (same < l && prevInput[same] == text[same]) ++same;
    var from = sel.from, to = sel.to;
    if (same < prevInput.length)
      from = {line: from.line, ch: from.ch - (prevInput.length - same)};
    else if (view.overwrite && posEq(from, to) && !cm.display.pasteIncoming)
      to = {line: to.line, ch: Math.min(getLine(cm.view.doc, to.line).text.length, to.ch + (text.length - same))};
    var updateInput = cm.curOp.updateInput;
    updateDoc(cm, from, to, splitLines(text.slice(same)), "end",
              cm.display.pasteIncoming ? "paste" : "input", {from: from, to: to});
    cm.curOp.updateInput = updateInput;
    if (text.length > 1000) input.value = cm.display.prevInput = "";
    else cm.display.prevInput = text;
    endOperation(cm);
    cm.display.pasteIncoming = false;
    return true;
  }
function readInput(cm) {
    var input = cm.display.input, prevInput = cm.display.prevInput, view = cm.view, sel = view.sel;
    if (!view.focused || hasSelection(input) || isReadOnly(cm)) return false;
    var text = input.value;
    if (text == prevInput && posEq(sel.from, sel.to)) return false;
    startOperation(cm);
    view.sel.shift = false;
    var same = 0, l = Math.min(prevInput.length, text.length);
    while (same < l && prevInput[same] == text[same]) ++same;
    var from = sel.from, to = sel.to;
    if (same < prevInput.length)
      from = {line: from.line, ch: from.ch - (prevInput.length - same)};
    else if (view.overwrite && posEq(from, to) && !cm.display.pasteIncoming)
      to = {line: to.line, ch: Math.min(getLine(cm.view.doc, to.line).text.length, to.ch + (text.length - same))};
    var updateInput = cm.curOp.updateInput;
    updateDoc(cm, from, to, splitLines(text.slice(same)), "end",
              cm.display.pasteIncoming ? "paste" : "input", {from: from, to: to});
    cm.curOp.updateInput = updateInput;
    if (text.length > 1000) input.value = cm.display.prevInput = "";
    else cm.display.prevInput = text;
    endOperation(cm);
    cm.display.pasteIncoming = false;
    return true;
  }
prevInput is a hack to work with IME. If we reset the textarea on every change, that breaks IME. So we look for changes compared to the previous content instead. (Modern browsers have events that indicate IME taking place, but these are not widely supported or compatible enough yet to rely on.)