- From: Ojan Vafai <ojan@chromium.org>
- Date: Tue, 15 Nov 2011 11:32:35 -0800
- To: Aryeh Gregor <ayg@aryeh.name>
- Cc: Ryosuke Niwa <rniwa@webkit.org>, Anne van Kesteren <annevk@opera.com>, "www-dom@w3.org" <www-dom@w3.org>
- Message-ID: <CANMdWTu3HqHcOm34NvoMyiMU0N1vkaUyjuvfwvQg51GL4E7bSw@mail.gmail.com>
On Tue, Nov 15, 2011 at 11:06 AM, Aryeh Gregor <ayg@aryeh.name> wrote: > 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. > I believe preventing XSS was one of the primary use-cases driving the quasis spec. > 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. > Yes. I agree with Jonas on the other thread, we just need to define this and make it work in as sane a way as possible. Heh "just" :) To avoid splitting that part of the discussion on two threads, I was just assuming that the other thread would resolve how to make it work. :) > 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. > Agreed. Although, I share Ryosuke's sadness that it encourages having lots of whitespace textnodes everywhere in your DOM. Not sure what we could do about that. > (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?) > Kind of. The html is actually just a javascript function. So you could call it explicitly with the right object. You could write a simple function that would construct the right arguments for the html quasi function argument given an HTML string. So the following: var b = 0, d = 1; html`aaaa${b}cc\nc${d}eee` Desugars to: var $__0 = Object.freeze({ raw: Object.freeze(["aaaa", "cc\\nc", "eee"]), cooked: Object.freeze(["aaaa", "cc\nc", "eee"]) }); var b = 0, d = 1, f = function() { }; html($__0, b, d); And b and d are interleaved between the items in the array.
Received on Tuesday, 15 November 2011 19:33:44 UTC