Re: [DOM4] atomicity of DocumentFragment insertion

On Fri, Oct 28, 2011 at 2:47 PM, David Flanagan <dflanagan@mozilla.com> wrote:
> I think the DOM4 spec should be clearer about the atomicity (or
> non-atomicity) of DocumentFragment insertion.  I assume that when a
> DocumentFragment is inserted, scripts should never be able to observe the
> document in state where some of the children of the fragment have been
> inserted and others have not.  But I don't think the spec currently states
> that anywhere, and I think it should.
>
> This may be an issue for mutation events, and it also turns out to be an
> issue for HTML script tags, which execute when children are inserted.  For
> example, what is the proper behavior of this code?:
>
>    // s and f are global variables
>    s = document.createElement("script");
>    document.head.appendChild(s);
>    f = document.createDocumentFragment();
>    f.appendChild(document.createTextNode("alert(s.text);
> alert(f.childNodes.length);"));
>    f.appendChild(document.createTextNode("alert(2);"));
>    f.appendChild(document.createTextNode("alert(3);"));
>    s.appendChild(f);
>    alert(s.text);
>
> Firefox runs the code in all 3 text nodes and displays 5 alerts total. The
> first and last alerts both contain the concatenated text of all three text
> nodes. The second alert display 0 because there are no children left in the
> document fragment.
>
> But Chrome, Safari and Opera run only the code in the first text node and
> display 3 alerts. The first alert displays only the first text node, the
> second alert displays 2 because one child has been moved from the fragment
> into the script, and the third alert displays all 3 text nodes.
>
> So, Firefox inserts the DocumentFragment atomically and the other browsers
> (I don't have a Windows installation to test IE) insert it non-atomically
> and allow the document to be observed in a partially inserted state.
>
> I've raised this issue (with a slightly simpler example) on the whatwg.org
> list:
> http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-October/033705.html
> but I suspect that DOM4 might actually be the right place to fix it.
>
> The DOM4 spec should either adopt language like "the document is never
> observable in a partially-inserted state" or it should simply define
> operations on document fragments using recursion so that it is clear that
> calling appendChild on a document fragment is exactly the same as
> sequentially calling appendChild on its children.

(cc'ing webapps as that's the proper list to discuss the DOM. Yes,
it's confusing).

This is very intentional behavior from Firefox side. Being able to
observe a partial insertion here creates all sorts of strange edge
cases. For example where do you insert nodes a fragment is
.insertBefore'ed and a "callback" rips out all inserted nodes as well
as any immediately surrounding nodes and insert them somewhere else in
the tree?

And what do you do if the callback adds or removes nodes in the
fragment when the fragment is half-way inserted.

It also requires defining things like are nodes inserted front-to-back
or back-to-front. And are they removed from the fragment one at a time
or all at once. Defining these cases might prevent implementations
from performing these operations in whatever order is the fastest for
them.

/ Jonas

Received on Friday, 28 October 2011 23:32:58 UTC