Re: [webcomponents] Template element parser changes => Proposal for adding DocumentFragment.innerHTML

On Fri, May 11, 2012 at 1:01 AM, Ian Hickson <ian@hixie.ch> wrote:
> On Fri, 11 May 2012, Tab Atkins Jr. wrote:
>> while Element.create() is great, it solves a different use-case.  Being
>> able to construct DOM from raw HTML is easy to read and write and
>> understand, particularly when it's a static fragment (or a concatenation
>> of mostly static fragments), while Element.create() requires a
>> translation into a JS API with a much different syntax. Element.create()
>> is much more readable and writable when you're making some DOM out of a
>> *lot* of dynamic information.
>>
>> In other words, this:
>>
>> $("<div class=foo><img src="+foosrc+"></div>")
>>
>> is a lot easier than:
>>
>> Element.create("div", {class: "foo"}, [ Element.create("img", {src: foosrc}) ]);
>>
>> So, that's the use-case for this API.
>
> The idea of building elements using string concatenation is a security
> disaster. What if "foosrc" above contains '" onclick="...' ?

Why are you assuming that the var there comes from potentially-unsafe
user-provided data?  As I mentioned, a lot of the usage of this is
creating markup from static fragments, or from a concatenation of
mostly static fragments.


> But ok, let's assume that the use case is "create an element and its
> subtree so that you can insert dynamically generated parts of an
> application during runtime", e.g. inserting images in a dynamically
> generated gallery, and security by damned.

Security doesn't have to have anything to do with this.  The
dynamically generated sources could be purely script-generated,
providing request parameters that the server consumes.


> If we're going to do that, then we don't need any lookahead at all. We
> should support literally that: parsing one element and its descendants. We
> determine what element is being generatd by looking at the top of the
> string ("<div ..." -> it's a div, "<tr ..." -> it's a tr, etc), and we
> parse until that element is popped from the stack or the end of the string
> is reached. This avoids all the problems with doing magical lookahead.

This solves exactly the jQuery use-case of "parse a document fragment
from a string".

It doesn't solve the *almost* identical case of "parse the contents of
a <template>", because there you don't have a root element.  (But you
still have to know the appropriate context, for the same reasons.  And
that information is also still implicitly expressed in the data
already.)


> But I'm very skeptical about creating new APIs to encourage authors to use
> injection-prone, non-type-checked, direct string manipulation in script to
> generate DOM trees.

As others have said, you've lost this race. jQuery is the most popular
JS library in the world.  This particular functionality is used
*constantly* in jQuery; it's a very basic usage that is almost
impossible to avoid.  Simply put, this is a *very* popular API, and
authors will continue to use it no matter what you don't do.  We might
as well make it fast, easy, and complete.

~TJ

Received on Thursday, 10 May 2012 23:14:09 UTC