Re: innerHTML in DocumentFragment

On Thu, Nov 10, 2011 at 3:43 AM, Henri Sivonen <hsivonen@iki.fi> wrote:
> On Fri, Nov 4, 2011 at 1:03 AM, Yehuda Katz <wycats@gmail.com> wrote:
>> It would be useful if there was a way to take a String of HTML and parse it
>> into a document fragment. This should work even if the HTML string contains
>> elements that are invalid in the "in body" insertion mode.
>> Something like this code should work:
>>   var frag = document.createDocumentFragment();
>>   frag.innerHTML = "<tr><td>hello</td></tr>"
>>   someTable.appendChild(frag)
>
> It's easy for me to believe that there are valid use cases where the
> first tag encountered is <tr>.
>
>> This would probably require a new, laxer insertion mode, which would behave
>> similarly to the body insertion mode, but with different semantics in the "A
>> start tag whose tag name is one of: "caption", "col", "colgroup", "frame",
>> "head", "tbody", "td", "tfoot", "th", "thead", "tr"" case.
>
> What are the use cases for having this work with <head> and <frame> as
> first-level tags in the string? Do you also want it work with <html>,
> <body> and <frameset>?
>
> What about SVG and MathML elements?
>
> I totally sympathize that this is a problem with <tr>, but developing
> a complete solution that works sensibly even when you do stuff like
> frag.innerHTML = "<head></head>"
> frag.innerHTML = "<head><div></div></head>"
> frag.innerHTML = "<frameset></frameset>a<!-- b -->"
> frag.innerHTML = "<html><body>foo</html>bar<tr></tr>"
> frag.innerHTML = "<html><body>foo</html><tr></tr>"
> frag.innerHTML = "<div></div><tr></tr>"
> frag.innerHTML = "<tr></tr><div></div>"
> frag.innerHTML = "<g><path/></g>"
> is a much trickier problem than you <tr> example makes it first seem.
>
> Do you have use cases for tags other than <tr> appearing as the outermost tag?
>
> What would you expect the my examples above to do and why?

I don't think we should make up rules for where it makes sense to
insert DOM and where it doesn't. After all, we support .innerHTML on
all HTML elements (and soon maybe all Elements), and not just a subset
of them, right?

And requiring that a context node is passed in in all cases when HTML
is parsed is terrible developer ergonomics.

And yes, this does create a lot of edge cases which needs to be
defined. But the goal should be to make sane calls sane, that seems
imminently possible. So

frag.innerHTML = "<g></g>";
someSVGElement.appendChild(frag);

seems very possible to make work. And yes, it will mean that if
someone does something crappy like:

frag.innerHTML = "<g></g><div></div>";
someSVGElement.appendChild(frag);

then things will not behave sane. But as long as browsers behave
consistently this doesn't seem like a terrible situation. We have
after all the exact same problem with .innerHTML.

someTableElement.innerHTML = "<tr>...</tr><div></div>";

will just drop the div on the floor.

So let's work on defining the edge cases rather than dropping the
whole API because it can't be made perfect. Nothing about HTML parsing
is even remotely close to perfect.

/ Jonas

Received on Thursday, 10 November 2011 17:33:45 UTC