[PATCH v2 1/8] mshtml: Implement IHTMLElement::toString.
Jacek Caban
jacek at codeweavers.com
Mon Sep 27 10:42:34 CDT 2021
Hi Gabriel,
On 9/24/21 3:45 PM, Gabriel Ivăncescu wrote:
> Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
> ---
> dlls/mshtml/dispex.c | 10 ++
> dlls/mshtml/htmlanchor.c | 3 +-
> dlls/mshtml/htmlarea.c | 3 +-
> dlls/mshtml/htmlbody.c | 3 +-
> dlls/mshtml/htmlcomment.c | 3 +-
> dlls/mshtml/htmlelem.c | 163 +++++++++++++++++++++++++-----
> dlls/mshtml/htmlform.c | 3 +-
> dlls/mshtml/htmlframe.c | 6 +-
> dlls/mshtml/htmlhead.c | 12 ++-
> dlls/mshtml/htmlimg.c | 3 +-
> dlls/mshtml/htmlinput.c | 9 +-
> dlls/mshtml/htmllink.c | 3 +-
> dlls/mshtml/htmlobject.c | 6 +-
> dlls/mshtml/htmlscript.c | 3 +-
> dlls/mshtml/htmlselect.c | 6 +-
> dlls/mshtml/htmlstyleelem.c | 3 +-
> dlls/mshtml/htmltable.c | 9 +-
> dlls/mshtml/htmltextarea.c | 3 +-
> dlls/mshtml/mshtml_private.h | 2 +
> dlls/mshtml/tests/documentmode.js | 142 ++++++++++++++++++++++++++
> 20 files changed, 341 insertions(+), 54 deletions(-)
>
> diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
> index 64ead8f..797f024 100644
> --- a/dlls/mshtml/dispex.c
> +++ b/dlls/mshtml/dispex.c
> @@ -1482,6 +1482,16 @@ compat_mode_t dispex_compat_mode(DispatchEx *dispex)
> : dispex->info->desc->vtbl->get_compat_mode(dispex);
> }
>
> +const WCHAR *dispex_tostring(DispatchEx *dispex)
> +{
> + const WCHAR *str = dispex->info->desc->tostring_name;
> +
> + /* Empty string is special for all modes */
> + if((!str || str[0]) && dispex_compat_mode(dispex) < COMPAT_MODE_IE9)
The special case for an empty string should not be needed.
> + str = L"[object]";
> + return str;
> +}Gabriel
I was hoping that it could take care of entire implementation. Caller
could be about to do just:
return dispex_to_string(&This->dispex, p);
> HRESULT HTMLCommentElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLElement **elem)
> diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
> index d9554f4..8546c19 100644
> --- a/dlls/mshtml/htmlelem.c
> +++ b/dlls/mshtml/htmlelem.c
> @@ -47,31 +47,116 @@ typedef struct {
> } tag_desc_t;
>
> static const tag_desc_t tag_descs[] = {
> - {L"A", HTMLAnchorElement_Create},
> - {L"AREA", HTMLAreaElement_Create},
> - {L"BODY", HTMLBodyElement_Create},
> - {L"BUTTON", HTMLButtonElement_Create},
> - {L"EMBED", HTMLEmbedElement_Create},
> - {L"FORM", HTMLFormElement_Create},
> - {L"FRAME", HTMLFrameElement_Create},
> - {L"HEAD", HTMLHeadElement_Create},
> - {L"HTML", HTMLHtmlElement_Create},
> - {L"IFRAME", HTMLIFrame_Create},
> - {L"IMG", HTMLImgElement_Create},
> - {L"INPUT", HTMLInputElement_Create},
> - {L"LABEL", HTMLLabelElement_Create},
> - {L"LINK", HTMLLinkElement_Create},
> - {L"META", HTMLMetaElement_Create},
> - {L"OBJECT", HTMLObjectElement_Create},
> - {L"OPTION", HTMLOptionElement_Create},
> - {L"SCRIPT", HTMLScriptElement_Create},
> - {L"SELECT", HTMLSelectElement_Create},
> - {L"STYLE", HTMLStyleElement_Create},
> - {L"TABLE", HTMLTable_Create},
> - {L"TD", HTMLTableCell_Create},
> - {L"TEXTAREA", HTMLTextAreaElement_Create},
> - {L"TITLE", HTMLTitleElement_Create},
> - {L"TR", HTMLTableRow_Create}
> + {L"A", HTMLAnchorElement_Create},
> + {L"ABBR", NULL},
> + {L"ACRONYM", NULL},
> + {L"ADDRESS", NULL},
> + {L"APPLET", NULL},
> + {L"AREA", HTMLAreaElement_Create},
> + {L"ARTICLE", NULL},
> + {L"ASIDE", NULL},
> + {L"AUDIO", NULL},
> + {L"B", NULL},
> + {L"BASE", NULL},
> + {L"BASEFONT", NULL},
> + {L"BDO", NULL},
> + {L"BIG", NULL},
> + {L"BLOCKQUOTE", NULL},
> + {L"BODY", HTMLBodyElement_Create},
> + {L"BR", NULL},
> + {L"BUTTON", HTMLButtonElement_Create},
> + {L"CANVAS", NULL},
> + {L"CAPTION", NULL},
> + {L"CENTER", NULL},
> + {L"CITE", NULL},
> + {L"CODE", NULL},
> + {L"COL", NULL},
> + {L"COLGROUP", NULL},
> + {L"DATALIST", NULL},
> + {L"DD", NULL},
> + {L"DEL", NULL},
> + {L"DFN", NULL},
> + {L"DIR", NULL},
> + {L"DIV", NULL},
> + {L"DL", NULL},
> + {L"DT", NULL},
> + {L"EM", NULL},
> + {L"EMBED", HTMLEmbedElement_Create},
> + {L"FIELDSET", NULL},
> + {L"FIGCAPTION", NULL},
> + {L"FIGURE", NULL},
> + {L"FONT", NULL},
> + {L"FOOTER", NULL},
> + {L"FORM", HTMLFormElement_Create},
> + {L"FRAME", HTMLFrameElement_Create},
> + {L"FRAMESET", NULL},
> + {L"H1", NULL},
> + {L"H2", NULL},
> + {L"H3", NULL},
> + {L"H4", NULL},
> + {L"H5", NULL},
> + {L"H6", NULL},
> + {L"HEAD", HTMLHeadElement_Create},
> + {L"HEADER", NULL},
> + {L"HR", NULL},
> + {L"HTML", HTMLHtmlElement_Create},
> + {L"I", NULL},
> + {L"IFRAME", HTMLIFrame_Create},
> + {L"IMG", HTMLImgElement_Create},
> + {L"INPUT", HTMLInputElement_Create},
> + {L"INS", NULL},
> + {L"KBD", NULL},
> + {L"LABEL", HTMLLabelElement_Create},
> + {L"LEGEND", NULL},
> + {L"LI", NULL},
> + {L"LINK", HTMLLinkElement_Create},
> + {L"MAP", NULL},
> + {L"MARK", NULL},
> + {L"META", HTMLMetaElement_Create},
> + {L"NAV", NULL},
> + {L"NOFRAMES", NULL},
> + {L"NOSCRIPT", NULL},
> + {L"OBJECT", HTMLObjectElement_Create},
> + {L"OL", NULL},
> + {L"OPTGROUP", NULL},
> + {L"OPTION", HTMLOptionElement_Create},
> + {L"P", NULL},
> + {L"PARAM", NULL},
> + {L"PRE", NULL},
> + {L"PROGRESS", NULL},
> + {L"Q", NULL},
> + {L"RP", NULL},
> + {L"RT", NULL},
> + {L"RUBY", NULL},
> + {L"S", NULL},
> + {L"SAMP", NULL},
> + {L"SCRIPT", HTMLScriptElement_Create},
> + {L"SECTION", NULL},
> + {L"SELECT", HTMLSelectElement_Create},
> + {L"SMALL", NULL},
> + {L"SOURCE", NULL},
> + {L"SPAN", NULL},
> + {L"STRIKE", NULL},
> + {L"STRONG", NULL},
> + {L"STYLE", HTMLStyleElement_Create},
> + {L"SUB", NULL},
> + {L"SUP", NULL},
> + {L"TABLE", HTMLTable_Create},
> + {L"TBODY", NULL},
> + {L"TD", HTMLTableCell_Create},
> + {L"TEXTAREA", HTMLTextAreaElement_Create},
> + {L"TFOOT", NULL},
> + {L"TH", NULL},
> + {L"THEAD", NULL},
> + {L"TITLE", HTMLTitleElement_Create},
> + {L"TR", HTMLTableRow_Create},
> + {L"TRACK", NULL},
> + {L"TT", NULL},
> + {L"U", NULL},
> + {L"UL", NULL},
> + {L"VAR", NULL},
> + {L"VIDEO", NULL},
> + {L"WBR", NULL}
> };
I think that having a separated constructor instead of all those NULLs
would avoid the mess that you need in HTMLElement_toString:
>
> static const tag_desc_t *get_tag_desc(const WCHAR *tag_name)
> @@ -2112,8 +2197,30 @@ static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *
> static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
> {
> HTMLElement *This = impl_from_IHTMLElement(iface);
> - FIXME("(%p)->(%p)\n", This, String);
> - return E_NOTIMPL;
> + const PRUnichar *str;
> + nsAString tag_str;
> + nsresult nsres;
> +
> + TRACE("(%p)->(%p)\n", This, String);
> +
> + if(!String)
> + return E_INVALIDARG;
> +
> + str = dispex_tostring(&This->node.event_target.dispex);
> + if(!str) {
> + nsAString_Init(&tag_str, NULL);
> + nsres = nsIDOMElement_GetTagName(This->dom_element, &tag_str);
> + if(NS_FAILED(nsres)) {
> + nsAString_Finish(&tag_str);
> + return map_nsresult(nsres);
> + }
> + nsAString_GetData(&tag_str, &str);
> + str = get_tag_desc(str) ? L"[object HTMLElement]" : L"[object HTMLUnknownElement]";
> + nsAString_Finish(&tag_str);
> + }
> +
> + *String = SysAllocString(str);
> + return *String ? S_OK : E_OUTOFMEMORY;
> }
>
(...)
> diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
> index c1e7e78..67ea0ad 100644
> --- a/dlls/mshtml/mshtml_private.h
> +++ b/dlls/mshtml/mshtml_private.h
> @@ -331,6 +331,7 @@ typedef struct {
> const tid_t disp_tid;
> const tid_t* const iface_tids;
> void (*init_info)(dispex_data_t*,compat_mode_t);
> + const WCHAR *tostring_name;
> dispex_data_t *info_cache[COMPAT_MODE_CNT];
> dispex_data_t *delayed_init_info;
> } dispex_static_data_t;
It would be cleaner to no tie it so tightly with toString and store just
the type name. "[object ...]" decorations can be a part of toString
implementation.
I also think it would be nicer to have it as the first field of
dispex_static_data_t.
Thanks,
Jacek
More information about the wine-devel
mailing list