On 08/11/2021 20:46, Jacek Caban wrote:
On 11/7/21 2:38 PM, Gabriel Ivăncescu wrote:
On 06/11/2021 21:19, Jacek Caban wrote:
On 11/6/21 2:46 PM, Gabriel Ivăncescu wrote:
I thought of another idea, which I don't think is necessarily better, but maybe it's worth a thought.
We could iterate through a bunch of root context tags, namely <template>, <head> and <html> in that order, then use setInnerHTML on them and retrieve the first child, until we get a child and then use that if we did.
I guess <html> context might be tricky here, since it can be either
<head> or <body> tag that is parsed, might need some special casing (and retrieve either first or second child in such case, perhaps we can just check the first letter since other tags should already work in either <template> or <head> themselves—so would have been filtered already).
Just an idea. Is it worth pursuing?
The whole thing is still too hacky, in my opinion. If we can't get Gecko to do what we need, maybe we need to do parsing ourselves. Given that we only need to parse a small subset of HTML, it shouldn't be too bad and all we need from Gecko is createElement() and setAttribute().
Thanks,
Jacek
Hi Jacek,
I think parsing it ourselves might be somewhat complicated, because of stuff like the HTML escapes (e.g. " " & and so on), which would have to be handled as the tests show.
A mixed way would be a simpler version of the first patch that goes roughly like the following. For this case, let's assume we want to create the <body a="b"> element, so:
The first two steps are needed regardless of whether we parse it ourselves or not:
- Parse its tag name ("body")
- Create a <body> element
Then:
- Create a <template> element, and setInnerHTML to <foo a="b">
- Get its first child
- Loop through all attributes on the child and set them on the
element we created in (2)
This is pretty much like first patch but simplified to <template> and allows gecko to parse it for us.
Do you think it's feasible? If not, do you have some suggestions how I should implement the escapes? I guess a table?
Yeah, it's a bit better. It's not perfect, but it should work.
Thanks,
Jacek
So I decided to go with contextual fragment instead, setInnerHTML seemed to be a bit fragile/buggy or maybe I'm not understanding the issues, but getFirstChild or getFirstElementChild always returned NULL after setInnerHTML, despite getInnerHTML showing the proper html when tracing.
I considered setOuterHTML but that seems to not work at all, no matter what I input to it. It doesn't do anything. I then looked at our implementation of outerHTML, and it seems to be using contextual fragments to replace the node, so that's what I went with.
I think it's cleaner too, since we don't use a <template> tag anymore (or any other tag).
Note that even contextual fragments are still context-dependent (as the name shows) so I still had to use the same tricks with dummy tag / attribute copying as with innerHTML, unfortunately. But at least now it's correct in *all* cases.