So it doesn't clash with IHTMLWindow2, which uses low ids ('console' clashes with 'history').
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
This is a patch series pre-requisite for the proper toString() and object names implementations, which fixes a bunch of things and implements some missing bits first. It's needed for those tests to pass properly while testing almost all of the objects, and to avoid sending too many patches at once, I decided to split them up into multiple series.
dlls/mshtml/mshtml_private_iface.idl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 491f4af..2292e2c 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -83,9 +83,9 @@ interface IWineMSHTMLConsole : IDispatch ] interface IWineHTMLWindowPrivate : IDispatch { - [id(1)] + [id(50)] HRESULT requestAnimationFrame([in] VARIANT *expr, [retval, out] VARIANT *timer_id); - [propget, id(2)] + [propget, id(51)] HRESULT console([retval, out] IDispatch **console); }
It returns the classes as specified in className.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 32 +++++++++++++++++++++++++++++++- dlls/mshtml/tests/dom.js | 4 ++++ 2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index d9554f4..4e5aba7 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -6624,12 +6624,42 @@ static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = { token_list_remove, };
+static inline struct token_list *token_list_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct token_list, dispex); +} + +static HRESULT token_list_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + HRESULT hres; + + switch(flags) { + case DISPATCH_PROPERTYGET: + hres = IHTMLElement_get_className(token_list->element, &V_BSTR(res)); + if(FAILED(hres)) + return hres; + V_VT(res) = VT_BSTR; + break; + default: + FIXME("Unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; +} + +static const dispex_static_data_vtbl_t token_list_dispex_vtbl = { + token_list_value +}; + static const tid_t token_list_iface_tids[] = { IWineDOMTokenList_tid, 0 }; static dispex_static_data_t token_list_dispex = { - NULL, + &token_list_dispex_vtbl, IWineDOMTokenList_tid, token_list_iface_tids }; diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 0085b40..efbab66 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -527,6 +527,7 @@ sync_test("classList", function() {
classList.add("c"); ok(elem.className === "a b c 4", "(2) Expected className 'a b c 4', got " + elem.className); + ok(("" + classList) === "a b c 4", "Expected classList value 'a b c 4', got " + classList);
var exception = false
@@ -605,4 +606,7 @@ sync_test("classList", function() {
classList.remove("b"); ok(elem.className === "", "remove: expected className '', got " + elem.className); + + elem.className = " testclass foobar "; + ok(("" + classList) === " testclass foobar ", "Expected classList value ' testclass foobar ', got " + classList); });
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=99198
Your paranoid android.
=== w1064_tsign (32 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w10pro64_ja (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1633097514847 expected 1633097514910"
=== w7u_el (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
This will be tested further during toString implementations later.
dlls/mshtml/htmlelem.c | 10 ++++++++++ dlls/mshtml/mshtml_private_iface.idl | 2 ++ dlls/mshtml/tests/dom.js | 2 ++ 3 files changed, 14 insertions(+)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 4e5aba7..b07de03 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -6612,6 +6612,15 @@ static HRESULT WINAPI token_list_remove(IWineDOMTokenList *iface, BSTR token) return token_list_add_remove(iface, token, TRUE); }
+static HRESULT WINAPI token_list_toString(IWineDOMTokenList *iface, BSTR *String) +{ + struct token_list *token_list = impl_from_IWineDOMTokenList(iface); + + TRACE("(%p)->(%p)\n", token_list, String); + + return IHTMLElement_get_className(token_list->element, String); +} + static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = { token_list_QueryInterface, token_list_AddRef, @@ -6622,6 +6631,7 @@ static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = { token_list_Invoke, token_list_add, token_list_remove, + token_list_toString };
static inline struct token_list *token_list_from_DispatchEx(DispatchEx *iface) diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 2292e2c..5755afd 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -115,6 +115,8 @@ interface IWineDOMTokenList : IDispatch HRESULT add([in] BSTR token); [id(2)] HRESULT remove([in] BSTR token); + [id(3)] + HRESULT toString([retval, out] BSTR *String); }
} /* library MSHTML_private */ diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index efbab66..73c2b3b 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -528,6 +528,7 @@ sync_test("classList", function() { classList.add("c"); ok(elem.className === "a b c 4", "(2) Expected className 'a b c 4', got " + elem.className); ok(("" + classList) === "a b c 4", "Expected classList value 'a b c 4', got " + classList); + ok(classList.toString() === "a b c 4", "Expected classList toString 'a b c 4', got " + classList.toString());
var exception = false
@@ -609,4 +610,5 @@ sync_test("classList", function() {
elem.className = " testclass foobar "; ok(("" + classList) === " testclass foobar ", "Expected classList value ' testclass foobar ', got " + classList); + ok(classList.toString() === " testclass foobar ", "Expected classList toString ' testclass foobar ', got " + classList.toString()); });
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=99199
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlarea.c | 36 +++++++++++++++++++++--- dlls/mshtml/tests/dom.c | 62 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlarea.c b/dlls/mshtml/htmlarea.c index a0708c4..e785871 100644 --- a/dlls/mshtml/htmlarea.c +++ b/dlls/mshtml/htmlarea.c @@ -129,15 +129,43 @@ static HRESULT WINAPI HTMLAreaElement_get_coords(IHTMLAreaElement *iface, BSTR * static HRESULT WINAPI HTMLAreaElement_put_href(IHTMLAreaElement *iface, BSTR v) { HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&nsstr, v); + nsres = nsIDOMHTMLAreaElement_SetHref(This->nsarea, &nsstr); + nsAString_Finish(&nsstr); + if(NS_FAILED(nsres)) + return E_FAIL; + + return S_OK; }
static HRESULT WINAPI HTMLAreaElement_get_href(IHTMLAreaElement *iface, BSTR *p) { HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString href_str; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&href_str, NULL); + nsres = nsIDOMHTMLAreaElement_GetHref(This->nsarea, &href_str); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *href; + + nsAString_GetData(&href_str, &href); + hres = nsuri_to_url(href, TRUE, p); + }else { + ERR("GetHref failed: %08x\n", nsres); + hres = E_FAIL; + } + + nsAString_Finish(&href_str); + return hres; }
static HRESULT WINAPI HTMLAreaElement_put_target(IHTMLAreaElement *iface, BSTR v) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 67d7978..3bae9e0 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -77,6 +77,7 @@ static const char elem_test_str[] = "<script id="sc" type="text/javascript"><!--\nfunction Testing() {}\n// -->\n</script>" "<test /><object id="objid" name="objname" vspace=100></object><embed />" "<img id="imgid" name="WineImg"/>" + "<area id="area" href="http://test%5C%22%3E" "<iframe src="about:blank" id="ifr"></iframe>" "<form id="frm"></form>" "<div id="attr" attr1="attr1" attr2 attr3="attr3"></div>" @@ -918,6 +919,17 @@ static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk) return anchor; }
+#define get_area_iface(u) _get_area_iface(__LINE__,u) +static IHTMLAreaElement *_get_area_iface(unsigned line, IUnknown *unk) +{ + IHTMLAreaElement *area; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLAreaElement, (void**)&area); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAreaElement: %08x\n", hres); + return area; +} + #define get_textarea_iface(u) _get_textarea_iface(__LINE__,u) static IHTMLTextAreaElement *_get_textarea_iface(unsigned line, IUnknown *unk) { @@ -1704,6 +1716,36 @@ static void _test_anchor_hash(unsigned line, IHTMLElement *elem, const WCHAR *ex SysFreeString(str); }
+#define test_area_href(a,h) _test_area_href(__LINE__,a,h) +static void _test_area_href(unsigned line, IUnknown *unk, const WCHAR *exhref) +{ + IHTMLAreaElement *area = _get_area_iface(line, unk); + BSTR str; + HRESULT hres; + + hres = IHTMLAreaElement_get_href(area, &str); + ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres); + ok_(__FILE__,line)(!lstrcmpW(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(exhref)); + SysFreeString(str); + + _test_disp_value(line, unk, exhref); +} + +#define test_area_put_href(a,h) _test_area_put_href(__LINE__,a,h) +static void _test_area_put_href(unsigned line, IUnknown *unk, const WCHAR *exhref) +{ + IHTMLAreaElement *area = _get_area_iface(line, unk); + BSTR str; + HRESULT hres; + + str = SysAllocString(exhref); + hres = IHTMLAreaElement_put_href(area, str); + ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres); + SysFreeString(str); + + _test_disp_value(line, unk, exhref); +} + #define test_option_text(o,t) _test_option_text(__LINE__,o,t) static void _test_option_text(unsigned line, IHTMLOptionElement *option, const WCHAR *text) { @@ -8763,6 +8805,7 @@ static void test_elems(IHTMLDocument2 *doc) ET_OBJECT, ET_EMBED, ET_IMG, + ET_AREA, ET_IFRAME, ET_FORM, ET_DIV @@ -8803,8 +8846,8 @@ static void test_elems(IHTMLDocument2 *doc) ok(hres == S_OK, "get_links failed: %08x\n", hres); if(hres == S_OK) { - static const elem_type_t images_types[] = {ET_A}; - test_elem_collection((IUnknown*)collection, images_types, 1); + static const elem_type_t link_types[] = {ET_A,ET_AREA}; + test_elem_collection((IUnknown*)collection, link_types, 2);
IHTMLElementCollection_Release(collection); } @@ -9211,6 +9254,21 @@ static void test_elems(IHTMLDocument2 *doc) IHTMLElement_Release(elem); }
+ elem = get_elem_by_id(doc, L"area", TRUE); + if(elem) { + test_area_href((IUnknown*)elem, L"http://test/"); + + /* Change the href */ + test_area_put_href((IUnknown*)elem, L"http://test1/"); + test_area_href((IUnknown*)elem, L"http://test1/"); + + /* Restore the href */ + test_area_put_href((IUnknown*)elem, L"http://test/"); + test_area_href((IUnknown*)elem, L"http://test/"); + + IHTMLElement_Release(elem); + } + elem = get_doc_elem_by_id(doc, L"metaid"); if(elem) { test_meta_name((IUnknown*)elem, L"meta name");
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstylesheet.c | 36 ++++++++++++++++++++++++++++++++++-- dlls/mshtml/tests/dom.js | 26 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index 4519b06..b6f1c98 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -795,9 +795,41 @@ static HRESULT WINAPI HTMLStyleSheet_addRule(IHTMLStyleSheet *iface, BSTR bstrSe BSTR bstrStyle, LONG lIndex, LONG *plIndex) { HTMLStyleSheet *This = impl_from_IHTMLStyleSheet(iface); - FIXME("(%p)->(%s %s %d %p)\n", This, debugstr_w(bstrSelector), debugstr_w(bstrStyle), + const WCHAR format[] = L"%s {%s}"; + nsIDOMCSSRuleList *nslist = NULL; + UINT32 length, new_index; + nsAString nsstr; + nsresult nsres; + WCHAR *rule; + size_t len; + + TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(bstrSelector), debugstr_w(bstrStyle), lIndex, plIndex); - return E_NOTIMPL; + + if(!bstrSelector || !bstrStyle || !bstrSelector[0] || !bstrStyle[0]) + return E_INVALIDARG; + + nsres = nsIDOMCSSStyleSheet_GetCssRules(This->nsstylesheet, &nslist); + if(NS_FAILED(nsres)) + return E_FAIL; + nsIDOMCSSRuleList_GetLength(nslist, &length); + + if(lIndex > length) + lIndex = length; + + len = ARRAY_SIZE(format) - 4 /* %s twice */ + wcslen(bstrSelector) + wcslen(bstrStyle); + if(!(rule = heap_alloc(len * sizeof(WCHAR)))) + return E_OUTOFMEMORY; + swprintf(rule, len, format, bstrSelector, bstrStyle); + + nsAString_InitDepend(&nsstr, rule); + nsres = nsIDOMCSSStyleSheet_InsertRule(This->nsstylesheet, &nsstr, lIndex, &new_index); + if(NS_FAILED(nsres)) WARN("failed: %08x\n", nsres); + nsAString_Finish(&nsstr); + heap_free(rule); + + *plIndex = new_index; + return map_nsresult(nsres); }
static HRESULT WINAPI HTMLStyleSheet_removeImport(IHTMLStyleSheet *iface, LONG lIndex) diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 73c2b3b..3a2b96a 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -405,6 +405,32 @@ sync_test("stylesheets", function() { stylesheet.insertRule(".input { margin-left: 1px; }", 3); ok(false, "expected exception"); }catch(e) {} + + id = stylesheet.addRule(".p", "margin-top: 2px"); + ok(id === 2, "id = " + id); + ok(document.styleSheets.length === 1, "document.styleSheets.length = " + document.styleSheets.length); + ok(stylesheet.rules.length === 3, "stylesheet.rules.length = " + stylesheet.rules.length); + + id = stylesheet.addRule(".pre", "border: none", -1); + ok(id === 3, "id = " + id); + ok(stylesheet.rules.length === 4, "stylesheet.rules.length = " + stylesheet.rules.length); + + id = stylesheet.addRule(".h1", " ", 0); + ok(id === 0, "id = " + id); + ok(stylesheet.rules.length === 5, "stylesheet.rules.length = " + stylesheet.rules.length); + + id = stylesheet.addRule(".h2", "color: black", 8); + ok(id === 5, "id = " + id); + ok(stylesheet.rules.length === 6, "stylesheet.rules.length = " + stylesheet.rules.length); + + try { + stylesheet.addRule("", "border: none", 0); + ok(false, "expected exception"); + }catch(e) {} + try { + stylesheet.addRule(".img", "", 0); + ok(false, "expected exception"); + }catch(e) {} });
sync_test("storage", function() {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=99201
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Presently, even toString() is exposed as an attribute, because it's a builtin of the element, which makes no sense.
dlls/mshtml/htmlattr.c | 21 ++++----------------- dlls/mshtml/htmlelem.c | 31 ++++++++++++++++++++++++++++++- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/documentmode.js | 31 +++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 18 deletions(-)
diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c index dc8c45e..b293d91 100644 --- a/dlls/mshtml/htmlattr.c +++ b/dlls/mshtml/htmlattr.c @@ -174,10 +174,7 @@ static HRESULT WINAPI HTMLDOMAttribute_get_nodeValue(IHTMLDOMAttribute *iface, V static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, VARIANT_BOOL *p) { HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface); - nsIDOMAttr *nsattr; - nsAString nsname; BSTR name; - nsresult nsres; HRESULT hres;
TRACE("(%p)->(%p)\n", This, p); @@ -196,22 +193,12 @@ static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, V if(FAILED(hres)) return hres;
- /* FIXME: This is not exactly right, we have some attributes that don't map directly to Gecko attributes. */ - nsAString_InitDepend(&nsname, name); - nsres = nsIDOMElement_GetAttributeNode(This->elem->dom_element, &nsname, &nsattr); - nsAString_Finish(&nsname); + hres = is_elem_attr_specified(This->elem, name); SysFreeString(name); - if(NS_FAILED(nsres)) - return E_FAIL; + if(FAILED(hres)) + return hres;
- /* If the Gecko attribute node can be found, we know that the attribute is specified. - There is no point in calling GetSpecified */ - if(nsattr) { - nsIDOMAttr_Release(nsattr); - *p = VARIANT_TRUE; - }else { - *p = VARIANT_FALSE; - } + *p = (hres == S_OK) ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; }
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index b07de03..c285a21 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7169,6 +7169,28 @@ static HRESULT WINAPI HTMLAttributeCollection_Invoke(IHTMLAttributeCollection *i wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); }
+HRESULT is_elem_attr_specified(HTMLElement *elem, const WCHAR *name) +{ + nsIDOMAttr *nsattr; + nsAString nsname; + nsresult nsres; + + /* FIXME: This is not exactly right, we have some attributes that don't map directly to Gecko attributes. */ + nsAString_InitDepend(&nsname, name); + nsres = nsIDOMElement_GetAttributeNode(elem->dom_element, &nsname, &nsattr); + nsAString_Finish(&nsname); + if(NS_FAILED(nsres)) + return E_FAIL; + + /* If the Gecko attribute node can be found, we know that the attribute is specified. + There is no point in calling GetSpecified */ + if(nsattr) { + nsIDOMAttr_Release(nsattr); + return S_OK; + } + return S_FALSE; +} + static HRESULT get_attr_dispid_by_idx(HTMLAttributeCollection *This, LONG *idx, DISPID *dispid) { IDispatchEx *dispex = &This->elem->node.event_target.dispex.IDispatchEx_iface; @@ -7222,7 +7244,14 @@ static inline HRESULT get_attr_dispid_by_name(HTMLAttributeCollection *This, BST
hres = IDispatchEx_GetDispID(&This->elem->node.event_target.dispex.IDispatchEx_iface, name, fdexNameCaseInsensitive, id); - return hres; + if(FAILED(hres)) + return hres; + + if(get_dispid_type(*id) != DISPEXPROP_BUILTIN) + return S_OK; + + hres = is_elem_attr_specified(This->elem, name); + return (hres == S_FALSE) ? DISP_E_UNKNOWNNAME : hres; }
static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG *list_pos, HTMLDOMAttribute **attr) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c1e7e78..624963a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -1161,6 +1161,7 @@ HRESULT create_child_collection(nsIDOMNodeList*,compat_mode_t,IHTMLDOMChildrenCo HRESULT attr_value_to_string(VARIANT*) DECLSPEC_HIDDEN; HRESULT get_elem_attr_value_by_dispid(HTMLElement*,DISPID,VARIANT*) DECLSPEC_HIDDEN; HRESULT get_elem_source_index(HTMLElement*,LONG*) DECLSPEC_HIDDEN; +HRESULT is_elem_attr_specified(HTMLElement*,const WCHAR*) DECLSPEC_HIDDEN;
nsresult get_elem_attr_value(nsIDOMElement*,const WCHAR*,nsAString*,const PRUnichar**) DECLSPEC_HIDDEN; HRESULT elem_string_attr_getter(HTMLElement*,const WCHAR*,BOOL,BSTR*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index c20f6ee..41d7a6b 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -785,4 +785,35 @@ sync_test("elem_attr", function() { ok(r === "cls2", "class attr = " + r); r = elem.getAttribute("className"); ok(r === "cls3", "className attr = " + r); + + function test_exposed(prop, expect) { + if(expect) + ok(prop in elem.attributes, prop + " not found in elem.attributes."); + else + ok(!(prop in elem.attributes), prop + " found in elem.attributes."); + } + + test_exposed("className", v >= 8); + test_exposed("doScroll", false); + test_exposed("readyState", false); + test_exposed("clientTop", false); + if (v >= 9 /* todo_wine */) test_exposed("title", v < 9); + test_exposed("querySelectorAll", false); + test_exposed("textContent", false); + test_exposed("prefix", false); + test_exposed("firstElementChild", false); + test_exposed("onsubmit", false); + test_exposed("getElementsByClassName", false); + test_exposed("removeAttributeNS", false); + test_exposed("addEventListener", false); + test_exposed("hasAttribute", false); + test_exposed("removeEventListener", false); + test_exposed("dispatchEvent", false); + test_exposed("msSetPointerCapture", false); + if (v >= 9 /* todo_wine */) test_exposed("spellcheck", v < 9); + + if(v < 9) + test_exposed("toString", false); + else if(false /* todo_wine */) + ok(!elem.attributes.hasOwnProperty("toString"), "toString found in elem.attributes."); });
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=99202
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
=== w8adm (32 bit report) ===
mshtml: htmldoc.c:3084: Test failed: Incorrect error code: -2146697211 htmldoc.c:3089: Test failed: Page address: L"http://test.winehq.org/tests/winehq_snapshot/" htmldoc.c:5861: Test failed: expected OnChanged_1012 htmldoc.c:5862: Test failed: expected Exec_HTTPEQUIV htmldoc.c:5864: Test failed: expected Exec_SETTITLE htmldoc.c:5905: Test failed: expected FireNavigateComplete2
=== debiant2 (32 bit report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Arabic:Morocco report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit German report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit French report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Hebrew:Israel report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Hindi:India report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Japanese:Japan report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Chinese:China report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit WoW report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (64 bit WoW report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 64-bit code (0x000000000040a3b6).
On 10/1/21 3:12 PM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescugabrielopcode@gmail.com
Presently, even toString() is exposed as an attribute, because it's a builtin of the element, which makes no sense.
Unfortunately, it's more tricky than that. With that change, we'd expose too few attributes (instead of too many), which is likely to cause regressions. In general, attributes objects were not yet updated for compatibility modes and they are likely to require more drastic changes. I would expect attributes to be proper nodes in IE9+ mode (rather than node alike objects from previous versions), so we could probably make them a wrappers around nsIDOMAttr using HTMLDOMNode. Similarly, it would be interesting to try to use nsIDOMMozNamedAttrMap for HTMLAttributeCollection.
I'm not sure why it matters for toString, it seems like none of that should be required to get toString itself working.
Thanks,
Jacek
On 04/10/2021 19:32, Jacek Caban wrote:
On 10/1/21 3:12 PM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescugabrielopcode@gmail.com
Presently, even toString() is exposed as an attribute, because it's a builtin of the element, which makes no sense.
Unfortunately, it's more tricky than that. With that change, we'd expose too few attributes (instead of too many), which is likely to cause regressions. In general, attributes objects were not yet updated for compatibility modes and they are likely to require more drastic changes. I would expect attributes to be proper nodes in IE9+ mode (rather than node alike objects from previous versions), so we could probably make them a wrappers around nsIDOMAttr using HTMLDOMNode. Similarly, it would be interesting to try to use nsIDOMMozNamedAttrMap for HTMLAttributeCollection.
I'm not sure why it matters for toString, it seems like none of that should be required to get toString itself working.
Thanks,
Jacek
Well it's needed to test the object name and toString for attributes object, but if it's that complicated I'll let it aside for the moment and just drop it from the tests somehow and add a note (it's only one line anyway).
Basically what happens is this:
Test function (later, not sent yet) tries toString and checks it. Works (because of the toString "attribute" wrongly exposed from the element) so it retrieves it as a DISPID. So it ends up in HTMLAttributeCollection_invoke with DISPATCH_METHOD (i.e. calling it on an "attribute" named "toString" as a method since it's .toString() in the test code) which is of course not implemented and causes an exception. It's not the unimplemented issue though, I mean, does it even make sense to call an attribute with DISPATCH_METHOD?
Anyway like I said I'll just drop the test with a note and you can ignore this patch for now.
Thanks, Gabriel
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 93 ++++++++++++++++++++++++++++ dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/mshtml_private_iface.idl | 18 ++++++ dlls/mshtml/tests/documentmode.js | 3 +- 4 files changed, 114 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 870d7e8..7d35a60 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -191,6 +191,8 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii *ppv = &This->IProvideMultipleClassInfo_iface; }else if(IsEqualGUID(&IID_IWineHTMLWindowPrivate, riid)) { *ppv = &This->IWineHTMLWindowPrivate_iface; + }else if(IsEqualGUID(&IID_IWineHTMLWindowCompatPrivate, riid)) { + *ppv = &This->IWineHTMLWindowCompatPrivate_iface; }else if(IsEqualGUID(&IID_IMarshal, riid)) { *ppv = NULL; FIXME("(%p)->(IID_IMarshal %p)\n", This, ppv); @@ -3145,6 +3147,94 @@ static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = { window_private_get_console, };
+static inline HTMLWindow *impl_from_IWineHTMLWindowCompatPrivateVtbl(IWineHTMLWindowCompatPrivate *iface) +{ + return CONTAINING_RECORD(iface, HTMLWindow, IWineHTMLWindowCompatPrivate_iface); +} + +static HRESULT WINAPI window_compat_private_QueryInterface(IWineHTMLWindowCompatPrivate *iface, + REFIID riid, void **ppv) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv); +} + +static ULONG WINAPI window_compat_private_AddRef(IWineHTMLWindowCompatPrivate *iface) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface); +} + +static ULONG WINAPI window_compat_private_Release(IWineHTMLWindowCompatPrivate *iface) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IHTMLWindow2_Release(&This->IHTMLWindow2_iface); +} + +static HRESULT WINAPI window_compat_private_GetTypeInfoCount(IWineHTMLWindowCompatPrivate *iface, UINT *pctinfo) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI window_compat_private_GetTypeInfo(IWineHTMLWindowCompatPrivate *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI window_compat_private_GetIDsOfNames(IWineHTMLWindowCompatPrivate *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI window_compat_private_Invoke(IWineHTMLWindowCompatPrivate *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI window_compat_private_put_performance(IWineHTMLWindowCompatPrivate *iface, VARIANT v) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IHTMLWindow7_put_performance(&This->IHTMLWindow7_iface, v); +} + +static HRESULT WINAPI window_compat_private_get_performance(IWineHTMLWindowCompatPrivate *iface, VARIANT *p) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowCompatPrivateVtbl(iface); + + return IHTMLWindow7_get_performance(&This->IHTMLWindow7_iface, p); +} + +static const IWineHTMLWindowCompatPrivateVtbl WineHTMLWindowCompatPrivateVtbl = { + window_compat_private_QueryInterface, + window_compat_private_AddRef, + window_compat_private_Release, + window_compat_private_GetTypeInfoCount, + window_compat_private_GetTypeInfo, + window_compat_private_GetIDsOfNames, + window_compat_private_Invoke, + window_compat_private_put_performance, + window_compat_private_get_performance, +}; + static inline HTMLWindow *impl_from_IDispatchEx(IDispatchEx *iface) { return CONTAINING_RECORD(iface, HTMLWindow, IDispatchEx_iface); @@ -3649,6 +3739,8 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa { if(compat_mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLWindow7_tid, NULL); + else + dispex_info_add_interface(info, IWineHTMLWindowCompatPrivate_tid, NULL); if(compat_mode >= COMPAT_MODE_IE10) dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, NULL);
@@ -3714,6 +3806,7 @@ static void *alloc_window(size_t size) window->IObjectIdentity_iface.lpVtbl = &ObjectIdentityVtbl; window->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl; window->IWineHTMLWindowPrivate_iface.lpVtbl = &WineHTMLWindowPrivateVtbl; + window->IWineHTMLWindowCompatPrivate_iface.lpVtbl = &WineHTMLWindowCompatPrivateVtbl; window->ref = 1;
return window; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 624963a..44b9d74 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -276,6 +276,7 @@ typedef struct EventTarget EventTarget; XIID(IWineDOMTokenList) \ XIID(IWineHTMLElementPrivate) \ XIID(IWineHTMLWindowPrivate) \ + XIID(IWineHTMLWindowCompatPrivate) \ XIID(IWineMSHTMLConsole)
typedef enum { @@ -494,6 +495,7 @@ struct HTMLWindow { IObjectIdentity IObjectIdentity_iface; IProvideMultipleClassInfo IProvideMultipleClassInfo_iface; IWineHTMLWindowPrivate IWineHTMLWindowPrivate_iface; + IWineHTMLWindowCompatPrivate IWineHTMLWindowCompatPrivate_iface;
IWineMSHTMLConsole *console;
diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 5755afd..b9039c9 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -18,6 +18,8 @@
#pragma makedep typelib
+#include <mshtmdid.h> + import "ocidl.idl";
[ @@ -89,6 +91,22 @@ interface IWineHTMLWindowPrivate : IDispatch HRESULT console([retval, out] IDispatch **console); }
+[ + odl, + oleautomation, + dual, + hidden, + uuid(1b5939fc-8f84-43f3-8d89-f9a92069fad6) +] +interface IWineHTMLWindowCompatPrivate : IDispatch +{ + [propput, id(DISPID_IHTMLWINDOW7_PERFORMANCE)] + HRESULT performance([in] VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW7_PERFORMANCE)] + HRESULT performance([out, retval] VARIANT *p); +} + [ odl, oleautomation, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 41d7a6b..1359089 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -120,8 +120,7 @@ sync_test("window_props", function() { test_exposed("requestAnimationFrame", v >= 10); test_exposed("Map", v >= 11); test_exposed("Set", v >= 11); - if(v >= 9) /* FIXME: native exposes it in all compat modes */ - test_exposed("performance", true); + test_exposed("performance", true); test_exposed("console", v >= 10); });
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=99203
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
=== w1064_tsign (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w7u_el (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1633114966950 expected 1633114967013"
=== debiant2 (32 bit report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Arabic:Morocco report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit German report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit French report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Hebrew:Israel report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Hindi:India report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Japanese:Japan report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit Chinese:China report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (32 bit WoW report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040b890).
=== debiant2 (64 bit WoW report) ===
mshtml: dom.c:9542: Test failed: attr = NULL Unhandled exception: page fault on read access to 0x00000000 in 64-bit code (0x000000000040a3b6).