Generally Firebug tries to get in to the page as early as possible.
Based on the above, DOMContentLoaded does trigger some Firebug actions,
but mostly minor ones. However I learned from Boris on Bug 536379 that
events like DOMNodeInserted are not expect before DOMContentLoaded has
fired. Are there other differences before that event?
jjb
That's not quite right. DOMNodeInserted is not fired for nodes inserted
by the parser. DOMContentLoaded fires at the point when the parser is
done with the document. So after DOMContentLoaded, you can expect to
see mutation events for all mutations to the document; before that you
can't have such an expectation.
Scripted mutations to the document will trigger mutation events even
before DOMContentLoaded has fired, of course.
> Are there other differences before that event?
That event just indicates that the parser is done with the document.
Before this event, document.write works differently (though this might
change in the HTML5 parser) and DOM mutations can interact weirdly with
the parser before DOMContentLoaded has fired (but not after, since
there's no parser after).
Those are the main differences off the top of my head, but any other
differences would also be due to the fact that the parser is still
running before DOMContentLoaded.
-Boris
I was confused by the "can't have such an expectation" followed by "of
course". I guess you mean:
Scripted mutations to the document trigger mutation events at all times.
Parser mutations may not trigger mutations events before DOMContentLoaded.
jjb
Yes.
> Parser mutations may not trigger mutations events before DOMContentLoaded.
"Do not", rather than "may not". They never trigger mutation events.
DOMContentLoaded just tells you that there will be no more parser
mutations for that document after that point (modulo document.open, of
course).
-Boris
So what about setting element.innerHTML and all other ways that look
like parsing is going on?
jjb
What other ways? innerHTML parses into a new document (or more
precisely document fragment), then inserts the nodes into your original
document via a DOM insertNode call. That call triggers mutation events
as needed. The HTML5 spec makes this pretty explicit.
-Boris
Ok good, I think we have sorted this out in Firebug, but we need a test
case we can rely on. How can we ensure that DOMContentLoaded is fired no
sooner than 400ms in a simple page? Load a script from an non-existent
server?
jjb
No, that wouldn't work. These would:
<script src="some-cgi-script-that-sleeps-for-more-than-400ms">
(or equivalent with httpd.js).
<script>
var start = new Date;
var end = new Date;
while (end - start < 400) {
end = new Date;
}
</script>
(Of course with the latter there's no guarantee that you'll get back to
the event loop before DOMContentLoaded...).
-Boris
> Before this event, document.write works differently (though this might
> change in the HTML5 parser)
It's unsafe to use DOMContentLoaded to make decisions about whether to
call document.write() when the HTML5 parser is enabled. When the event
has fired, it's clearly unsafe to call document.write(), but before the
event has fired, it is still unsafe to call document.write() in many
cases.
It is safe to call document.write() when the script execution is caused
by a </script> end tag getting parsed by a parser associated with the
same document object when the script element doesn't have the async or
defer attributes set. All other places (event handlers, timeouts, XBL
bindings, sync XHR nested event loops, async scripts, defer scripts,
etc.) are unsafe.
--
Henri Sivonen
hsiv...@iki.fi
http://hsivonen.iki.fi/
So I guess all the pages that do document.write() now in the unsafe
cases will have workaround this change?
In the unsafe cases, what happens? How does the developer learn it is
unsafe?
jjb
It turns out there are very few such, because those unsafe cases blow
the page away in other browsers already.
> In the unsafe cases, what happens?
The old document content all goes away and is replaced by the string you
passed to write().
> How does the developer learn it is unsafe?
Either looking at the spec, or trying it and it failing.
Note that this is preferable to what we have now, in Gecko, since it
will _consistently_ fail. Right now it might or might not in Gecko,
depending on the relative timing of DOMContentLoaded and whatever your
asynchronous stuff (event handler, XHR, etc) is doing.
-Boris