- From: David Flanagan <dflanagan@mozilla.com>
- Date: Wed, 20 Jul 2011 13:18:09 -0700
- To: Ryosuke Niwa <rniwa@webkit.org>
- CC: Aryeh Gregor <Simetrical+w3c@gmail.com>, public-webapps@w3.org
- Message-ID: <4E273801.50205@mozilla.com>
On 7/20/11 12:11 PM, Ryosuke Niwa wrote: > On Wed, Jul 20, 2011 at 11:56 AM, Aryeh Gregor > <Simetrical+w3c@gmail.com <mailto:Simetrical%2Bw3c@gmail.com>> wrote: > > On Wed, Jul 20, 2011 at 1:43 AM, David Flanagan > <dflanagan@mozilla.com <mailto:dflanagan@mozilla.com>> wrote: > > Finally, I still think it is worth thinking about trying to > model the > > distinction between removing nodes from the document tree and > moving them > > (atomically) within the tree. > > I'll chip in that I think this is useful. It makes things somewhat > more complicated, but remove/insert and move are conceptually very > different. > > > But internally, a node movement is a removal then an insertion. > There's always possibility that a node gets removed then inserted > again after mutation observers are invoked. Also, what happens if a > function removed a bunch of nodes and then inserted back one of them? > My definition of moving a node atomically is taking a node that is already in the tree and passing it to appendChild() or insertBefore(). Everything else is regular node removal followed by node insertion. If you get a mutation event that says that node A was removed from node B and inserted into node C, you know nothing about the state of node A, since it could have been mutated while it was outside of the tree and no mutation events would have been recorded. Its attributes, text and children all could have changed, so the mutation listener has to basically discard everything it knows about node A and treat it as a brand-new node. If, on the other hand, there was some way for the listener to know that the node was moved atomically, then it would know that it hadn't missed any mutation events and it could retain whatever cached state it had for node A, changing only the parent. Here's one possible way that the distinction between move and remove could be made: keep the added and removed lists of nodes exactly as they are now. But when a node is moved atomically, also add it to an array of moved nodes. Listeners that don't care about the move/remove distinction can just use the added and removed properties as in the current proposal. But listeners that do care can check any added or removed node against the moved array to see if it was an atomic move. Another approach that might work: define a "reparent" or "move" mutation event type. So when node A is moved from parent B to parent C, the mutations would be: [{target:A, type:"reparent"}, {target:B, type:"childList", removed:[A]}, {target:C, type:"childList", added:[B]}] To make this work, if an atomic move was followed by a removal, the reparent mutation would have to be removed from the list of mutations. David > e.g. say we have <div>hello<br>world<br>w3c<br></div> > > And we have a hypothetical function that does: > > 1. Remove all children of div > 2. Inserts "w3c" back after div. > > Then what should the list of mutations contain? Should it contain > 2 items one that says it removed "hello", "world", and 3 br's, and > then another one saying "w3c" moved? But then child nodes are not > all consecutive and scripts won't be able to infer where these > nodes were even if we provided offsets or before/after node. > > Should it contain 3 items, one that says "hello", "world" and the > first 2 br's are removed, then one for moving "w3c", and then > another one for removing the last br? But then UAs have to keep > reorganizing the list as the function modifies more DOM because > there is no way to differentiate "w3c" until it's inserted back > into DOM. > > > - Ryosuke
Received on Wednesday, 20 July 2011 20:18:47 UTC