[whatwg] UndoManager: Nested transactions and execCommand

Ryosuke Niwa rniwa at webkit.org
Sun Mar 11 23:19:51 PDT 2012


Consider the following scenario:

<div id="um1" undoscope><span id="um2" undoscope></span></div>
um1.undoManager.transact({ // transaction 1
 executeAutomatic: function() {
 um2.undoManager.transact({ // transaction 2
   executeAutomatic: function () {
     um2.appendChild(document.createTextNode('In um2')); // statement 1
     um1.appendChild(document.createTextNode('In um1')); // statement 2

In this case, the DOM mutation made by the statement 1 will be managed by
the undo manager of um2. The DOM mutation made by statement 2 won't be
managed by the same undo manager because the mutation happens outside of
the undo scope it manages [1].

However, because we're still in the process of applying the transaction 1
and therefore the DOM mutation made by the statement 2 becomes part of the
transaction 1.

This behavior is very subtle and counter-intutive.  To get rid of this
rather unintuitive behavior, I propose that we prohibit nested
transactions.  Meaning that while executing any transaction, script cannot
create any new transaction elsewhere in the page. (Note that UndoManager
spec already prohibits nested transactions in the same undo scope.)

An interesting consequence of this proposal is that, it will also get rid
of nested executions of execCommand since execCommand needs to be
implemented as a DOM transaction.

[1] http://rniwa.com/editing/undomanager.html#automatic-dom-transactions

Ryosuke Niwa
Software Engineer
Google Inc.

More information about the whatwg mailing list