[PATCH v2 03/16] mshtml: Implement HTMLElement's toString.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Tue Oct 5 09:18:36 CDT 2021
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
dlls/mshtml/htmlelem.c | 181 +++++++++++++++++++++++++-----
dlls/mshtml/tests/documentmode.js | 154 +++++++++++++++++++++++++
2 files changed, 306 insertions(+), 29 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 4b16fce..831cc0b 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -46,32 +46,119 @@ typedef struct {
HRESULT (*constructor)(HTMLDocumentNode*,nsIDOMElement*,HTMLElement**);
} tag_desc_t;
+static HRESULT HTMLElement_Constr(HTMLDocumentNode*,nsIDOMElement*,HTMLElement**);
+
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", HTMLElement_Constr},
+ {L"ACRONYM", HTMLElement_Constr},
+ {L"ADDRESS", HTMLElement_Constr},
+ {L"APPLET", HTMLElement_Constr},
+ {L"AREA", HTMLAreaElement_Create},
+ {L"ARTICLE", HTMLElement_Constr},
+ {L"ASIDE", HTMLElement_Constr},
+ {L"AUDIO", HTMLElement_Constr},
+ {L"B", HTMLElement_Constr},
+ {L"BASE", HTMLElement_Constr},
+ {L"BASEFONT", HTMLElement_Constr},
+ {L"BDO", HTMLElement_Constr},
+ {L"BIG", HTMLElement_Constr},
+ {L"BLOCKQUOTE", HTMLElement_Constr},
+ {L"BODY", HTMLBodyElement_Create},
+ {L"BR", HTMLElement_Constr},
+ {L"BUTTON", HTMLButtonElement_Create},
+ {L"CANVAS", HTMLElement_Constr},
+ {L"CAPTION", HTMLElement_Constr},
+ {L"CENTER", HTMLElement_Constr},
+ {L"CITE", HTMLElement_Constr},
+ {L"CODE", HTMLElement_Constr},
+ {L"COL", HTMLElement_Constr},
+ {L"COLGROUP", HTMLElement_Constr},
+ {L"DATALIST", HTMLElement_Constr},
+ {L"DD", HTMLElement_Constr},
+ {L"DEL", HTMLElement_Constr},
+ {L"DFN", HTMLElement_Constr},
+ {L"DIR", HTMLElement_Constr},
+ {L"DIV", HTMLElement_Constr},
+ {L"DL", HTMLElement_Constr},
+ {L"DT", HTMLElement_Constr},
+ {L"EM", HTMLElement_Constr},
+ {L"EMBED", HTMLEmbedElement_Create},
+ {L"FIELDSET", HTMLElement_Constr},
+ {L"FIGCAPTION", HTMLElement_Constr},
+ {L"FIGURE", HTMLElement_Constr},
+ {L"FONT", HTMLElement_Constr},
+ {L"FOOTER", HTMLElement_Constr},
+ {L"FORM", HTMLFormElement_Create},
+ {L"FRAME", HTMLFrameElement_Create},
+ {L"FRAMESET", HTMLElement_Constr},
+ {L"H1", HTMLElement_Constr},
+ {L"H2", HTMLElement_Constr},
+ {L"H3", HTMLElement_Constr},
+ {L"H4", HTMLElement_Constr},
+ {L"H5", HTMLElement_Constr},
+ {L"H6", HTMLElement_Constr},
+ {L"HEAD", HTMLHeadElement_Create},
+ {L"HEADER", HTMLElement_Constr},
+ {L"HR", HTMLElement_Constr},
+ {L"HTML", HTMLHtmlElement_Create},
+ {L"I", HTMLElement_Constr},
+ {L"IFRAME", HTMLIFrame_Create},
+ {L"IMG", HTMLImgElement_Create},
+ {L"INPUT", HTMLInputElement_Create},
+ {L"INS", HTMLElement_Constr},
+ {L"KBD", HTMLElement_Constr},
+ {L"LABEL", HTMLLabelElement_Create},
+ {L"LEGEND", HTMLElement_Constr},
+ {L"LI", HTMLElement_Constr},
+ {L"LINK", HTMLLinkElement_Create},
+ {L"MAP", HTMLElement_Constr},
+ {L"MARK", HTMLElement_Constr},
+ {L"META", HTMLMetaElement_Create},
+ {L"NAV", HTMLElement_Constr},
+ {L"NOFRAMES", HTMLElement_Constr},
+ {L"NOSCRIPT", HTMLElement_Constr},
+ {L"OBJECT", HTMLObjectElement_Create},
+ {L"OL", HTMLElement_Constr},
+ {L"OPTGROUP", HTMLElement_Constr},
+ {L"OPTION", HTMLOptionElement_Create},
+ {L"P", HTMLElement_Constr},
+ {L"PARAM", HTMLElement_Constr},
+ {L"PRE", HTMLElement_Constr},
+ {L"PROGRESS", HTMLElement_Constr},
+ {L"Q", HTMLElement_Constr},
+ {L"RP", HTMLElement_Constr},
+ {L"RT", HTMLElement_Constr},
+ {L"RUBY", HTMLElement_Constr},
+ {L"S", HTMLElement_Constr},
+ {L"SAMP", HTMLElement_Constr},
+ {L"SCRIPT", HTMLScriptElement_Create},
+ {L"SECTION", HTMLElement_Constr},
+ {L"SELECT", HTMLSelectElement_Create},
+ {L"SMALL", HTMLElement_Constr},
+ {L"SOURCE", HTMLElement_Constr},
+ {L"SPAN", HTMLElement_Constr},
+ {L"STRIKE", HTMLElement_Constr},
+ {L"STRONG", HTMLElement_Constr},
+ {L"STYLE", HTMLStyleElement_Create},
+ {L"SUB", HTMLElement_Constr},
+ {L"SUP", HTMLElement_Constr},
+ {L"TABLE", HTMLTable_Create},
+ {L"TBODY", HTMLElement_Constr},
+ {L"TD", HTMLTableCell_Create},
+ {L"TEXTAREA", HTMLTextAreaElement_Create},
+ {L"TFOOT", HTMLElement_Constr},
+ {L"TH", HTMLElement_Constr},
+ {L"THEAD", HTMLElement_Constr},
+ {L"TITLE", HTMLTitleElement_Create},
+ {L"TR", HTMLTableRow_Create},
+ {L"TRACK", HTMLElement_Constr},
+ {L"TT", HTMLElement_Constr},
+ {L"U", HTMLElement_Constr},
+ {L"UL", HTMLElement_Constr},
+ {L"VAR", HTMLElement_Constr},
+ {L"VIDEO", HTMLElement_Constr},
+ {L"WBR", HTMLElement_Constr}
};
static const tag_desc_t *get_tag_desc(const WCHAR *tag_name)
@@ -2114,8 +2201,21 @@ 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;
+ HRESULT hres;
+ VARIANT var;
+
+ TRACE("(%p)->(%p)\n", This, String);
+
+ if(!String)
+ return E_INVALIDARG;
+
+ hres = IDispatchEx_InvokeEx(&This->node.event_target.dispex.IDispatchEx_iface, DISPID_VALUE,
+ LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, NULL, &var, NULL, NULL);
+ if(SUCCEEDED(hres)) {
+ assert(V_VT(&var) == VT_BSTR);
+ *String = V_BSTR(&var);
+ }
+ return hres;
}
static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
@@ -6789,6 +6889,14 @@ static dispex_static_data_t HTMLElement_dispex = {
HTMLElement_init_dispex_info
};
+static dispex_static_data_t HTMLUnknownElement_dispex = {
+ L"HTMLUnknownElement",
+ &HTMLElement_event_target_vtbl.dispex_vtbl,
+ DispHTMLUnknownElement_tid,
+ HTMLElement_iface_tids,
+ HTMLElement_init_dispex_info
+};
+
void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMElement *nselem, dispex_static_data_t *dispex_data)
{
This->IHTMLElement_iface.lpVtbl = &HTMLElementVtbl;
@@ -6810,7 +6918,7 @@ void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMElement *n
nsIDOMHTMLElement *html_element;
nsresult nsres;
- HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem, dispex_data ? dispex_data : &HTMLElement_dispex);
+ HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem, dispex_data ? dispex_data : &HTMLUnknownElement_dispex);
/* No AddRef, share reference with HTMLDOMNode */
assert((nsIDOMNode*)nselem == This->node.nsnode);
@@ -6865,7 +6973,7 @@ HRESULT HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_g
elem = heap_alloc_zero(sizeof(HTMLElement));
if(elem) {
elem->node.vtbl = &HTMLElementImplVtbl;
- HTMLElement_Init(elem, doc, nselem, &HTMLElement_dispex);
+ HTMLElement_Init(elem, doc, nselem, &HTMLUnknownElement_dispex);
hres = S_OK;
}else {
hres = E_OUTOFMEMORY;
@@ -6884,6 +6992,21 @@ HRESULT HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_g
return S_OK;
}
+static HRESULT HTMLElement_Constr(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
+{
+ HTMLElement *ret;
+
+ ret = heap_alloc_zero(sizeof(*ret));
+ if(!ret)
+ return E_OUTOFMEMORY;
+
+ ret->node.vtbl = &HTMLElementImplVtbl;
+ HTMLElement_Init(ret, doc, nselem, &HTMLElement_dispex);
+
+ *elem = ret;
+ return S_OK;
+}
+
HRESULT get_element(nsIDOMElement *nselem, HTMLElement **ret)
{
HTMLDOMNode *node;
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index c20f6ee..70cc491 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -19,6 +19,160 @@
var compat_version;
var tests = [];
+sync_test("builtin_toString", function() {
+ var tags = [
+ [ "abbr", "Phrase" ],
+ [ "acronym", "Phrase" ],
+ [ "address", "Block" ],
+ // [ "applet", "Applet" ], // makes Windows pop up a dialog box
+ [ "article", "" ],
+ [ "aside", "" ],
+ [ "audio", "Audio" ],
+ [ "b", "Phrase" ],
+ [ "base", "Base" ],
+ [ "basefont", "BaseFont" ],
+ [ "bdi", "Unknown" ],
+ [ "bdo", "Phrase" ],
+ [ "big", "Phrase" ],
+ [ "blockquote", "Block" ],
+ [ "body", "Body" ],
+ [ "br", "BR" ],
+ [ "button", "Button" ],
+ [ "canvas", "Canvas" ],
+ [ "caption", "TableCaption" ],
+ [ "center", "Block" ],
+ [ "cite", "Phrase" ],
+ [ "code", "Phrase" ],
+ [ "col", "TableCol" ],
+ [ "colgroup", "TableCol" ],
+ [ "data", "Unknown" ],
+ [ "datalist", "DataList", 10 ],
+ [ "dd", "DD" ],
+ [ "del", "Mod" ],
+ [ "details", "Unknown" ],
+ [ "dfn", "Phrase" ],
+ [ "dialog", "Unknown" ],
+ [ "dir", "Directory" ],
+ [ "div", "Div" ],
+ [ "dl", "DList" ],
+ [ "dt", "DT" ],
+ [ "em", "Phrase" ],
+ [ "embed", "Embed" ],
+ [ "fieldset", "FieldSet" ],
+ [ "figcaption", "" ],
+ [ "figure", "" ],
+ [ "font", "Font" ],
+ [ "footer", "" ],
+ [ "form", "Form" ],
+ [ "frame", "Frame" ],
+ [ "frameset", "FrameSet" ],
+ [ "h1", "Heading" ],
+ [ "h2", "Heading" ],
+ [ "h3", "Heading" ],
+ [ "h4", "Heading" ],
+ [ "h5", "Heading" ],
+ [ "h6", "Heading" ],
+ [ "h7", "Unknown" ],
+ [ "head", "Head" ],
+ [ "header", "" ],
+ [ "hr", "HR" ],
+ [ "html", "Html" ],
+ [ "i", "Phrase" ],
+ [ "iframe", "IFrame" ],
+ [ "img", "Image" ],
+ [ "input", "Input" ],
+ [ "ins", "Mod" ],
+ [ "kbd", "Phrase" ],
+ [ "label", "Label" ],
+ [ "legend", "Legend" ],
+ [ "li", "LI" ],
+ [ "link", "Link" ],
+ [ "main", "Unknown" ],
+ [ "map", "Map" ],
+ [ "mark", "" ],
+ [ "meta", "Meta" ],
+ [ "meter", "Unknown" ],
+ [ "nav", "" ],
+ [ "noframes", "" ],
+ [ "noscript", "" ],
+ [ "object", "Object" ],
+ [ "ol", "OList" ],
+ [ "optgroup", "OptGroup" ],
+ [ "option", "Option" ],
+ [ "output", "Unknown" ],
+ [ "p", "Paragraph" ],
+ [ "param", "Param" ],
+ [ "picture", "Unknown" ],
+ [ "pre", "Pre" ],
+ [ "progress", "Progress", 10 ],
+ [ "q", "Quote" ],
+ [ "rp", "Phrase" ],
+ [ "rt", "Phrase" ],
+ [ "ruby", "Phrase" ],
+ [ "s", "Phrase" ],
+ [ "samp", "Phrase" ],
+ [ "script", "Script" ],
+ [ "section", "" ],
+ [ "select", "Select" ],
+ [ "small", "Phrase" ],
+ [ "source", "Source" ],
+ [ "span", "Span" ],
+ [ "strike", "Phrase" ],
+ [ "strong", "Phrase" ],
+ [ "style", "Style" ],
+ [ "sub", "Phrase" ],
+ [ "summary", "Unknown" ],
+ [ "sup", "Phrase" ],
+ [ "svg", "Unknown" ],
+ [ "table", "Table" ],
+ [ "tbody", "TableSection" ],
+ [ "td", "TableDataCell" ],
+ [ "template", "Unknown" ],
+ [ "textarea", "TextArea" ],
+ [ "tfoot", "TableSection" ],
+ [ "th", "TableHeaderCell" ],
+ [ "thead", "TableSection" ],
+ [ "time", "Unknown" ],
+ [ "title", "Title" ],
+ [ "tr", "TableRow" ],
+ [ "track", "Track", 10 ],
+ [ "tt", "Phrase" ],
+ [ "u", "Phrase" ],
+ [ "ul", "UList" ],
+ [ "var", "Phrase" ],
+ [ "video", "Video" ],
+ [ "wbr", "" ],
+ [ "winetest", "Unknown" ]
+ ];
+ var v = document.documentMode, e;
+
+ function test(msg, obj, name, fullstr) {
+ var s;
+ if(obj.toString) {
+ s = obj.toString();
+ todo_wine_if(name !== "HTMLElement" && s === "[object HTMLElement]").
+ ok(s === (fullstr ? fullstr : (v < 9 ? "[object]" : "[object " + name + "]")), msg + " toString returned " + s);
+ }
+ s = Object.prototype.toString.call(obj);
+ todo_wine_if(v >= 9 && name != "Object").
+ ok(s === (v < 9 ? "[object Object]" : "[object " + name + "]"), msg + " Object.toString returned " + s);
+ }
+
+ for(var i = 0; i < tags.length; i++)
+ if(tags[i].length < 3 || v >= tags[i][2])
+ test("tag '" + tags[i][0] + "'", document.createElement(tags[i][0]), "HTML" + tags[i][1] + "Element");
+
+ e = document.createElement("a");
+ ok(e.toString() === "", "tag 'a' (without href) toString returned " + e.toString());
+ e.href = "https://www.winehq.org/";
+ test("tag 'a'", e, "HTMLAnchorElement", "https://www.winehq.org/");
+
+ e = document.createElement("area");
+ ok(e.toString() === "", "tag 'area' (without href) toString returned " + e.toString());
+ e.href = "https://www.winehq.org/";
+ test("tag 'area'", e, "HTMLAreaElement", "https://www.winehq.org/");
+});
+
sync_test("elem_props", function() {
var elem = document.documentElement;
--
2.31.1
More information about the wine-devel
mailing list