[whatwg] Fixing undo on the Web - UndoManager and Transaction

Ehsan Akhgari ehsan at mozilla.com
Tue Aug 2 15:02:58 PDT 2011

On 11-08-02 3:10 PM, Ryosuke Niwa wrote:
> 1. The definition of @undoscope seems to not address the question of whether
>> the document element should be an Undo Scope or not.
> Each document has its own undo scope:
> http://rniwa.com/editing/undomanager.html#undo-scope

Sure.  What I was specifically talking about is this sentence under 
section 2.1:

"On getting, it must return "false" if the element belongs to the 
ancestor's undo scope, and "true" if the element defines a new undo scope"

By this definition, it's ambiguous what needs to happen to the 
documentElement's undoScope attribute, since it doesn't have an element 
ancestor.  I think we should just clarify that in that case, the value 
is "true", and the undoManager attribute is the same as 

> 2. @undoscope seems to make it very hard to support the usecase of moving
>> the undo scope from an element to another.  (I'm not sure if that is a
>> concern that we need to address at all, though).
> Right, I don't support that use case.  But I couldn't think of a case where
> this is useful.  Also, I was concerned that this will make browser's undo
> management much harder since I don't know how Opera and IE manage undo
> transaction history.

Yeah, I also can't think of a use case -- just wanted to make sure that 
this omission is intentional (and I'm fine with it, FWIW).

> 3. In regard to "Should apply return a boolean value indicating whether it
>> successfully applied or not?", answering yes means that we should make sure
>> that we're going to be able to cleanly revert a transaction when it fails,
>> right?  Also, saying yes here means that we should decide what happens if
>> that transaction is in a transaction group.  ... all of which makes me want
>> to say no.  :-)
> Not necessary.  I think saying "yes" means that apply function returned
> "true", and we've successfully added new entry to the undoManager. i.e.
> apply nor DOM mutation handlers did something insane like removing
> undoManager or interfering with DOM mutation, etc...  Also, if we add
> editAction/transaction event, we may want to make it cancelable so that the
> entire transaction may be prevented (not individual mutations).
> So returning boolean will let websites figure out whether a transaction was
> really added to the list or not.

So, do you mean that if the method returns false, it is responsible for 
doing any cleanups itself?  If so, that sounds good to me.

> 4. In regard to "Need to restore selection as well", is that something which
>> we want all the time?  Imagine an "indent" transaction which indents a
>> paragraph by increasing its start margin, should it change the selection
>> when it's undone?
> Oh, so what I mean is that selection needs to be restored to the state
> before the transaction was applied.  e.g. when I select then delete "hello
> world" and undo, I should be selecting "hello world".

I agree.  But what I was trying to point out that some for some editing 
operations, resetting the selection after an undo operation might not 
make sense.  Do you think selection restoring should be enforced for all 
editing operations?

> 5. I have serious doubts about the current specification of manual
>> transactions.  I don't know why we need to exclude them from group
>> transactions, but honestly, I'm not sure why we need to have them at all.
>>   What use cases are we trying to address by manual transactions that would
>> otherwise be impossible to address with managed transactions?
> In collaborative editing apps, it's infeasible for the UA to manage undo
> transaction history because their undo history will be a tree, or an
> arbitrary graph.  Also if you wanted to make an app that modifies both
> contenteditable region and canvas, you'll almost certainly need to modify
> canvas by script manually and yet you may want to let UA manage the undo
> transaction history of text fields.
> And the reason scripts want to use manual transaction as supposed to just
> modifying document, is to update UA's native UI.  Without manual transaction
> or a comparable mechanism, UA won't be able to enable undo/redo menu items
> or show a list of undoable items in their menu.

Hmm, OK.  But why should we exclude them from group transactions, for 
example?  I mean, I think that manual transactions are merely 
transactions with custom unapply/reapply methods, right?

> 6. I think if we want to address selection saving/restoring, that part
>> belongs to the "Mutation of DOM" section.  We might also need to address
>> some other editing related stuff in the DOM state, such as the keyboard
>> layout language, selection, etc.
> That's a good point.  I'd have to look into what each UA does and what needs
> to be preserved.  Aryeh, do you have any idea as to what UAs do for native
> editing actions?

Note that there may be some broken stuff in existing implementations. 
For example, currently if you change your keyboard language, type 
something in Gecko, and then undo the typing, the keyboard language is 
not restored.  But it's not exactly clear to me what the right thing to 
do in that case would be...

> 8. As a last comment, I think a better name for UndoManager is
>> TransactionManager, since, well, that's what it really is!  :-)
> Alternatively, we can change the name "transaction" to something else
> because "transaction" sounds too general.

Agreed.  Although I don't have a better suggestion for that name myself. 

Also, there is something that I forgot to mention before.  Are we going 
to also address the plain text editable fields in the UndoManager spec 
too?  We have a couple of options here:

1. Ignoring text inputs/textareas in this spec completely.
2. Specify a default value of "true" for the undoScope attribute on 
those elements, and let their undo managers be managed by the same 
machinery as that of any other element.  Under the hoods we can just use 
textual diffs as the transaction items.  This might be very useful for 
things like wiki editors which have custom editing commands.  We should 
also specify what happens when undoScope is set to false on those 
elements, should their undo history be managed by the nearest ancestor 
which has undoScope set to true?

Another thing which just came to my mind: are we going to support the 
use case of web page content completely disabling the undo history?


More information about the whatwg mailing list