title: How to undo changes made from script on contenteditable div
body: <p>Let's have contenteditable div. Browser itself manage undo on it.
  But when additional content changes (or touching selection ranges) are made from script (in addition to user action) then it stops behave as user expected.</p>
  <p>In other words when user hit Ctrl+Z then div content is not reverted to previous state.</p>
  <p>See following simplified artificial example:</p>
  <p><a href="https://codepen.io/farin/pen/WNEMVEB" rel="nofollow noreferrer">https://codepen.io/farin/pen/WNEMVEB</a></p>
  <pre><code>const editor = document.getElementById(&quot;editor&quot;)
  editor.addEventListener(&quot;keydown&quot;, ev =&gt; {  
    if (ev.key === 'a') {
      const sel = window.getSelection()
      const range = window.getSelection().getRangeAt(0)
      const node = range.startContainer;
      const value = node.nodeValue       
      node.nodeValue = value + 'aa'        
      range.setStart(node, value.length + 2)
      range.setEnd(node, value.length + 2)
      ev.preventDefault()
    }
  })
  </code></pre>
  <p>All written 'a' letters are doubled.</p>
  <p>Undo is ok as long as there is no 'a' typed.
  When user typed 'a' (appended to text as double 'aa') and hits Ctrl+Z, then he expects  both 'a' will be removed and cursor moves back to original position.</p>
  <p>Instead only one 'a' is reverted on undo and second one added by script remain.</p>
  <p>If event is also prevented by preventDefault() (which is not needed in this example, but in my real world example i can hardly avoid it) then all is worse.
  Because undo reverts previous user action.</p>
  <p>I could images that whole undo/redo stuff will be managed by script, but it means implementation of whole undo/redo logic. That's too complicated, possible fragile and with possible many glitches.</p>
  <p>Instead I would like tell browser something like that there is atomic change which should be reverted by one user undo. Is this possible?</p>