1 Introduction

Many rich text editors on the Web add editing operations that are not natively supported by execCommand and other Web APIs.
For example, many editors make modifications to DOM after an user agent executed user editing actions to work-around user agent bugs
and to customize for their use.

However, doing so breaks user agent's native undo and redo because the user agent cannot undo DOM modifications made by scripts.
This forces the editors to re-implement undo and redo entirely from scratch, and many editors, indeed, store innerHTML as string and recreate
the entire editable region whenever a user tires to undo and redo. This is very inefficient and has limited the depth of their undo stack.

Also, any Web app that tries to mix contenteditable region or text fields with canvas or other non-text editable regions will have to
reimplement undo and redo of contenteditable regions as well because the user agent typically has one undo transaction history per document,
and there is no easy way to add new undo entry to the user agent's native undo transaction history.

This specification tries to address above issues by providing ways to define undo scopes, add items to user agent's native
undo transaction history, and create a sequence of DOM changes that can be automatically undone or redone
by user agents.

The undo scope is the collection of DOM nodes that are managed by the same UndoManager.
A document node or an element with undoscope attribute defines a new undo scope,
and all descendent nodes of the element, excluding elements with and descendent nodes of elements with undoscope attribute,
will be managed by a new UndoManager.
An undo scope host is an element with with undoscope attribute or the document.

2.2 Undo scope

When the undoscope content attribute is added, the user agent must define new undo scope for the element,
and the user agent must create a new UndoManager to manage any DOM changes made to all descendent nodes of
the element excluding ones that have the undoscope content attribute and their descendent nodes.

When the undoscope content attribute is removed, the user agent must remove all entries in the undo transaction history
of the corresponding undo scope without unapplying them and destroy the corresponding UndoManager for the scope.
After the removal, the node from which the content attribute is removed and their descendent nodes, excluding elements with and descendent nodes of elements with
the undoscope content attribute, belong to the undo scope of the closest ancestor with
the undoscope content attribute or of the document.

A typical use case for a transaction group is typing where insertions of multiple letters, spaces, and new lines can be undone or redone in one step.

When transactions in a transaction group are unapplied,
the user agent must unapply each transaction in the array that forms the transaction group in the ascending order
from the first entry to the last entry.
When transactions in a transaction group are reapplied, the user agent must
reapply each transaction in the array in descending order from the last entry to the first entry.

When the first undo is executed immediately after this code is ran, the last two transactions are unapplied,
and the br element and string "hi" will be removed from the DOM. The second undo will unapply the first two transactions and remove "o" and "k".

Because Mac OS X and other frameworks expect applications to provide an array of undo items, simply dispatching undo and redo events
and having scripts manage undo transaction history would not let the user agent populate the native UI properly.

label attribute must return null or a string that describes the semantics of the transaction such as
"Inserting text" or "Deleting selection". The user agent may expose this string or a part of this string through its native UI such as menu bar or context menu.

apply, unapply, and
reapply are attributes that must be supported, as IDL attributes, by objects implementing
the Transaction interface.

It is the editing host of the lowest common ancestor of nodes mutated by the transaction if there is one.
Otherwise, it is the lowest common ancestor of nodes mutated by the transaction. For the purpose of determining a whether a transaction mutates a node or not, inserting, removing, or replacing a child node
is considered to be modifying the node.

For example, if an automatic transaction mutates a node inside a contenteditable div, then the highest node affecting this automatic transaction is the div.
If the transaction also temporarily removes the div and inserts back to where it was, then the highest node affecting it is the parent of the div.

TODO: Need to specify what happens if event listeners on DOM mutation events attempts to modify DOM during apply, unapply, or reapply.

3.4 Manual transactions

A manual transaction is a transaction where the logic to
apply, unapply, or reapply
the transaction is explicitly defined by an application.
It provides a way to communicate with user agent's undo transaction history, e.g. to populate user agent's undo menu.

When a manual transaction is applied, the function returned by the apply attribute is
invoked with isReapply set to false if the attribute returns a valid function object.

When a manual transaction is unapplied, the function returned by the unapply attribute
is invoked if the attribute returns a valid function object.

When a manual transaction is reapplied, the function returned by the reapply attribute
is invoked if the attribute returns a valid function object. If the reapply attribute returned null or undefined,
then the function returned by apply attribute is invoked with isReapply set to true instead
if the attribute returns a valid function object.