[whatwg] Should script run if it comes from a HTML fragment?

Jonas Sicking jonas at sicking.cc
Thu Nov 11 17:48:39 PST 2010

On Thu, Nov 11, 2010 at 4:34 PM, Ryosuke Niwa <rniwa at webkit.org> wrote:
> Greetings all,
> I'm working on the WebKit bug 12234 - Using createContextualFragment to
> insert a <script> does not cause the script to execute.  While investigating
> the issue, the following part of HTML5 spec came to my attention:
> The "in head" insertion mode
> ...
> A start tag whose tag name is "script"
> If the parser was originally created for the HTML fragment parsing
> algorithm, then mark the script element as "already started". (fragment
> case)
> Since 10.4 Parsing HTML fragments does not special case the script element,
> this seem to imply that we never execute scripts inserted by the HTML
> fragment parsing algorithm.  Am I right?
> To give you more concrete example, should the following markup show the
> alert or not?
> <!DOCTYPE html>
> <html>
> <script>
> document.body.innerHTML+="<scr"+"ipt>alert('SUCCESS')</scr"+"ipt>";
> </script>
> </html>

When setting .innerHTML browsers always have prevented any created
<script>s from running. We ended up copying this behavior from IE when
we originally implemented .innerHTML in firefox (then netscape) since
sites were relying on it.

In particular sites were doing things like

a.innerHTML = b.innerHTML;
a.innerHTML += "<b>what's up dog</b>";  (btw, perf-wise this is
terrible, but people do do it).

and in both cases fell over when scripts in a "re-executed". So your
example above should not alert if you want your browser to be
compatible with the web.

For range.createContextualFragment things are different though. (The
function returns a fragment, and so its obvious that script should
never execute *during* exeuction of createContextualFragment, the
question is if they should execute if that fragment is later inserted
in a document).

First off, there is no spec for createContextualFragment so there is
no spec text to turn to.

Second, there are a few reasons to keep scripts created using
createContextualFragment executable:
* Firefox has always left scripts created using
createContextualFragment as executable. So web compatibility would
speak for making the scripts executable.
* Other APIs that create fragments of content, such as the
XSLTProcessor.transformToFragment and createElement, create scripts
that are executable.
* It seems somewhat weird to single out script elements as being the
only ones to receive special treatment by disabling them. Things like
onclick attributes are still enabled.
* Since the API isn't a property, there is no possibility that people
will use the += operator to create confusion. It is still possible to
do something like range.createContextualFragment(a.innerHTML), but
arguably it's more likely that they'll use innerHTML all the way
* Since scripts don't execute synchronously from within
createContextualFragment the caller doesn't have to deal with weird
reentrancy issues during parsing.

For these reasons we decided to keep Firefox 4 behaving like previous
versions of firefox and allow scripts created using
createContextualFragment to execute.

/ Jonas

More information about the whatwg mailing list