Attempt at synthetic keyboard events

I've tried creating synthetic keyboard events here. It works insofar as event handlers are fired. However, the synthetic events do not actually modify the contents of editable elements. :-/

by lddubeau

HTML

<div id="first"><div contenteditable="true"><div contenteditable="true"><div contenteditable="true">bar</div></div><div contenteditable="true"><div contenteditable="false">ttt</div>
<div tabindex="-1" contenteditable="true">
      foo
    </div></div></div><button id="first-do">Do</button></div>

<p>===</p>

<div id="second"><div contenteditable="true"><div contenteditable="true"><div contenteditable="true">bar</div></div><div contenteditable="true"><div contenteditable="false">ttt</div><div contenteditable="true">
      foo
    </div></div></div></div>

JavaScript

//
// This shows another problem with contenteditable.
//
// The steps are:
//
// 1. Put cursor just before the "f" of "foo" in the text before "==="
// 2. Hit backspace.
//
// Nothing happens.
//
// Try the same steps but this time in the text after "===".
// 
// The word "foo" will jump over "ttt".
//
function simulateKeyEvent(node, character) {
   //var evt = new KeyboardEvent("keypress", {bubbles: true, cancelable: true, which: 8, charCode: 0});
  var evt = document.createEvent("KeyboardEvent");
  evt.initKeyEvent("keydown", true, true, window,
                    0, 0, 0, 0,
                    0, character.charCodeAt(0));
  node.dispatchEvent(evt);
  evt.initKeyEvent("keypress", true, true, window,
                    0, 0, 0, 0,
                    0, character.charCodeAt(0));
  node.dispatchEvent(evt);
  evt.initKeyEvent("keyup", true, true, window,
                    0, 0, 0, 0,
                    0, character.charCodeAt(0));
  node.dispatchEvent(evt);
}
function setCaret() {
    var $foo = $("#first div:contains('foo')").last();
    $foo.focus();
    var range = document.createRange();
    range.selectNodeContents($foo.get(0));
    range.collapse(true);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    simulateKeyEvent($foo.get(0).childNodes[0], "a");
}

$(function () {
    $("#first-do").click(setCaret);
    $("#first div:contains('foo')").last().keypress(function (ev) { console.log("blah"); });
});