[PATCH 6/7] mshtml: Implement inline attributes parsing for createElement.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Nov 1 11:48:46 CDT 2021


On 01/11/2021 16:06, Jacek Caban wrote:
> On 10/25/21 3:30 PM, Gabriel Ivăncescu wrote:
>> This is implemented by creating a dummy HTML element and parsing the 
>> inline
>> tag there, under a dummy tag name, so that it's filled with the parsed
>> attributes. After that, its attributes are copied into a proper element
>> with the proper tag name.
>>
>> Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
>> ---
>>   dlls/mshtml/htmlelem.c            | 154 +++++++++++++++++++++++++++++-
>>   dlls/mshtml/tests/documentmode.js |  69 +++++++++++++
>>   2 files changed, 222 insertions(+), 1 deletion(-)
>>
>> diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
>> index de69e2f..d5463f5 100644
>> --- a/dlls/mshtml/htmlelem.c
>> +++ b/dlls/mshtml/htmlelem.c
>> @@ -355,6 +355,154 @@ static inline HTMLElement 
>> *impl_from_IHTMLElement(IHTMLElement *iface)
>>       return CONTAINING_RECORD(iface, HTMLElement, IHTMLElement_iface);
>>   }
>> +static HRESULT create_nselem_with_elem_attrs(HTMLDocumentNode *doc, 
>> const WCHAR *tag, nsIDOMElement *elem_with_attr, nsIDOMElement **ret)
>> +{
>> +    nsIDOMMozNamedAttrMap *attrs;
>> +    nsAString name_str, val_str;
>> +    nsresult nsres, nsres2;
>> +    nsIDOMElement *elem;
>> +    nsIDOMAttr *attr;
>> +    UINT32 i, length;
>> +
>> +    nsAString_InitDepend(&name_str, tag);
>> +    nsres = nsIDOMHTMLDocument_CreateElement(doc->nsdoc, &name_str, 
>> &elem);
>> +    nsAString_Finish(&name_str);
>> +    if(NS_FAILED(nsres))
>> +        return map_nsresult(nsres);
>> +
>> +    nsres = nsIDOMElement_GetAttributes(elem_with_attr, &attrs);
>> +    if(NS_FAILED(nsres))
>> +        goto fail;
>> +
>> +    nsres = nsIDOMMozNamedAttrMap_GetLength(attrs, &length);
>> +    if(NS_FAILED(nsres)) {
>> +        nsIDOMMozNamedAttrMap_Release(attrs);
>> +        goto fail;
>> +    }
>> +
>> +    nsAString_Init(&name_str, NULL);
>> +    nsAString_Init(&val_str, NULL);
>> +    for(i = 0; i < length; i++) {
>> +        nsres = nsIDOMMozNamedAttrMap_Item(attrs, i, &attr);
>> +        if(NS_FAILED(nsres))
>> +            continue;
>> +
>> +        nsres  = nsIDOMAttr_GetNodeName(attr, &name_str);
>> +        nsres2 = nsIDOMAttr_GetNodeValue(attr, &val_str);
>> +        nsIDOMAttr_Release(attr);
>> +        if(NS_FAILED(nsres) || NS_FAILED(nsres2))
>> +            continue;
>> +
>> +        nsres = nsIDOMElement_SetAttribute(elem, &name_str, &val_str);
>> +    }
>> +    nsAString_Finish(&name_str);
>> +    nsAString_Finish(&val_str);
>> +
>> +    nsIDOMMozNamedAttrMap_Release(attrs);
>> +    *ret = elem;
>> +    return S_OK;
>> +
>> +fail:
>> +    nsIDOMElement_Release(elem);
>> +    return E_FAIL;
>> +}
> 
> 
> Isn't Node.cloneNode what you need here?
> 

Thanks for the suggestion, I wasn't aware it copied the attributes to a 
different element.

> 
>> +static HRESULT create_nselem_parse(HTMLDocumentNode *doc, const WCHAR 
>> *tag, nsIDOMElement **ret)
>> +{
>> +    static const WCHAR prefix[15] = L"<BODY><DUMMYTAG";
>> +    static const WCHAR suffix[] = L"/></BODY>";
> 
> 
> This whole function looks hacky. Why do you need extra <BODY> element? 
> Could we just parse the whole tag string?
> 

Would it work properly with things like <html ...> or <body ...> 
elements? I have tests for them and I remember testing them precisely 
for this reason. I remember I tried it originally to parse the whole 
thing, but ended up with those corner cases not working.

I'll look at it again and see if I messed something up, but I can't 
guarantee it will work.

Thanks,
Gabriel



More information about the wine-devel mailing list