[PATCH v3 2/3] mshtml: Implement inline attributes parsing for createElement.

Gabriel Ivăncescu gabrielopcode at gmail.com
Tue Nov 9 10:58:14 CST 2021


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:
>>
>> 1) Parse its tag name ("body")
>> 2) Create a <body> element
>>
>> Then:
>>
>> 3) Create a <template> element, and setInnerHTML to <foo a="b">
>> 4) Get its first child
>> 5) 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.



More information about the wine-devel mailing list