Re: Simplifying element creation

On Mon, Nov 14, 2011 at 7:04 PM, Ojan Vafai <ojan@chromium.org> wrote:
> With a browser-provided html quasi-literal, this could be:
> var table = html'<table><tbody></tbody></table>';
> for (var i = 0; i < labels.length; i++) {
>     table.childNodes[0].append(html'<tr>
>         <td>${labels[i]}</td>
>         <td>
>             <span class="bar" style="width:${some expression}%"></span>
>             <span class="value-container">${values[i]}</span>
>         </td>
>     </tr>');
> }
> element.append(table);

This seems like it's clearly the best solution proposed so far.  It's
hard to come up with a syntax for DOMs that's more concise or familiar
than HTML.  It's worth pointing out that if this returns a
DocumentFragment, it's actually impossible for authors to use string
concatenation -- the *only* way for them to embed variable quantities
is by the ${} syntax, which will auto-escape.  So this would really be
superb for preventing XSS.

It's also worth pointing out that sadly, running an HTML parser on
<tr> with no context node will simply make the <tr> disappear, so this
particular case would completely fail.  If the html quasi-function
uses the existing HTML parser without adjustment, you'll append a
bunch of spans and text nodes directly to the <tbody>, with no <tr> or
<td>.  There's discussion in another thread (I can't remember which
list) about how best to handle this for DocumentFragment.innerHTML,
which is relevant here.  It's not so simple to add a new magic
insertion mode that picks the right insertion context automatically,
particularly when you mix in SVG.

But I think this syntax is far more concise and readable than anything
else proposed so far, and it's also likely to be the most efficient
(only one function call).  This is the only kind of syntax that will
actually displace innerHTML and all its XSS problems.

(There is one aspect in which innerHTML might be better: if you're
adding hundreds of thousands of rows, it's going to be much faster to
run the HTML parser once instead of hundreds of thousands of times.
Is the idea that it's also possible to call the html quasi-function on
an arbitrary string you build, so you can resort to string
concatenation if you really need to?)

Received on Tuesday, 15 November 2011 19:07:28 UTC