[whatwg] DOM Range: redefining behavior under DOM mutation
Boris Zbarsky
bzbarsky at MIT.EDU
Mon Mar 28 17:05:22 PDT 2011
On 3/28/11 3:28 PM, Aryeh Gregor wrote:
> If a node is moved to a position "immediately before" its original
> position
One problem here is that there is not a concept of "moved" in the DOM.
There's just removed and inserted. Trying to insert something that
already has a parent will remove it and then do the insert. Thanks to
the wonders of mutation events and userdata, script can execute in state
when the node being moved is not in the DOM, which means that ranges
need to update separately for the removal and insertion because the
state of the range in the intermediate state with the node outside the
DOM needs to be well-defined.
Now if we dropped support for mutation events and userdata handlers
first.....
> How is it actually implemented?
Gecko's implementation of A.insertBefore(B, C), in pseudocode and
ignoring all the sanity-checking and for cases when B is not a document
fragment is:
if (B.ownerDocument != A.ownerDocument) {
A.ownerDocument.adoptNode(B); // This can run arbitrary script
}
if (B.parentNode) {
B.parentNode.removeChild(B); // This can run arbitrary script
}
// Mutate the child storage of A to put B in the child list; notify
// observers
Both the removeChild call and the mutation of A's child list notify
mutation observers. Ranges are mutation observers, and use the
notifications to update themselves. So from the point of view of a
range, the removal and insertion are two distinct events.
-Boris
P.S. I suspect that actual interoperability for the edge cases of this
stuff is poor: nothing defines whether the adopt happens before the
removeChild above, nothing defines what happens if user data handlers or
mutation events mutate the DOM, etc.
More information about the whatwg
mailing list