- From: Alex Vincent <ajvincent@gmail.com>
- Date: Sat, 9 Apr 2011 19:23:51 -0700
I'm working on DOM-based editing tools in my spare time, and have been for several years. I use DOM mutation events to build "transactions" - objects which let me undo DOM mutations and redo them. There's a strong suggestion that DOM mutation observers should replace DOM mutation events altogether, for performance reasons. I believe a recent discussion on execCommand brought this to light again. Also, Mozilla has a bug on file (https://bugzilla.mozilla.org/show_bug.cgi?id=641821 ) to implement mutation observers which only receive a node ( http://lists.w3.org/Archives/Public/public-webapps/2009AprJun/0745.html ). For me, this presents a problem: In order to build undoable and redoable DOM transactions, I need some way of extracting a "before" and an "after" state for each individual mutation that happens. For all the ballyhoo about mutation events being evil, this is one thing that they do very well, with "prevValue" and "newValue" properties for attribute and data nodes, and with a "relatedNode" property for node insertions and removals. The proposed mutation observer model does not provide that information. I hope there may be some room to negotiate (either with WHATWG or Mozilla) on the interfaces. Without "before" and "after" states exposed through the DOM somehow, I can't make my editor project work, period. --- Now, I was until today unaware of HTML5's UndoManager in section 8.8 ( http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#undo). Maybe that gets me part of the way there, since it potentially tracks changes to a document. In particular, I note there's no tests or sample JS code for it written yet. I'd like to take a closer look at the interfaces there. For comparison, I'd like to mention Mozilla's nsITransaction interfaces, including nsITransactionManager - one of the nicest ideas for an editor, and one that's worked well for Mozilla's editors, including HTML inputs and textareas, for over ten years. (They're good enough that they've largely escaped attention - very few people think about the interfaces, because the editor's undo mechanism Just Works!) See http://mxr.mozilla.org/mozilla-central/find?text=&string=nsITransaction for references. A few thoughts on UndoManager: * First, I really like the add() method. That sounds really useful, especially if it's scriptable, because I see myself having custom transactions which I may want to track through a document's UndoManager. * The title is even more important - it would give people a way to see a localized description of what the transaction is. Though I personally think it should not be a separate value - I think it should be a required property of the undo object. (This is one thing I actually hate about Mozilla's transaction interfaces: they didn't make it easy to label transactions.) * I'm not so sure about the remove() method. Why do we have it? If we allow removing items by index, would we want to have a splice() method that lets scripts insert items at a given index? * Naturally, UndoManager sounds a lot like nsITransactionManager. * I wonder about configuring UndoManager by script. For instance, I really want to turn UndoManager on or off by script. (Most of the time, users won't care about UndoManager, so I would think it would be disabled by default, not actively recording transactions.) Or, I may want to track attribute changes, but not node value changes. * I think a diagram clarifying the flow of actions through UndoManager would be helpful. Is it UndoManager.add(data) -> data.doSomething() (which changes the document), or the other way around? How would this affect custom actions being added through UndoManager.add()? * For undo objects added by script, how would the UndoManager tell the scripted undo object to, well, undo something? Or redo something? (In particular, in such a way that the UndoManager doesn't record changes happening while the undo object changes the document in an operation.) * Is it feasible to have an UndoManagerObserver which is notified of undo objects being passed through the UndoManager (either in enabled or disabled state)? That would make it possible to manage undo objects in another context besides the UndoManager (example: I want to export undo objects to a Mozilla transaction manager, so that I drive it from there). * I'm surprised that UndoManager doesn't have a maxlength. Do we really intend to let it undo an infinite number of actions? I hope to open a debate on the UndoManager section, and on undo/redo operations in general, with this e-mail. Alex Vincent San Leandro, CA author, Verbosio XML editor project (in development hell for six years and counting!) -- "The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own." -- Alexander J. Vincent, June 30, 2001
Received on Saturday, 9 April 2011 19:23:51 UTC