[whatwg] [webcomponents] Template element parser changes => Proposal for adding DocumentFragment.innerHTML
Tab Atkins Jr.
jackalmage at gmail.com
Fri May 4 17:29:58 PDT 2012
On Fri, May 4, 2012 at 3:26 PM, Ian Hickson <ian at hixie.ch> wrote:
> On Fri, 4 May 2012, Rafael Weinstein wrote:
>> On Fri, May 4, 2012 at 2:46 PM, Ian Hickson <ian at hixie.ch> wrote:
>> > On Fri, 4 May 2012, Rafael Weinstein wrote:
>> >> This is the current proposal:
>> >> http://lists.w3.org/Archives/Public/public-webapps/2012AprJun/0334.html
>> > I don't really understand the proposal.
>> > How does it relate to the template feature?
>> The contents of <template> need to parse context-free (or implied
>> context, or whatever). This adds the notion to HTML parsing so that
>> <template> can use it.
>> e.g. <template><tr><td>Foo</td></tr></template>
> I don't understand how this would work in the parser. The parser doesn't
> have a "context element" concept, that's only for fragment parsing. If you
> reset the insertion mode in the parser, it uses the stack of open
> elements, which would always be a <template> element in this case when
> you parse the <tr>.
It doesn't seem overly difficult to adapt. For <template>, you'd
adapt the language to use the same machinery (scan forward to the
first start tag, decide how to parse the contents based on that), and
that's about it. It's similar, conceptually, to the text-in-<table>
part of the parser.
The precise proposal that Raf made doesn't *directly* help <template>,
since it does need to be lightly adapted, but it solves a related
case, and once we agree how that related case should be solved,
<template> should work the same way. It's the same problem once
you're a few steps away, it just looks a little different when you're
knee-deep in parser.
>> > What does it do in the case of:
>> > var frag = document.createDocumentFragment();
>> > frag.innerHTML = 'bla bla .. 1GB of text .. bla <caption> bla' ?
>> Queue up pending tokens until you see the first start tag token or the
>> end of file. The webkit implementation is here:
> frag.innerHTML = 'bla bla .. 1GB of text .. bla <caption> bla';
> ...results in a document fragment with one node containing " bla", while:
> frag.innerHTML = 'bla bla .. 1GB of text .. bla <caqtion> bla';
> ...results in a document fragment with a 1GB text node, an unknown element
> <caqtion>, and another text node?
> That seems pretty weird.
Blame <caption> for being weird. ^_^ All the other in-table elements
work more sanely, and will preserve the preceding text node. Shrug.
That's just how HTML parsing works.
(If you're trying to fill in a fragment of a table, and you have
free-floating text, you're doing something wrong anyway. Getting a
weird result isn't a huge deal, but it's nice to be consistent with
the rest of the parser rather than trying to do something "smart".)
>> > Why do we imply a tbody if the input is "<tr></tr><div></div>"?
>> Because there's nothing better to do.
> I think almost anything else would be better. :-)
> In particular, I think having the output be a <tr> element and <div>
> element as siblings would be better, as would having the output be just a
> <tr> element or just a <div> element.
You may have missed a reply. Raf corrected himself - no <tbody> is
implied there. Instead, you get a <tr> and a <div> as siblings,
because you start parsing in the "in-table-body" mode, and that's
exactly what the parser produces.
>> > Since you need the context element to know how to initialise the
>> > tokeniser, how do you find the first tag?
>> You always start in the DATA state. Can you think of a case where this
>> won't work?
> You describe the change as a "mere addition", but it sounds much more
> invasive than that if you're going to assume a context element and then
> change it later.
> It sounds like what you're really proposing is not to change the context
> element but to have the parser start off in some new mode where we just
> wait for the first open tag, and then we do some substitution to get a
> surrogate node, and try to reset based on that surrogate node's name
> instead of the stack of open elements.
> That seems pretty weird to me, but certainly isn't the weirdest thing
> that's been proposed.
It's basically equivalent to the mechanism in the "in-table" insertion
mode, where you collect all the character tokens you see until you
reach a start-tag, at which point you make a decision about what to do
with the stuff you've collected so far.
We could much more closely match the "in-table" insertion mode's
action, and directly state what to do with the collected stuff, but
there are a lot more possibilities there. It's easier conceptually
(and less likely to produce bugs down the line if things drift out of
sync) to instead treat it as an initial scan, and then a complete
reparse in a different mode.
The description you give in the second-to-last paragraph in the quote
I'm responding to sounds more-or-less right. Doing stuff based on the
first start tag rather than the stack of open elements is *exactly*
what you want to do for <template>, since <template> *doesn't imply
anything about its contents*. All you know is that its contents are
intended to go *somewhere else*, eventually, so you should parse them
in the friendliest way you can to support the ability to easily put
them somewhere else later.
> Do we have a page or e-mail somewhere that documents all the cases we're
> trying to support?
For Raf's exact proposal, the use-case is precisely what jQuery does -
easily create a bunch of HTML from a string, like you can do with
innerHTML, but the "bunch of HTML" might be intended to be, say, the
contents of a <tr>. You can't just directly use innerHTML unless you
first scan for an appropriate context element, which is easily buggy.
For the closely-related implicit proposal for the "in-template"
parsing mode, it's almost the same, except not from a string - you
want to create a bunch of HTML for use elsewhere, where the content
might be elements that would normally be handled by a special parsing
More information about the whatwg