[whatwg] Fixing undo on the Web - UndoManager and Transaction
rniwa at webkit.org
Tue Jul 26 23:34:54 PDT 2011
In the last couple of weeks, I've been working with developers of CKEditor,
TinyMCE, and Google Docs to come up with *new API for undo and redo*.
Why? Because* undo and redo are broken on the Web today*. Whenever Web apps
try to add a custom editing operation without using execCommand or do a "fix
up" after browser executes a user editing action, user agents get confused
by DOM mutations made by the apps and won't be able to undo or redo user
editing actions and execCommand. This forces Web apps to re-implement undo
and redo themselves, and in fact, *many rich text editors store innerHTML of
a contenteditable element* as a string in their internal undo transaction
history (a.k.a undo stack).
Also, there's no way for Web apps to add new undo item and populate undo and
redo menus on user agent's native UI. In addition, if an editor app has a
widget with input/textarea, then the undo stack of the editor gets confused
when the widget goes away because the undo transaction history exists only
In order to solve above and numerous other problems, we've come to a
conclusion that we need to *add UndoManager and Transaction*.
*UndoManager* is an interface for managing undo transaction history. It
exists on a document and an element with the *undoscope* content attribute.
UndoManager applies new transaction (i.e. make undoable DOM changes) and
manage them. The main purpose of UndoManager is to communicate the list of
undoable items with the user agent so that the user agent can provide a
native UI (e.g. populating menu items with them).
A *transaction* is a collection of DOM mutations that can be applied,
unapplied, or reapplied. UndoManager manages transactions and execute
unapply and reapply upon undo and redo respectively.
There are two types of DOM transactions:
- *Managed transaction* - the app supplies apply() and the user agent
automatically takes care of undo and redo. It is *compatible with user
editing actions and editing commands*, and allows Web apps to easily add
new editing operations or fix up DOM after user editing actions or editing
commands and still have the user agent manage the undo and redo.
- *Manual transaction* - the app supplies apply(), unapply(), and
reapply() and *the app takes the full control of undo and redo*. However,
it is NOT compatible with user editing actions, editing commands, or managed
transactions, meaning that, the user agents won't be able to undo or redo
them. This transaction is useful for apps such as a collaborative editor
that implements domain-specific undo or redo.
You can see more concrete definitions of UndoManager and Transaction at:
https://rniwa.com/editing/undomanager.html and see a list of uses cases at
https://rniwa.com/editing/undomanager-usecases.html. The documents are
incomplete and I need your feedback in order to refine details.
More information about the whatwg