- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Mon, 28 Mar 2011 20:05:22 -0400
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.
Received on Monday, 28 March 2011 17:05:22 UTC