[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 

> 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.


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