Signed-off-by: Gabriel Ivăncescu gabrielopcode@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 29aa378..de69e2f 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_Ctor(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_Ctor}, + {L"ACRONYM", HTMLElement_Ctor}, + {L"ADDRESS", HTMLElement_Ctor}, + {L"APPLET", HTMLElement_Ctor}, + {L"AREA", HTMLAreaElement_Create}, + {L"ARTICLE", HTMLElement_Ctor}, + {L"ASIDE", HTMLElement_Ctor}, + {L"AUDIO", HTMLElement_Ctor}, + {L"B", HTMLElement_Ctor}, + {L"BASE", HTMLElement_Ctor}, + {L"BASEFONT", HTMLElement_Ctor}, + {L"BDO", HTMLElement_Ctor}, + {L"BIG", HTMLElement_Ctor}, + {L"BLOCKQUOTE", HTMLElement_Ctor}, + {L"BODY", HTMLBodyElement_Create}, + {L"BR", HTMLElement_Ctor}, + {L"BUTTON", HTMLButtonElement_Create}, + {L"CANVAS", HTMLElement_Ctor}, + {L"CAPTION", HTMLElement_Ctor}, + {L"CENTER", HTMLElement_Ctor}, + {L"CITE", HTMLElement_Ctor}, + {L"CODE", HTMLElement_Ctor}, + {L"COL", HTMLElement_Ctor}, + {L"COLGROUP", HTMLElement_Ctor}, + {L"DATALIST", HTMLElement_Ctor}, + {L"DD", HTMLElement_Ctor}, + {L"DEL", HTMLElement_Ctor}, + {L"DFN", HTMLElement_Ctor}, + {L"DIR", HTMLElement_Ctor}, + {L"DIV", HTMLElement_Ctor}, + {L"DL", HTMLElement_Ctor}, + {L"DT", HTMLElement_Ctor}, + {L"EM", HTMLElement_Ctor}, + {L"EMBED", HTMLEmbedElement_Create}, + {L"FIELDSET", HTMLElement_Ctor}, + {L"FIGCAPTION", HTMLElement_Ctor}, + {L"FIGURE", HTMLElement_Ctor}, + {L"FONT", HTMLElement_Ctor}, + {L"FOOTER", HTMLElement_Ctor}, + {L"FORM", HTMLFormElement_Create}, + {L"FRAME", HTMLFrameElement_Create}, + {L"FRAMESET", HTMLElement_Ctor}, + {L"H1", HTMLElement_Ctor}, + {L"H2", HTMLElement_Ctor}, + {L"H3", HTMLElement_Ctor}, + {L"H4", HTMLElement_Ctor}, + {L"H5", HTMLElement_Ctor}, + {L"H6", HTMLElement_Ctor}, + {L"HEAD", HTMLHeadElement_Create}, + {L"HEADER", HTMLElement_Ctor}, + {L"HR", HTMLElement_Ctor}, + {L"HTML", HTMLHtmlElement_Create}, + {L"I", HTMLElement_Ctor}, + {L"IFRAME", HTMLIFrame_Create}, + {L"IMG", HTMLImgElement_Create}, + {L"INPUT", HTMLInputElement_Create}, + {L"INS", HTMLElement_Ctor}, + {L"KBD", HTMLElement_Ctor}, + {L"LABEL", HTMLLabelElement_Create}, + {L"LEGEND", HTMLElement_Ctor}, + {L"LI", HTMLElement_Ctor}, + {L"LINK", HTMLLinkElement_Create}, + {L"MAP", HTMLElement_Ctor}, + {L"MARK", HTMLElement_Ctor}, + {L"META", HTMLMetaElement_Create}, + {L"NAV", HTMLElement_Ctor}, + {L"NOFRAMES", HTMLElement_Ctor}, + {L"NOSCRIPT", HTMLElement_Ctor}, + {L"OBJECT", HTMLObjectElement_Create}, + {L"OL", HTMLElement_Ctor}, + {L"OPTGROUP", HTMLElement_Ctor}, + {L"OPTION", HTMLOptionElement_Create}, + {L"P", HTMLElement_Ctor}, + {L"PARAM", HTMLElement_Ctor}, + {L"PRE", HTMLElement_Ctor}, + {L"PROGRESS", HTMLElement_Ctor}, + {L"Q", HTMLElement_Ctor}, + {L"RP", HTMLElement_Ctor}, + {L"RT", HTMLElement_Ctor}, + {L"RUBY", HTMLElement_Ctor}, + {L"S", HTMLElement_Ctor}, + {L"SAMP", HTMLElement_Ctor}, + {L"SCRIPT", HTMLScriptElement_Create}, + {L"SECTION", HTMLElement_Ctor}, + {L"SELECT", HTMLSelectElement_Create}, + {L"SMALL", HTMLElement_Ctor}, + {L"SOURCE", HTMLElement_Ctor}, + {L"SPAN", HTMLElement_Ctor}, + {L"STRIKE", HTMLElement_Ctor}, + {L"STRONG", HTMLElement_Ctor}, + {L"STYLE", HTMLStyleElement_Create}, + {L"SUB", HTMLElement_Ctor}, + {L"SUP", HTMLElement_Ctor}, + {L"TABLE", HTMLTable_Create}, + {L"TBODY", HTMLElement_Ctor}, + {L"TD", HTMLTableCell_Create}, + {L"TEXTAREA", HTMLTextAreaElement_Create}, + {L"TFOOT", HTMLElement_Ctor}, + {L"TH", HTMLElement_Ctor}, + {L"THEAD", HTMLElement_Ctor}, + {L"TITLE", HTMLTitleElement_Create}, + {L"TR", HTMLTableRow_Create}, + {L"TRACK", HTMLElement_Ctor}, + {L"TT", HTMLElement_Ctor}, + {L"U", HTMLElement_Ctor}, + {L"UL", HTMLElement_Ctor}, + {L"VAR", HTMLElement_Ctor}, + {L"VIDEO", HTMLElement_Ctor}, + {L"WBR", HTMLElement_Ctor} };
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_Ctor(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..ec486e1 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, tostr) { + var s; + if(obj.toString) { + s = obj.toString(); + todo_wine_if(name !== "HTMLElement" && s === "[object HTMLElement]"). + ok(s === (tostr ? tostr : (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;