Author: akhaldi Date: Sat Nov 28 21:11:14 2015 New Revision: 70193
URL: http://svn.reactos.org/svn/reactos?rev=70193&view=rev Log: [MSHTML_WINETEST] Sync with Wine Staging 1.7.55. CORE-10536
Added: trunk/rostests/winetests/mshtml/xmlhttprequest.c (with props) Modified: trunk/rostests/winetests/mshtml/CMakeLists.txt trunk/rostests/winetests/mshtml/dom.c trunk/rostests/winetests/mshtml/events.c trunk/rostests/winetests/mshtml/events.html trunk/rostests/winetests/mshtml/htmldoc.c trunk/rostests/winetests/mshtml/script.c trunk/rostests/winetests/mshtml/style.c trunk/rostests/winetests/mshtml/testlist.c
Modified: trunk/rostests/winetests/mshtml/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/CMakeList... ============================================================================== --- trunk/rostests/winetests/mshtml/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/CMakeLists.txt [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -13,7 +13,8 @@ protocol.c script.c style.c - testlist.c) + testlist.c + xmlhttprequest.c)
add_executable(mshtml_winetest ${SOURCE} rsrc.rc)
Modified: trunk/rostests/winetests/mshtml/dom.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/dom.c?rev... ============================================================================== --- trunk/rostests/winetests/mshtml/dom.c [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/dom.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -30,6 +30,7 @@ #include <mshtmcid.h> #include <mshtmhst.h> //#include "docobj.h" +#include <hlink.h> //#include "dispex.h" #include "mshtml_test.h" #include <objsafe.h> @@ -270,6 +271,7 @@
static const IID * const attr_iids[] = { &IID_IHTMLDOMAttribute, + &IID_IHTMLDOMAttribute2, &IID_IDispatchEx, NULL }; @@ -426,6 +428,15 @@ &IID_IDispatch, &IID_IDispatchEx, &IID_IHTMLImageElementFactory, + NULL +}; + +static const IID * const selection_iids[] = { + &IID_IUnknown, + &IID_IDispatch, + &IID_IDispatchEx, + &IID_IHTMLSelectionObject, + &IID_IHTMLSelectionObject2, NULL };
@@ -508,6 +519,34 @@ return ret; }
+static const char *debugstr_variant(const VARIANT *var) +{ + static char buf[400]; + + if (!var) + return "(null)"; + + switch (V_VT(var)) + { + case VT_EMPTY: + return "{VT_EMPTY}"; + case VT_BSTR: + sprintf(buf, "{VT_BSTR: %s}", wine_dbgstr_w(V_BSTR(var))); + break; + case VT_BOOL: + sprintf(buf, "{VT_BOOL: %x}", V_BOOL(var)); + break; + case VT_UI4: + sprintf(buf, "{VT_UI4: %u}", V_UI4(var)); + break; + default: + sprintf(buf, "{vt %d}", V_VT(var)); + break; + } + + return buf; +} + static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2) { IUnknown *unk1, *unk2; @@ -852,6 +891,17 @@ return select; }
+#define get_option_iface(u) _get_option_iface(__LINE__,u) +static IHTMLOptionElement *_get_option_iface(unsigned line, IUnknown *unk) +{ + IHTMLOptionElement *option; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLOptionElement, (void**)&option); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLOptionElement: %08x\n", hres); + return option; +} + #define get_form_iface(u) _get_form_iface(__LINE__,u) static IHTMLFormElement *_get_form_iface(unsigned line, IUnknown *unk) { @@ -970,6 +1020,17 @@
hres = IUnknown_QueryInterface(unk, &IID_IHTMLLabelElement, (void**)&ret); ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLabelElement: %08x\n", hres); + return ret; +} + +#define get_attr2_iface(u) _get_attr2_iface(__LINE__,u) +static IHTMLDOMAttribute2 *_get_attr2_iface(unsigned line, IUnknown *unk) +{ + IHTMLDOMAttribute2 *ret; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMAttribute2, (void**)&ret); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMAttribute2: %08x\n", hres); return ret; }
@@ -1626,6 +1687,76 @@ _test_option_selected(line, option, b); }
+#define test_option_get_index(o,s) _test_option_get_index(__LINE__,o,s) +static void _test_option_get_index(unsigned line, IHTMLOptionElement *option, LONG exval) +{ + HRESULT hres; + LONG val; + + hres = IHTMLOptionElement_get_index(option, NULL); + ok_(__FILE__,line)(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres); + + val = 12345678; + hres = IHTMLOptionElement_get_index(option, &val); + ok_(__FILE__,line)(hres == S_OK, "get_index failed: %08x\n", hres); + ok_(__FILE__,line)(val == exval || broken(val == 12345678), /* Win2k doesn't touch it*/ + "value = %d, expected = %d\n", val, exval); +} + +#define test_option_put_defaultSelected(o,d) _test_option_put_defaultSelected(__LINE__,o,d) +static void _test_option_put_defaultSelected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b) +{ + HRESULT hres; + + hres = IHTMLOptionElement_put_defaultSelected(option, b); + ok_(__FILE__,line)(hres == S_OK, "put_defaultSelected %08x\n", hres); +} + +#define test_option_defaultSelected(o,e) _test_option_defaultSelected(__LINE__,o,e) +static void _test_option_defaultSelected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex) +{ + HRESULT hres; + VARIANT_BOOL b; + + hres = IHTMLOptionElement_get_defaultSelected(option, NULL); + ok_(__FILE__,line)(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres); + + b = 0x100; + hres = IHTMLOptionElement_get_defaultSelected(option, &b); + ok_(__FILE__,line)(hres == S_OK, "get_defaultSelected failed: %08x\n", hres); + ok_(__FILE__,line)(b == ex, "b = %x, expected = %x\n", b, ex); +} + +static void test_option_defaultSelected_property(IHTMLOptionElement *option) +{ + test_option_defaultSelected(option, VARIANT_FALSE); + test_option_selected(option, VARIANT_FALSE); + + test_option_put_defaultSelected(option, 0x100); /* Invalid value */ + test_option_defaultSelected(option, VARIANT_FALSE); + test_option_selected(option, VARIANT_FALSE); + + test_option_put_defaultSelected(option, VARIANT_TRUE); + test_option_defaultSelected(option, VARIANT_TRUE); + test_option_selected(option, VARIANT_FALSE); + + test_option_put_defaultSelected(option, 0x100); /* Invalid value */ + test_option_defaultSelected(option, VARIANT_FALSE); + test_option_selected(option, VARIANT_FALSE); + + test_option_put_selected(option, VARIANT_TRUE); + test_option_selected(option, VARIANT_TRUE); + test_option_defaultSelected(option, VARIANT_FALSE); + + test_option_put_defaultSelected(option, VARIANT_TRUE); + test_option_defaultSelected(option, VARIANT_TRUE); + test_option_selected(option, VARIANT_TRUE); + + /* Restore defaultSelected */ + test_option_put_defaultSelected(option, VARIANT_TRUE); + test_option_put_selected(option, VARIANT_FALSE); +} + #define test_textarea_value(t,v) _test_textarea_value(__LINE__,t,v) static void _test_textarea_value(unsigned line, IUnknown *unk, const char *exval) { @@ -1658,6 +1789,38 @@ _test_textarea_value(line, unk, value); }
+#define test_textarea_defaultvalue(t,v) _test_textarea_defaultvalue(__LINE__,t,v) +static void _test_textarea_defaultvalue(unsigned line, IUnknown *unk, const char *exval) +{ + IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk); + BSTR value = (void*)0xdeadbeef; + HRESULT hres; + + hres = IHTMLTextAreaElement_get_defaultValue(textarea, &value); + IHTMLTextAreaElement_Release(textarea); + ok_(__FILE__,line)(hres == S_OK, "get_defaultValue failed: %08x\n", hres); + if(exval) + ok_(__FILE__,line)(!strcmp_wa(value, exval), "defaultValue = %s, expected %s\n", wine_dbgstr_w(value), exval); + else + ok_(__FILE__,line)(!value, "value = %p\n", value); + SysFreeString(value); +} + +#define test_textarea_put_defaultvalue(t,v) _test_textarea_put_defaultvalue(__LINE__,t,v) +static void _test_textarea_put_defaultvalue(unsigned line, IUnknown *unk, const char *value) +{ + IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk); + BSTR tmp = a2bstr(value); + HRESULT hres; + + hres = IHTMLTextAreaElement_put_defaultValue(textarea, tmp); + IHTMLTextAreaElement_Release(textarea); + ok_(__FILE__,line)(hres == S_OK, "put_defaultValue failed: %08x\n", hres); + SysFreeString(tmp); + + _test_textarea_defaultvalue(line, unk, value); +} + #define test_textarea_readonly(t,v) _test_textarea_readonly(__LINE__,t,v) static void _test_textarea_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL ex) { @@ -1726,6 +1889,49 @@
IHTMLCommentElement_Release(comment); SysFreeString(text); +} + +#define test_attr_specified(a,b) _test_attr_specified(__LINE__,a,b) +static void _test_attr_specified(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected) +{ + VARIANT_BOOL specified; + HRESULT hres; + + hres = IHTMLDOMAttribute_get_specified(attr, &specified); + ok_(__FILE__,line)(hres == S_OK, "get_specified failed: %08x\n", hres); + ok_(__FILE__,line)(specified == expected, "specified = %x, expected %x\n", specified, expected); +} + +#define test_attr_expando(a,b) _test_attr_expando(__LINE__,a,b) +static void _test_attr_expando(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected) +{ + IHTMLDOMAttribute2 *attr2 = _get_attr2_iface(line, (IUnknown*)attr); + VARIANT_BOOL expando; + HRESULT hres; + + hres = IHTMLDOMAttribute2_get_expando(attr2, &expando); + ok_(__FILE__,line)(hres == S_OK, "get_expando failed: %08x\n", hres); + ok_(__FILE__,line)(expando == expected, "expando = %x, expected %x\n", expando, expected); + + IHTMLDOMAttribute2_Release(attr2); +} + +#define test_attr_value(a,b) _test_attr_value(__LINE__,a,b) +static void _test_attr_value(unsigned line, IHTMLDOMAttribute *attr, const char *exval) +{ + IHTMLDOMAttribute2 *attr2 = _get_attr2_iface(line, (IUnknown*)attr); + BSTR val; + HRESULT hres; + + hres = IHTMLDOMAttribute2_get_value(attr2, &val); + ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres); + if(exval) + ok_(__FILE__,line)(!strcmp_wa(val, exval), "value = %s, expected %s\n", wine_dbgstr_w(val), exval); + else + ok_(__FILE__,line)(!val, "value = %s, expected NULL\n", wine_dbgstr_w(val)); + + IHTMLDOMAttribute2_Release(attr2); + SysFreeString(val); }
#define test_comment_attrs(c) _test_comment_attrs(__LINE__,c) @@ -1751,6 +1957,8 @@ hres = IHTMLElement4_getAttributeNode(elem4, name, &attr); ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres); ok(attr != NULL, "attr == NULL\n"); + + test_attr_expando(attr, VARIANT_TRUE);
IHTMLDOMAttribute_Release(attr); IHTMLCommentElement_Release(comment); @@ -2048,6 +2256,61 @@ ok_(__FILE__,line) (hres == S_OK, "put_multiple failed: %08x\n", hres);
_test_select_multiple(line, select, val); +} + +#define test_select_size(s,v) _test_select_size(__LINE__,s,v) +static void _test_select_size(unsigned line, IHTMLSelectElement *select, LONG exval) +{ + HRESULT hres; + LONG val; + + hres = IHTMLSelectElement_get_size(select, NULL); + ok_(__FILE__,line) (hres == E_INVALIDARG, "got %08x, expected E_INVALIDARG\n", hres); + + val = 0xdeadbeef; + hres = IHTMLSelectElement_get_size(select, &val); + ok_(__FILE__,line) (hres == S_OK, "get_size failed: %08x\n", hres); + ok_(__FILE__,line) (val == exval, "size = %d, expected %d\n", val, exval); +} + +#define test_select_set_size(s,v,e) _test_select_set_size(__LINE__,s,v,e) +static void _test_select_set_size(unsigned line, IHTMLSelectElement *select, LONG val, HRESULT exhres) +{ + HRESULT hres; + + hres = IHTMLSelectElement_put_size(select, val); + ok_(__FILE__,line) (hres == exhres, "put_size(%d) got %08x, expect %08x\n", val, hres, exhres); +} + +#define test_select_name(s,v) _test_select_name(__LINE__,s,v) +static void _test_select_name(unsigned line, IHTMLSelectElement *select, const char *extext) +{ + HRESULT hres; + BSTR text; + + text = NULL; + hres = IHTMLSelectElement_get_name(select, &text); + ok_(__FILE__,line) (hres == S_OK, "get_name failed: %08x\n", hres); + if(extext) { + ok_(__FILE__,line) (text != NULL, "text == NULL\n"); + ok_(__FILE__,line) (!strcmp_wa(text, extext), "name = %s, expected %s\n", + wine_dbgstr_w(text), extext); + SysFreeString(text); + } else + ok_(__FILE__,line) (text == NULL, "text(%p) = %s\n", text, wine_dbgstr_w(text)); +} + +#define test_select_set_name(s,v) _test_select_set_name(__LINE__,s,v) +static void _test_select_set_name(unsigned line, IHTMLSelectElement *select, const char *text) +{ + HRESULT hres; + BSTR bstr; + + bstr = a2bstr(text); + + hres = IHTMLSelectElement_put_name(select, bstr); + ok_(__FILE__,line) (hres == S_OK, "put_name(%s) failed: %08x\n", wine_dbgstr_w(bstr), hres); + SysFreeString(bstr); }
#define test_range_text(r,t) _test_range_text(__LINE__,r,t) @@ -2339,6 +2602,27 @@ ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres); ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
+ V_VT(&name) = VT_UI4; + V_I4(&name) = len; + disp = (void*)0xdeadbeef; + hres = IHTMLElementCollection_item(col, name, index, &disp); + ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres); + ok_(__FILE__,line) (disp == NULL, "disp != NULL\n"); + + V_VT(&name) = VT_INT; + V_I4(&name) = len; + disp = (void*)0xdeadbeef; + hres = IHTMLElementCollection_item(col, name, index, &disp); + ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres); + ok_(__FILE__,line) (disp == NULL, "disp != NULL\n"); + + V_VT(&name) = VT_UINT; + V_I4(&name) = len; + disp = (void*)0xdeadbeef; + hres = IHTMLElementCollection_item(col, name, index, &disp); + ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres); + ok_(__FILE__,line) (disp == NULL, "disp != NULL\n"); + V_VT(&name) = VT_I4; V_I4(&name) = -1; disp = (void*)0xdeadbeef; @@ -2684,7 +2968,6 @@ test_select_length(select, 2);
hres = IHTMLSelectElement_remove(select, -1); - todo_wine ok(hres == E_INVALIDARG, "remove failed: %08x, expected E_INVALIDARG\n", hres); test_select_length(select, 2);
@@ -2922,7 +3205,7 @@ hres = IHTMLImgElement_get_alt(img, &alt); ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres); if(exalt) - ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "inexopected alt %s\n", wine_dbgstr_w(alt)); + ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "unexpected alt %s\n", wine_dbgstr_w(alt)); else ok_(__FILE__,line) (!alt, "alt != NULL\n"); SysFreeString(alt); @@ -3170,30 +3453,37 @@ ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres); ok(V_VT(&val) == VT_BSTR, "id: V_VT(&val) = %d\n", V_VT(&val)); ok(!strcmp_wa(V_BSTR(&val), "attr"), "id: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val))); + test_attr_expando(dom_attr, VARIANT_FALSE); + test_attr_value(dom_attr, "attr"); } else if(!strcmp_wa(name, "attr1")) { checked++; hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val); ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres); ok(V_VT(&val) == VT_BSTR, "attr1: V_VT(&val) = %d\n", V_VT(&val)); ok(!strcmp_wa(V_BSTR(&val), "attr1"), "attr1: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val))); + test_attr_expando(dom_attr, VARIANT_TRUE); + test_attr_value(dom_attr, "attr1"); } else if(!strcmp_wa(name, "attr2")) { checked++; hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val); ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres); ok(V_VT(&val) == VT_BSTR, "attr2: V_VT(&val) = %d\n", V_VT(&val)); ok(!V_BSTR(&val), "attr2: V_BSTR(&val) != NULL\n"); + test_attr_value(dom_attr, ""); } else if(!strcmp_wa(name, "attr3")) { checked++; hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val); ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres); ok(V_VT(&val) == VT_BSTR, "attr3: V_VT(&val) = %d\n", V_VT(&val)); ok(!strcmp_wa(V_BSTR(&val), "attr3"), "attr3: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val))); + test_attr_value(dom_attr, "attr3"); } else if(!strcmp_wa(name, "test")) { checked++; hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val); ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres); ok(V_VT(&val) == VT_I4, "test: V_VT(&val) = %d\n", V_VT(&val)); ok(V_I4(&val) == 1, "test: V_I4(&val) = %d\n", V_I4(&val)); + test_attr_value(dom_attr, "1"); }
IHTMLDOMAttribute_Release(dom_attr); @@ -3216,17 +3506,6 @@
IDispatch_Release(disp); IHTMLAttributeCollection_Release(attr_col); -} - -#define test_attr_specified(a,b) _test_attr_specified(__LINE__,a,b) -static void _test_attr_specified(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected) -{ - VARIANT_BOOL specified; - HRESULT hres; - - hres = IHTMLDOMAttribute_get_specified(attr, &specified); - ok_(__FILE__,line)(hres == S_OK, "get_specified failed: %08x\n", hres); - ok_(__FILE__,line)(specified == expected, "specified = %x, expected %x\n", specified, expected); }
#define test_elem_id(e,i) _test_elem_id(__LINE__,e,i) @@ -4097,6 +4376,40 @@ SysFreeString(str);
IHTMLFormElement_Release(form); +} + +static void test_select_form(IUnknown *uselect, IUnknown *uform) +{ + IHTMLSelectElement *select = get_select_iface(uselect); + IHTMLFormElement *form; + HRESULT hres; + + hres = IHTMLSelectElement_get_form(select, NULL); + ok(hres == E_POINTER, "got %08x\n, expected E_POINTER\n", hres); + + hres = IHTMLSelectElement_get_form(select, &form); + ok(hres == S_OK, "get_form failed: %08x\n", hres); + ok(form != NULL, "form == NULL\n"); + + test_form_length((IUnknown*)form, 1); + test_form_elements((IUnknown*)form); + test_form_name((IUnknown*)form, "form_name"); + + ok(iface_cmp(uform, (IUnknown*)form), "Expected %p, got %p\n", uform, form); + + IHTMLSelectElement_Release(select); + IHTMLFormElement_Release(form); +} + +static void test_select_form_notfound(IHTMLSelectElement *select) +{ + IHTMLFormElement *form; + HRESULT hres; + + form = (IHTMLFormElement*)0xdeadbeef; + hres = IHTMLSelectElement_get_form(select, &form); + ok(hres == S_OK, "get_form failed: %08x\n", hres); + ok(form == NULL, "got %p\n", form); }
#define test_meta_name(a,b) _test_meta_name(__LINE__,a,b) @@ -4722,6 +5035,20 @@ test_select_set_value(select, "val1"); test_select_value(select, "val1");
+ test_select_size(select, 0); + test_select_set_size(select, 1, S_OK); + test_select_size(select, 1); + + test_select_set_size(select, -1, CTL_E_INVALIDPROPERTYVALUE); + test_select_size(select, 1); + test_select_set_size(select, 3, S_OK); + test_select_size(select, 3); + + test_select_name(select, NULL); + test_select_set_name(select, "select-name"); + test_select_name(select, "select-name"); + test_select_form_notfound(select); + test_select_get_disabled(select, VARIANT_FALSE); test_select_set_disabled(select, VARIANT_TRUE); test_select_set_disabled(select, VARIANT_FALSE); @@ -4822,10 +5149,31 @@
test_option_put_text(option, "new text"); test_option_put_value(option, "new value"); + test_option_get_index(option, 0); + test_option_defaultSelected_property(option); test_option_put_selected(option, VARIANT_TRUE); test_option_put_selected(option, VARIANT_FALSE);
IHTMLOptionElement_Release(option); +} + +static void test_option_form(IUnknown *uoption, IUnknown *uform) +{ + IHTMLOptionElement *option = get_option_iface(uoption); + IHTMLFormElement *form; + HRESULT hres; + + hres = IHTMLOptionElement_get_form(option, NULL); + ok(hres == E_POINTER, "got %08x\n, expected E_POINTER\n", hres); + + hres = IHTMLOptionElement_get_form(option, &form); + ok(hres == S_OK, "get_form failed: %08x\n", hres); + ok(form != NULL, "form == NULL\n"); + + ok(iface_cmp(uform, (IUnknown*)form), "Expected %p, got %p\n", uform, form); + + IHTMLOptionElement_Release(option); + IHTMLFormElement_Release(form); }
static void test_create_img_elem(IHTMLDocument2 *doc) @@ -5089,6 +5437,7 @@ ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres);
test_disp((IUnknown*)selection, &IID_IHTMLSelectionObject, "[object]"); + test_ifaces((IUnknown*)selection, selection_iids);
hres = IHTMLSelectionObject_createRange(selection, &disp_range); ok(hres == S_OK, "IHTMLSelectionObject_createRange failed: %08x\n", hres); @@ -5278,6 +5627,7 @@
window = get_doc_window(doc); hres = IHTMLWindow2_get_navigator(window, &nav); + ok(hres == S_OK, "get_navigator failed: %08x\n", hres); IHTMLWindow2_Release(window);
hres = IOmNavigator_get_plugins(nav, &col); @@ -5294,6 +5644,12 @@ hres = IHTMLPluginsCollection_get_length(col, &len); ok(hres == S_OK, "get_length failed: %08x\n", hres); ok(!len, "length = %d\n", len); + + hres = IHTMLPluginsCollection_refresh(col, VARIANT_FALSE); + ok(hres == S_OK, "refresh failed: %08x\n", hres); + + hres = IHTMLPluginsCollection_refresh(col, VARIANT_TRUE); + ok(hres == S_OK, "refresh failed: %08x\n", hres);
ref = IHTMLPluginsCollection_Release(col); ok(!ref, "ref=%d\n", ref); @@ -5517,7 +5873,7 @@ ok_(__FILE__,line)(res, "LCIDToLocaleName failed: %u\n", GetLastError()); ok_(__FILE__,line)(!lstrcmpW(lang, buf), "lang = %s, expected %s\n", wine_dbgstr_w(lang), wine_dbgstr_w(buf)); }else { - skip("LCIDToLocaleName not available, unable to test language string\n"); + win_skip("LCIDToLocaleName not available, unable to test language string\n"); ok_(__FILE__,line)(lang != NULL, "lang == NULL\n"); } } @@ -5937,9 +6293,37 @@ IOmHistory_Release(history); }
+static void test_xmlhttprequest(IHTMLWindow5 *window) +{ + HRESULT hres; + VARIANT var; + IHTMLXMLHttpRequestFactory *factory; + IHTMLXMLHttpRequest *xml; + + hres = IHTMLWindow5_get_XMLHttpRequest(window, &var); + ok(hres == S_OK, "get_XMLHttpRequest failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "expect VT_DISPATCH, got %s\n", debugstr_variant(&var)); + + factory = NULL; + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLXMLHttpRequestFactory, (void**)&factory); + ok(hres == S_OK, "QueryInterface(&IID_IHTMLXMLHttpRequestFactory) failed: %08x\n", hres); + ok(factory != NULL, "factory == NULL\n"); + + xml = NULL; + hres = IHTMLXMLHttpRequestFactory_create(factory, &xml); + ok(hres == S_OK, "create failed: %08x\n", hres); + ok(xml != NULL, "xml == NULL\n"); + test_disp((IUnknown*)xml, &DIID_DispHTMLXMLHttpRequest, "[object]"); + + IHTMLXMLHttpRequest_Release(xml); + IHTMLXMLHttpRequestFactory_Release(factory); + VariantClear(&var); +} + static void test_window(IHTMLDocument2 *doc) { IHTMLWindow2 *window, *window2, *self, *parent; + IHTMLWindow5 *window5; IHTMLDocument2 *doc2 = NULL; IDispatch *disp; IUnknown *unk; @@ -6025,6 +6409,15 @@ test_window_status(window); set_window_status(window, "Test!"); test_history(window); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5); + if(SUCCEEDED(hres)) { + ok(window5 != NULL, "window5 == NULL\n"); + test_xmlhttprequest(window5); + IHTMLWindow5_Release(window5); + }else { + win_skip("IHTMLWindow5 not supported!\n"); + }
IHTMLWindow2_Release(window); } @@ -6745,7 +7138,7 @@ hres = IHTMLTable_put_width(table, v); ok(hres == S_OK, "put_width = %08x\n", hres); VariantClear(&v); - IHTMLTable_get_width(table, &v); + hres = IHTMLTable_get_width(table, &v); ok(hres == S_OK, "get_width = %08x\n", hres); ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); @@ -6755,7 +7148,7 @@ hres = IHTMLTable_put_width(table, v); ok(hres == S_OK, "put_width = %08x\n", hres); VariantClear(&v); - IHTMLTable_get_width(table, &v); + hres = IHTMLTable_get_width(table, &v); ok(hres == S_OK, "get_width = %08x\n", hres); ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); @@ -6765,7 +7158,7 @@ hres = IHTMLTable_put_width(table, v); ok(hres == S_OK, "put_width = %08x\n", hres); VariantClear(&v); - IHTMLTable_get_width(table, &v); + hres = IHTMLTable_get_width(table, &v); ok(hres == S_OK, "get_width = %08x\n", hres); ok(!strcmp_wa(V_BSTR(&v), "40.2%"), "Expected 40.2%%, got %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); @@ -6774,7 +7167,7 @@ V_I4(&v) = 11; hres = IHTMLTable_put_width(table, v); ok(hres == S_OK, "put_width = %08x\n", hres); - IHTMLTable_get_width(table, &v); + hres = IHTMLTable_get_width(table, &v); ok(hres == S_OK, "get_width = %08x\n", hres); ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); @@ -6783,7 +7176,7 @@ V_R8(&v) = 11.9; hres = IHTMLTable_put_width(table, v); ok(hres == S_OK, "put_width = %08x\n", hres); - IHTMLTable_get_width(table, &v); + hres = IHTMLTable_get_width(table, &v); ok(hres == S_OK, "get_width = %08x\n", hres); ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); @@ -8012,6 +8405,7 @@
attr = get_elem_attr_node((IUnknown*)elem, "tabIndex", TRUE); test_attr_specified(attr, VARIANT_FALSE); + test_attr_expando(attr, VARIANT_FALSE); IHTMLDOMAttribute_Release(attr); }
@@ -8135,6 +8529,9 @@
test_textarea_value((IUnknown*)elem, NULL); test_textarea_put_value((IUnknown*)elem, "test"); + test_textarea_defaultvalue((IUnknown*)elem, NULL); + test_textarea_put_defaultvalue((IUnknown*)elem, "defval text"); + test_textarea_put_value((IUnknown*)elem, "test"); test_textarea_readonly((IUnknown*)elem, VARIANT_FALSE); test_textarea_put_readonly((IUnknown*)elem, VARIANT_TRUE); test_textarea_put_readonly((IUnknown*)elem, VARIANT_FALSE); @@ -8145,6 +8542,13 @@
test_elem_istextedit(elem, VARIANT_TRUE);
+ IHTMLElement_Release(elem); + } + + test_elem_set_innerhtml((IUnknown*)div, "<textarea id="ta">default text</textarea>"); + elem = get_elem_by_id(doc, "ta", TRUE); + if(elem) { + test_textarea_defaultvalue((IUnknown*)elem, "default text"); IHTMLElement_Release(elem); }
@@ -8208,6 +8612,22 @@ IHTMLElement_Release(elem); }
+ test_elem_set_innerhtml((IUnknown*)div, + "<form id="form" name="form_name"><select id="sform"><option id="oform"></option></select></form>"); + elem = get_elem_by_id(doc, "sform", TRUE); + elem2 = get_elem_by_id(doc, "form", TRUE); + if(elem && elem2) { + test_select_form((IUnknown*)elem, (IUnknown*)elem2); + IHTMLElement_Release(elem); + + elem = get_elem_by_id(doc, "oform", TRUE); + if(elem) { + test_option_form((IUnknown*)elem, (IUnknown*)elem2); + IHTMLElement_Release(elem); + } + IHTMLElement_Release(elem2); + } + test_attr(div); test_blocked(doc, div); test_elem_names(doc); @@ -8873,6 +9293,22 @@ test_compatmode(doc, "CSS1Compat"); }
+static void test_quirks_mode_offsetHeight(IHTMLDocument2 *doc) +{ + IHTMLElement *elem; + HRESULT hres; + LONG oh; + + hres = IHTMLDocument2_get_body(doc, &elem); + ok(hres == S_OK, "get_body fauled: %08x\n", hres); + + /* body.offsetHeight value depends on window size in quirks mode */ + hres = IHTMLElement_get_offsetHeight(elem, &oh); + ok(hres == S_OK, "get_offsetHeight failed: %08x\n", hres); + todo_wine ok(oh == 500, "offsetHeight = %d\n", oh); + IHTMLElement_Release(elem); +} + static IHTMLDocument2 *notif_doc; static BOOL doc_complete;
@@ -8932,6 +9368,395 @@
static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
+static HRESULT cs_qi(REFIID,void **); +static IOleDocumentView *view; +static HWND container_hwnd; + +static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv) +{ + static const GUID undocumented_frame_iid = {0xfbece6c9,0x48d7,0x4a37,{0x8f,0xe3,0x6a,0xd4,0x27,0x2f,0xdd,0xac}}; + + if(!IsEqualGUID(&undocumented_frame_iid, riid)) + ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface) +{ + return 2; +} + +static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface) +{ + return 1; +} + +static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface, + LPCBORDERWIDTHS pborderwidths) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface, + LPCBORDERWIDTHS pborderwidths) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, + IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, + LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, + HOLEMENU holemenu, HWND hwndActiveObject) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = { + InPlaceFrame_QueryInterface, + InPlaceFrame_AddRef, + InPlaceFrame_Release, + InPlaceFrame_GetWindow, + InPlaceFrame_ContextSensitiveHelp, + InPlaceFrame_GetBorder, + InPlaceFrame_RequestBorderSpace, + InPlaceFrame_SetBorderSpace, + InPlaceFrame_SetActiveObject, + InPlaceFrame_InsertMenus, + InPlaceFrame_SetMenu, + InPlaceFrame_RemoveMenus, + InPlaceFrame_SetStatusText, + InPlaceFrame_EnableModeless, + InPlaceFrame_TranslateAccelerator +}; + +static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl }; + +static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv) +{ + return cs_qi(riid, ppv); +} + +static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface) +{ + return 2; +} + +static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface) +{ + return 1; +} + +static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd) +{ + *phwnd = container_hwnd; + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface, + IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, + LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + static const RECT rect = {0,0,500,500}; + + *ppFrame = &InPlaceFrame; + *ppDoc = NULL; + *lprcPosRect = rect; + *lprcClipRect = rect; + + lpFrameInfo->fMDIApp = FALSE; + lpFrameInfo->hwndFrame = container_hwnd; + lpFrameInfo->haccel = NULL; + lpFrameInfo->cAccelEntries = 0; + + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect) +{ + return E_NOTIMPL; +} + +static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = { + InPlaceSite_QueryInterface, + InPlaceSite_AddRef, + InPlaceSite_Release, + InPlaceSite_GetWindow, + InPlaceSite_ContextSensitiveHelp, + InPlaceSite_CanInPlaceActivate, + InPlaceSite_OnInPlaceActivate, + InPlaceSite_OnUIActivate, + InPlaceSite_GetWindowContext, + InPlaceSite_Scroll, + InPlaceSite_OnUIDeactivate, + InPlaceSite_OnInPlaceDeactivate, + InPlaceSite_DiscardUndoState, + InPlaceSite_DeactivateAndUndo, + InPlaceSite_OnPosRectChange, +}; + +static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl }; + +static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) +{ + return cs_qi(riid, ppv); +} + +static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface) +{ + return 2; +} + +static ULONG WINAPI ClientSite_Release(IOleClientSite *iface) +{ + return 1; +} + +static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, + IMoniker **ppmon) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IOleClientSiteVtbl ClientSiteVtbl = { + ClientSite_QueryInterface, + ClientSite_AddRef, + ClientSite_Release, + ClientSite_SaveObject, + ClientSite_GetMoniker, + ClientSite_GetContainer, + ClientSite_ShowObject, + ClientSite_OnShowWindow, + ClientSite_RequestNewObjectLayout +}; + +static IOleClientSite ClientSite = { &ClientSiteVtbl }; + +static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv) +{ + return cs_qi(riid, ppv); +} + +static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface) +{ + return 2; +} + +static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface) +{ + return 1; +} + +static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate) +{ + RECT rect = {0,0,500,500}; + IOleDocument *document; + HRESULT hres; + + hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document); + ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres); + + hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view); + IOleDocument_Release(document); + ok(hres == S_OK, "CreateView failed: %08x\n", hres); + + hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite); + ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres); + + hres = IOleDocumentView_UIActivate(view, TRUE); + ok(hres == S_OK, "UIActivate failed: %08x\n", hres); + + hres = IOleDocumentView_SetRect(view, &rect); + ok(hres == S_OK, "SetRect failed: %08x\n", hres); + + hres = IOleDocumentView_Show(view, TRUE); + ok(hres == S_OK, "Show failed: %08x\n", hres); + + return S_OK; +} + +static const IOleDocumentSiteVtbl DocumentSiteVtbl = { + DocumentSite_QueryInterface, + DocumentSite_AddRef, + DocumentSite_Release, + DocumentSite_ActivateMe +}; + +static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl }; + +static HRESULT cs_qi(REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid)) + *ppv = &ClientSite; + else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) + *ppv = &DocumentSite; + else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid)) + *ppv = &InPlaceSite; + + return *ppv ? S_OK : E_NOINTERFACE; +} + +static void set_client_site(IHTMLDocument2 *doc, BOOL set) +{ + IOleObject *oleobj; + HRESULT hres; + + if(!set && view) { + IOleDocumentView_Show(view, FALSE); + IOleDocumentView_CloseView(view, 0); + IOleDocumentView_SetInPlaceSite(view, NULL); + IOleDocumentView_Release(view); + view = NULL; + } + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj); + ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres); + + hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL); + ok(hres == S_OK, "SetClientSite failed: %08x\n", hres); + + if(set) { + IHlinkTarget *hlink; + + hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink); + ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres); + + hres = IHlinkTarget_Navigate(hlink, 0, NULL); + ok(hres == S_OK, "Navgate failed: %08x\n", hres); + + IHlinkTarget_Release(hlink); + } + + IOleObject_Release(oleobj); +} + static IHTMLDocument2 *create_doc_with_string(const char *str) { IPersistStreamInit *init; @@ -8990,6 +9815,7 @@ if(!doc) return;
+ set_client_site(doc, TRUE); do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) { @@ -8999,6 +9825,7 @@
test(doc);
+ set_client_site(doc, FALSE); ref = IHTMLDocument2_Release(doc); ok(!ref || broken(ref == 1), /* Vista */ "ref = %d\n", ref); @@ -9009,6 +9836,7 @@ run_domtest("<html></html>", check_quirks_mode); run_domtest("<!DOCTYPE html>\n<html></html>", check_strict_mode); run_domtest("<!-- comment --><!DOCTYPE html>\n<html></html>", check_quirks_mode); + run_domtest("<html><body></body></html>", test_quirks_mode_offsetHeight); }
START_TEST(dom) @@ -9018,6 +9846,8 @@ pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
CoInitialize(NULL); + container_hwnd = CreateWindowA("static", NULL, WS_POPUP|WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, NULL, NULL);
run_domtest(doc_str1, test_doc_elem); run_domtest(doc_str1, test_get_set_attr); @@ -9043,5 +9873,6 @@
test_quirks_mode();
+ DestroyWindow(container_hwnd); CoUninitialize(); }
Modified: trunk/rostests/winetests/mshtml/events.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/events.c?... ============================================================================== --- trunk/rostests/winetests/mshtml/events.c [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/events.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -1057,6 +1057,7 @@ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { IHTMLEventObj *event; + VARIANT v; HRESULT hres;
CHECK_EXPECT(submit_onclick_setret); @@ -1068,10 +1069,20 @@ ok(hres == S_OK, "get_event failed: %08x\n", hres); ok(event != NULL, "event == NULL\n");
+ V_VT(&v) = VT_ERROR; + hres = IHTMLEventObj_get_returnValue(event, &v); + ok(hres == S_OK, "get_returnValue failed: %08x\n", hres); + ok(V_VT(&v) == VT_EMPTY, "V_VT(returnValue) = %d\n", V_VT(&v)); + hres = IHTMLEventObj_put_returnValue(event, onclick_event_retval); ok(hres == S_OK, "put_returnValue failed: %08x\n", hres); + + V_VT(&v) = VT_ERROR; + hres = IHTMLEventObj_get_returnValue(event, &v); + ok(hres == S_OK, "get_returnValue failed: %08x\n", hres); + ok(VarCmp(&v, &onclick_event_retval, 0, 0) == VARCMP_EQ, "unexpected returnValue\n"); + IHTMLEventObj_Release(event); - *pvarRes = onclick_retval; return S_OK; } @@ -1097,9 +1108,9 @@
hres = IHTMLEventObj_put_cancelBubble(event, VARIANT_TRUE); ok(hres == S_OK, "put_returnValue failed: %08x\n", hres); + + test_event_cancelbubble(event, VARIANT_TRUE); IHTMLEventObj_Release(event); - - test_event_cancelbubble(event, VARIANT_TRUE); return S_OK; }
@@ -1412,7 +1423,7 @@ DispatchMessageW(&msg); } }else { - while(!b && PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { + while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessageW(&msg); } @@ -1571,7 +1582,7 @@ V_VT(&v) = VT_BSTR; V_BSTR(&v) = a2bstr("function();"); hres = IHTMLElement_put_onclick(div, v); - todo_wine ok(hres == S_OK, "put_onclick failed: %08x\n", hres); + ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
if(hres == S_OK) { V_VT(&v) = VT_EMPTY; @@ -1843,7 +1854,7 @@ ok(V_DISPATCH(&v) == (IDispatch*)&img_onerror_obj, "V_DISPATCH(onerror) != onerrorFunc\n"); VariantClear(&v);
- str = a2bstr("https://www.winehq.org/images/winehq_logo_text.png"); + str = a2bstr("http://test.winehq.org/tests/winehq_snapshot/index_files/winehq_logo_text.pn..."); hres = IHTMLImgElement_put_src(img, str); ok(hres == S_OK, "put_src failed: %08x\n", hres); SysFreeString(str);
Modified: trunk/rostests/winetests/mshtml/events.html URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/events.ht... ============================================================================== --- trunk/rostests/winetests/mshtml/events.html [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/events.html [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -139,6 +139,24 @@ readystatechange_log = "append"; }
+var string_handler_called = false; + +function test_string_event_handler() { + var e = document.createElement("div"); + var event_str = "string_handler_called = true;"; + + document.body.appendChild(e); + e.onclick = event_str; + ok(e.onclick === event_str, "e.onclick = " + e.onclick); + e.click(); + ok(string_handler_called === false, "string handler called"); + + e.setAttribute("onclick", event_str); + ok(e.onclick === event_str, "e.onclick = " + e.onclick); + e.click(); + ok(string_handler_called === false, "string handler called"); +} + window.onload = function() { try { ok(inlscr_complete_called, "onreadystatechange not fired"); @@ -159,6 +177,7 @@ ondataavailable_test(); test_handler_this(); test_insert_script(); + test_string_event_handler(); }catch(e) { ok(false, "Got an exception: " + e.message); }
Modified: trunk/rostests/winetests/mshtml/htmldoc.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/htmldoc.c... ============================================================================== --- trunk/rostests/winetests/mshtml/htmldoc.c [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/htmldoc.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -872,7 +872,13 @@
static HRESULT WINAPI NewWindowManager_QueryInterface(INewWindowManager *iface, REFIID riid, void **ppv) { - ok(0, "unexpected call\n"); + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(riid, &IID_INewWindowManager)) { + *ppv = iface; + return S_OK; + } + + trace("NewWindowManager_QueryInterface %s\n", wine_dbgstr_guid(riid)); + *ppv = NULL; return E_NOINTERFACE; }
@@ -2614,6 +2620,12 @@ ok(ppchURLOut != NULL, "ppchURLOut == NULL\n"); ok(!*ppchURLOut, "*ppchURLOut = %p\n", *ppchURLOut);
+ /* Not related to hash navigation, just return NULL and S_OK in some cases. */ + if(loading_hash) { + *ppchURLOut = NULL; + return S_OK; + } + return S_FALSE; }
@@ -2633,7 +2645,7 @@ ok(pchKey != NULL, "pchKey = NULL\n"); if(pchKey) ok(!*pchKey, "*pchKey=%p, expected NULL\n", *pchKey); - ok(!dw, "dw=%d, xepected 0\n", dw); + ok(!dw, "dw=%d, expected 0\n", dw); return S_OK; }
@@ -2866,8 +2878,6 @@ }
if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) { - if(nCmdID != 63 && nCmdID != 178 && (!is_refresh || nCmdID != 37)) - test_readyState(NULL); ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
switch(nCmdID) { @@ -2881,6 +2891,8 @@ test_readyState(NULL); load_state = LD_LOADING; }else { + if(!is_refresh) + test_readyState(NULL); if(nav_url) test_GetCurMoniker(doc_unk, NULL, nav_serv_url, FALSE); else if(load_from_stream) @@ -2944,6 +2956,7 @@ if(pvaIn) ok(V_VT(pvaOut) == VT_EMPTY, "V_VT(pvaOut)=%d\n", V_VT(pvaOut));
+ test_readyState(NULL); return E_NOTIMPL;
case 103: @@ -2952,6 +2965,7 @@ ok(pvaIn == NULL, "pvaIn != NULL\n"); ok(pvaOut == NULL, "pvaOut != NULL\n");
+ test_readyState(NULL); return E_NOTIMPL;
case 105: @@ -2960,12 +2974,14 @@ ok(pvaIn != NULL, "pvaIn == NULL\n"); ok(pvaOut == NULL, "pvaOut != NULL\n");
+ test_readyState(NULL); return E_NOTIMPL;
case 138: CHECK_EXPECT2(Exec_ShellDocView_138); ok(!pvaIn, "pvaIn != NULL\n"); ok(!pvaOut, "pvaOut != NULL\n"); + test_readyState(NULL); return S_OK;
case 140: @@ -2974,10 +2990,13 @@ ok(pvaIn == NULL, "pvaIn != NULL\n"); ok(pvaOut == NULL, "pvaOut != NULL\n");
+ test_readyState(NULL); return E_NOTIMPL;
case 83: + case 101: case 102: + case 132: case 133: case 134: /* TODO */ case 135: @@ -2991,6 +3010,7 @@ case 180: case 181: case 182: + case 183: return E_NOTIMPL;
default: @@ -3447,7 +3467,8 @@ if(!testing_submit) { ok(!pPostData, "pPostData = %p\n", pPostData); ok(!cbPostData, "cbPostData = %d\n", cbPostData); - ok(!lpszHeaders, "lpszHeaders = %s\n", wine_dbgstr_w(lpszHeaders)); + ok(!lpszHeaders || !strcmp_wa(lpszHeaders, "Referer: http://test.winehq.org/tests/winehq_snapshot/%5Cr%5Cn"), + "lpszHeaders = %s\n", wine_dbgstr_w(lpszHeaders)); }else { ok(cbPostData == 9, "cbPostData = %d\n", cbPostData); ok(!memcmp(pPostData, "cmd=TEST", cbPostData), "pPostData = %p\n", pPostData); @@ -5731,7 +5752,6 @@ SET_EXPECT(CountEntries); SET_EXPECT(Exec_HTTPEQUIV_DONE); } - SET_EXPECT(SetStatusText); if(nav_url || support_wbapp) { SET_EXPECT(UpdateUI); SET_EXPECT(Exec_UPDATECOMMANDS); @@ -5925,6 +5945,56 @@
IPersistMoniker_Release(persist_mon); } +} + +static void test_put_hash(IHTMLDocument2 *doc, const char *new_hash) +{ + static char nav_url_buff[256]; + IHTMLLocation *location; + BSTR str; + char *psharp; + HRESULT hres; + + trace("put_hash, url = %s, new hash = %s\n", nav_url, new_hash); + + location = NULL; + hres = IHTMLDocument2_get_location(doc, &location); + ok(hres == S_OK, "get_location failed: %08x\n", hres); + ok(location != NULL, "location == NULL\n"); + + SET_EXPECT(TranslateUrl); + SET_EXPECT(Exec_ShellDocView_67); + SET_EXPECT(FireBeforeNavigate2); + SET_EXPECT(FireDocumentComplete); + SET_EXPECT(FireNavigateComplete2); + + /* Edit nav_url */ + strcpy(nav_url_buff, nav_url); + psharp = strchr(nav_url_buff, '#'); + if (psharp) + *psharp = '\0'; + strcat(nav_url_buff, new_hash); + nav_url = nav_url_buff; + + str = a2bstr(new_hash); + hres = IHTMLLocation_put_hash(location, str); + ok (hres == S_OK, "put_hash failed: %08x\n", hres); + SysFreeString(str); + + CHECK_CALLED(TranslateUrl); + CHECK_CALLED_BROKEN(Exec_ShellDocView_67); /* Broken on Win7 and 8 */ + CHECK_CALLED(FireBeforeNavigate2); + CHECK_CALLED(FireDocumentComplete); + CHECK_CALLED(FireNavigateComplete2); + + + /* Check the result */ + hres = IHTMLLocation_get_hash(location, &str); + ok(hres == S_OK, "get_hash failed: %08x\n", hres); + ok(!strcmp_wa(str, new_hash), "expected %s, got %s\n", new_hash, wine_dbgstr_w(str)); + SysFreeString(str); + + IHTMLLocation_Release(location); }
static void test_put_href(IHTMLDocument2 *doc, BOOL use_replace, const char *href, const char *new_nav_url, BOOL is_js, @@ -6111,7 +6181,7 @@ ok(hres == S_OK, "Could not get IPersistHistory iface: %08x\n", hres);
prev_url = nav_url; - nav_url = "http://test.winehq.org/tests/winehq_snapshot/#test"; + nav_url = "http://test.winehq.org/tests/winehq_snapshot/#hash_test"; nav_serv_url = "http://test.winehq.org/tests/winehq_snapshot/";
SET_EXPECT(Exec_ShellDocView_138); @@ -6504,11 +6574,10 @@
editmode = TRUE;
- if(loaded) + if(loaded) { load_state = LD_DOLOAD; - - if(loaded) SET_EXPECT(GetClassID); + } SET_EXPECT(SetStatusText); SET_EXPECT(Exec_ShellDocView_37); SET_EXPECT(GetHostInfo); @@ -7717,6 +7786,7 @@ nav_url = nav_serv_url = "http://test.winehq.org/tests/winehq_snapshot/"; /* for valid prev nav_url */ if(support_wbapp) { test_put_href(doc, FALSE, "#test", "http://test.winehq.org/tests/winehq_snapshot/#test", FALSE, TRUE, 0); + test_put_hash(doc, "#hash_test"); test_travellog(doc); test_refresh(doc); } @@ -8493,8 +8563,12 @@ hres = IServiceProvider_QueryService(provider, &SID_SContainerDispatch, &IID_IUnknown, (void**)&unk); ok(hres == S_OK, "got 0x%08x\n", hres); ok(iface_cmp((IUnknown*)doc, unk), "got wrong pointer\n"); - IUnknown_Release(unk); + + hres = IServiceProvider_QueryService(provider, &SID_SHTMLEditServices, &IID_IHTMLEditServices, (void**)&unk); + ok(hres == S_OK, "QueryService(HTMLEditServices) failed: %08x\n", hres); + IUnknown_Release(unk); + IServiceProvider_Release(provider); release_document(doc); }
Modified: trunk/rostests/winetests/mshtml/script.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/script.c?... ============================================================================== --- trunk/rostests/winetests/mshtml/script.c [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/script.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -333,20 +333,20 @@ { if(IsEqualGUID(guidService, &SID_VariantConversion)) { CHECK_EXPECT(QS_VariantConversion); - ok(IsEqualGUID(riid, &IID_IVariantChangeType), "uenxpected riid %s\n", wine_dbgstr_guid(riid)); + ok(IsEqualGUID(riid, &IID_IVariantChangeType), "unexpected riid %s\n", wine_dbgstr_guid(riid)); *ppv = &VChangeType; return S_OK; }
if(IsEqualGUID(guidService, &IID_IActiveScriptSite)) { CHECK_EXPECT(QS_IActiveScriptSite); - ok(IsEqualGUID(riid, &IID_IOleCommandTarget), "uenxpected riid %s\n", wine_dbgstr_guid(riid)); + ok(IsEqualGUID(riid, &IID_IOleCommandTarget), "unexpected riid %s\n", wine_dbgstr_guid(riid)); return IActiveScriptSite_QueryInterface(site, riid, ppv); }
if(IsEqualGUID(guidService, &SID_GetCaller)) { CHECK_EXPECT(QS_GetCaller); - ok(IsEqualGUID(riid, &IID_IServiceProvider), "uenxpected riid %s\n", wine_dbgstr_guid(riid)); + ok(IsEqualGUID(riid, &IID_IServiceProvider), "unexpected riid %s\n", wine_dbgstr_guid(riid)); *ppv = NULL; return E_NOINTERFACE; }
Modified: trunk/rostests/winetests/mshtml/style.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/style.c?r... ============================================================================== --- trunk/rostests/winetests/mshtml/style.c [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/style.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -2435,6 +2435,17 @@ ok(!strcmp_wa(str, "nowrap"), "whiteSpace = %s\n", wine_dbgstr_w(str)); SysFreeString(str);
+ str = a2bstr("normal"); + hres = IHTMLStyle_put_whiteSpace(style, str); + SysFreeString(str); + ok(hres == S_OK, "put_whiteSpace failed: %08x\n", hres); + + str = NULL; + hres = IHTMLStyle_get_whiteSpace(style, &str); + ok(hres == S_OK, "get_whiteSpace failed: %08x\n", hres); + ok(!strcmp_wa(str, "normal"), "whiteSpace = %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + /* listStyleType */ hres = IHTMLStyle_get_listStyleType(style, &str); ok(hres == S_OK, "get_listStyleType failed: %08x\n", hres); @@ -2622,6 +2633,7 @@ static void test_current_style(IHTMLCurrentStyle *current_style) { IHTMLCurrentStyle2 *current_style2; + IHTMLCurrentStyle3 *current_style3; VARIANT_BOOL b; BSTR str; HRESULT hres; @@ -2895,6 +2907,16 @@ ok(b == VARIANT_TRUE, "hasLayout = %x\n", b);
IHTMLCurrentStyle2_Release(current_style2); + + hres = IHTMLCurrentStyle_QueryInterface(current_style, &IID_IHTMLCurrentStyle3, (void**)¤t_style3); + ok(hres == S_OK, "Could not get IHTMLCurrentStyle3 iface: %08x\n", hres); + + hres = IHTMLCurrentStyle3_get_whiteSpace(current_style3, &str); + ok(hres == S_OK, "get_whiteSpace failed: %08x\n", hres); + ok(!strcmp_wa(str, "normal"), "whiteSpace = %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IHTMLCurrentStyle3_Release(current_style3); }
static const char basic_test_str[] = "<html><body><div id="divid"></div/</body></html>";
Modified: trunk/rostests/winetests/mshtml/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/testlist.... ============================================================================== --- trunk/rostests/winetests/mshtml/testlist.c [iso-8859-1] (original) +++ trunk/rostests/winetests/mshtml/testlist.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -12,6 +12,7 @@ extern void func_protocol(void); extern void func_script(void); extern void func_style(void); +extern void func_xmlhttprequest(void);
const struct test winetest_testlist[] = { @@ -24,5 +25,6 @@ { "protocol", func_protocol }, { "script", func_script }, { "style", func_style }, + { "xmlhttprequest", func_xmlhttprequest }, { 0, 0 } };
Added: trunk/rostests/winetests/mshtml/xmlhttprequest.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/mshtml/xmlhttpre... ============================================================================== --- trunk/rostests/winetests/mshtml/xmlhttprequest.c (added) +++ trunk/rostests/winetests/mshtml/xmlhttprequest.c [iso-8859-1] Sat Nov 28 21:11:14 2015 @@ -0,0 +1,940 @@ +/* + * Copyright 2015 Zhenbo Li + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include <wine/test.h> +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "mshtml.h" + +static BSTR a2bstr(const char *str) +{ + BSTR ret; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = SysAllocStringLen(NULL, len); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + +static int strcmp_wa(LPCWSTR strw, const char *stra) +{ + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); + return lstrcmpA(stra, buf); +} + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0) + +#define CHECK_EXPECT2(func) \ + do { \ + trace(#func "\n"); \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +static IHTMLXMLHttpRequest *xhr = NULL; +static BSTR content_type = NULL; +static int loading_cnt = 0; +static int readystatechange_cnt = 0; + +DEFINE_EXPECT(xmlhttprequest_onreadystatechange_opened); +DEFINE_EXPECT(xmlhttprequest_onreadystatechange_headers_received); +DEFINE_EXPECT(xmlhttprequest_onreadystatechange_loading); +DEFINE_EXPECT(xmlhttprequest_onreadystatechange_done); + +#define test_disp(u,id) _test_disp(__LINE__,u,id) +static void _test_disp(unsigned line, IUnknown *unk, const IID *diid) +{ + IDispatchEx *dispex; + ITypeInfo *typeinfo; + UINT ticnt; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex); + ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres); + if(FAILED(hres)) + return; + + ticnt = 0xdeadbeef; + hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt); + ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres); + ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt); + + hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo); + ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres); + + if(SUCCEEDED(hres)) { + TYPEATTR *type_attr; + + hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr); + ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres); + ok_(__FILE__,line) (IsEqualGUID(&type_attr->guid, diid), "unexpected guid %s\n", + wine_dbgstr_guid(&type_attr->guid)); + + ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr); + ITypeInfo_Release(typeinfo); + } + + IDispatchEx_Release(dispex); +} + +#define test_event_args(a,b,c,d,e,f,g) _test_event_args(__LINE__,a,b,c,d,e,f,g) +static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok_(__FILE__,line) (id == DISPID_VALUE, "id = %d\n", id); + ok_(__FILE__,line) (wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags); + ok_(__FILE__,line) (pdp != NULL, "pdp == NULL\n"); + ok_(__FILE__,line) (pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs); + ok_(__FILE__,line) (pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs); + ok_(__FILE__,line) (pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", + pdp->rgdispidNamedArgs[0]); + ok_(__FILE__,line) (V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg)); + ok_(__FILE__,line) (pvarRes != NULL, "pvarRes == NULL\n"); + ok_(__FILE__,line) (pei != NULL, "pei == NULL"); + ok_(__FILE__,line) (!pspCaller, "pspCaller != NULL\n"); + + if(dispiid) + _test_disp(line, (IUnknown*)V_DISPATCH(pdp->rgvarg), dispiid); +} + +static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch) + || IsEqualGUID(riid, &IID_IDispatchEx)) + *ppv = iface; + else { + ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); + return E_NOINTERFACE; + } + + return S_OK; +} + +static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface) +{ + return 2; +} + +static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface) +{ + return 1; +} + +static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) +{ + ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI xmlhttprequest_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + LONG val; + HRESULT hres; + + test_event_args(&DIID_DispHTMLXMLHttpRequest, id, wFlags, pdp, pvarRes, pei, pspCaller); + + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + readystatechange_cnt++; + + switch(val) { + case 1: + CHECK_EXPECT(xmlhttprequest_onreadystatechange_opened); + break; + case 2: + CHECK_EXPECT(xmlhttprequest_onreadystatechange_headers_received); + break; + case 3: + loading_cnt++; + CHECK_EXPECT2(xmlhttprequest_onreadystatechange_loading); + break; + case 4: + CHECK_EXPECT(xmlhttprequest_onreadystatechange_done); + break; + default: + ok(0, "unexpected readyState: %d\n", val); + } + return S_OK; +} + +static IDispatchExVtbl xmlhttprequest_onreadystatechangeFuncVtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + DispatchEx_GetDispID, + xmlhttprequest_onreadystatechange, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; +static IDispatchEx xmlhttprequest_onreadystatechange_obj = { &xmlhttprequest_onreadystatechangeFuncVtbl }; + +static BOOL doc_complete; +static IHTMLDocument2 *notif_doc; + +static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, + REFIID riid, void**ppv) +{ + if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) { + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected call\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface) +{ + return 2; +} + +static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface) +{ + return 1; +} + +static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID) +{ + if(dispID == DISPID_READYSTATE){ + BSTR state; + HRESULT hres; + + hres = IHTMLDocument2_get_readyState(notif_doc, &state); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + + if(!strcmp_wa(state, "complete")) + doc_complete = TRUE; + + SysFreeString(state); + } + + return S_OK; +} + +static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = { + PropertyNotifySink_QueryInterface, + PropertyNotifySink_AddRef, + PropertyNotifySink_Release, + PropertyNotifySink_OnChanged, + PropertyNotifySink_OnRequestEdit +}; + +static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl }; + +static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise) +{ + IConnectionPointContainer *container; + IConnectionPoint *cp; + DWORD cookie; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container); + ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres); + + hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp); + IConnectionPointContainer_Release(container); + ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres); + + hres = IConnectionPoint_Advise(cp, unk_advise, &cookie); + IConnectionPoint_Release(cp); + ok(hres == S_OK, "Advise failed: %08x\n", hres); +} + +static void pump_msgs(BOOL *b) +{ + MSG msg; + + if(b) { + while(!*b && GetMessageW(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + }else { + while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } +} + + +struct HEADER_TYPE { + const char *key; + const char *value; +}; + +static void create_xmlhttprequest(IHTMLDocument2 *doc) +{ + IHTMLWindow2 *window; + IHTMLWindow5 *window5; + VARIANT var; + IHTMLXMLHttpRequestFactory *factory; + HRESULT hres; + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres); + ok(window != NULL, "window == NULL\n"); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5); + IHTMLWindow2_Release(window); + if(FAILED(hres)) { + win_skip("IHTMLWindow5 not supported\n"); + return; + } + + VariantInit(&var); + hres = IHTMLWindow5_get_XMLHttpRequest(window5, &var); + IHTMLWindow5_Release(window5); + ok(hres == S_OK, "get_XMLHttpRequest failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(&var) is %08x, expected VT_DISPATCH\n", V_VT(&var)); + + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLXMLHttpRequestFactory, (void**)&factory); + VariantClear(&var); + ok(hres == S_OK, "QueryInterface(IID_IHTMLXMLHttpRequestFactory) failed: %08x\n", hres); + ok(factory != NULL, "factory == NULL\n"); + + hres = IHTMLXMLHttpRequestFactory_create(factory, &xhr); + IHTMLXMLHttpRequestFactory_Release(factory); + ok(hres == S_OK, "create failed: %08x\n", hres); + ok(xhr != NULL, "xhr == NULL\n"); +} + +static void test_header(const struct HEADER_TYPE expect[], int num) +{ + int i; + BSTR key, text, all_header; + HRESULT hres; + char all[4096], buf[512]; + + all_header = NULL; + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, &all_header); + ok(hres == S_OK, "getAllResponseHeader failed: %08x\n", hres); + ok(all_header != NULL, "all_header == NULL\n"); + + WideCharToMultiByte(CP_UTF8, 0, all_header, -1, all, sizeof(all), NULL, NULL); + SysFreeString(all_header); + + for(i = 0; i < num; ++i) { + text = NULL; + key = a2bstr(expect[i].key); + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, key, &text); + ok(hres == S_OK, "getResponseHeader failed, got %08x\n", hres); + ok(text != NULL, "text == NULL\n"); + ok(!strcmp_wa(text, expect[i].value), + "Expect %s: %s, got %s\n", expect[i].key, expect[i].value, wine_dbgstr_w(text)); + SysFreeString(key); + SysFreeString(text); + + strcpy(buf, expect[i].key); + strcat(buf, ": "); + strcat(buf, expect[i].value); + ok(strstr(all, buf) != NULL, "AllResponseHeaders(%s) don't have expected substr(%s)\n", all, buf); + } +} + +static void test_sync_xhr(IHTMLDocument2 *doc, const char *xml_url, const char *expect_text) +{ + VARIANT vbool, vempty, var; + BSTR method, url; + BSTR text; + LONG val; + HRESULT hres; + static const struct HEADER_TYPE expect_headers[] = { + {"Server", "Apache"}, + {"Accept-Ranges", "bytes"}, + {"Content-Length", "51"}, + {"Content-Type", "application/xml"} + }; + + create_xmlhttprequest(doc); + if(!xhr) + return; + + V_VT(&var) = VT_EMPTY; + hres = IHTMLXMLHttpRequest_get_onreadystatechange(xhr, &var); + ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres); + ok(V_VT(&var) == VT_NULL, "V_VT(onreadystatechange) = %d\n", V_VT(&var)); + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)&xmlhttprequest_onreadystatechange_obj; + hres = IHTMLXMLHttpRequest_put_onreadystatechange(xhr, var); + ok(hres == S_OK, "put_onreadystatechange failed: %08x\n", hres); + + V_VT(&var) = VT_EMPTY; + hres = IHTMLXMLHttpRequest_get_onreadystatechange(xhr, &var); + ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(onreadystatechange) = %d\n", V_VT(&var)); + ok(V_DISPATCH(&var) == (IDispatch*)&xmlhttprequest_onreadystatechange_obj, "unexpected onreadystatechange value\n"); + + hres = IHTMLXMLHttpRequest_get_readyState(xhr, NULL); + ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 0, "Expect UNSENT, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_status(xhr, NULL); + ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(val == 0, "Expect 0, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_statusText(xhr, NULL); + ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres); + + hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(text == NULL, "Expect NULL, got %p\n", text); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + method = a2bstr("GET"); + url = a2bstr(xml_url); + V_VT(&vbool) = VT_BOOL; + V_BOOL(&vbool) = VARIANT_FALSE; + V_VT(&vempty) = VT_EMPTY; + + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty); + todo_wine ok(hres == S_OK, "open failed: %08x\n", hres); /* Gecko 30+ only supports async */ + todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + + SysFreeString(method); + SysFreeString(url); + + if(FAILED(hres)) { + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; + return; + } + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(val == 0, "Expect 0, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(text == NULL, "Expect NULL, got %p\n", text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 1, "Expect OPENED, got %d\n", val); + + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + SET_EXPECT(xmlhttprequest_onreadystatechange_headers_received); + SET_EXPECT(xmlhttprequest_onreadystatechange_loading); + SET_EXPECT(xmlhttprequest_onreadystatechange_done); + loading_cnt = 0; + hres = IHTMLXMLHttpRequest_send(xhr, vempty); + ok(hres == S_OK, "send failed: %08x\n", hres); + CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + CHECK_CALLED(xmlhttprequest_onreadystatechange_headers_received); + CHECK_CALLED(xmlhttprequest_onreadystatechange_loading); + CHECK_CALLED(xmlhttprequest_onreadystatechange_done); + ok(loading_cnt == 1, "loading_cnt = %d\n", loading_cnt); + + text = NULL; + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, &text); + ok(hres == S_OK, "getResponseHeader failed, got %08x\n", hres); + ok(text != NULL, "text == NULL\n"); + SysFreeString(text); + + if(expect_text) + test_header(expect_headers, sizeof(expect_headers)/sizeof(expect_headers[0])); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == S_OK, "get_status failed: %08x\n", hres); + ok(val == 200, "Expect 200, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text); + ok(hres == S_OK, "get_statusText failed: %08x\n", hres); + ok(text != NULL, "text == NULL\n"); + ok(!strcmp_wa(text, "OK"), + "Expected "OK", got %s\n", wine_dbgstr_w(text)); + SysFreeString(text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 4, "Expect DONE, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_responseText(xhr, &text); + ok(hres == S_OK, "get_responseText failed: %08x\n", hres); + ok(text != NULL, "test == NULL\n"); + if(expect_text) + ok(!strcmp_wa(text, expect_text), "expect %s, got %s\n", + expect_text, wine_dbgstr_w(text)); + SysFreeString(text); + + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; +} + +static void test_async_xhr(IHTMLDocument2 *doc, const char *xml_url, const char *expect_text) +{ + VARIANT vbool, vempty, var; + BSTR method, url; + BSTR text; + LONG val; + HRESULT hres; + static const struct HEADER_TYPE expect_headers[] = { + {"Content-Length", "51"}, + {"Content-Type", "application/xml"} + }; + + create_xmlhttprequest(doc); + if(!xhr) + return; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)&xmlhttprequest_onreadystatechange_obj; + hres = IHTMLXMLHttpRequest_put_onreadystatechange(xhr, var); + ok(hres == S_OK, "put_onreadystatechange failed: %08x\n", hres); + + V_VT(&var) = VT_EMPTY; + hres = IHTMLXMLHttpRequest_get_onreadystatechange(xhr, &var); + ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(onreadystatechange) = %d\n", V_VT(&var)); + ok(V_DISPATCH(&var) == (IDispatch*)&xmlhttprequest_onreadystatechange_obj, "unexpected onreadystatechange value\n"); + + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, NULL, &text); + ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres); + + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, NULL); + ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres); + + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, NULL, NULL); + ok(hres == E_POINTER || broken(hres == E_INVALIDARG), /* Vista and before */ + "Expect E_POINTER, got %08x\n", hres); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, NULL); + ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(val == 0, "Expect 0, got %d\n", val); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(text == NULL, "Expect NULL, got %p\n", text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 0, "Expect UNSENT, got %d\n", val); + + method = a2bstr("GET"); + url = a2bstr(xml_url); + V_VT(&vbool) = VT_BOOL; + V_BOOL(&vbool) = VARIANT_TRUE; + V_VT(&vempty) = VT_EMPTY; + + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty); + ok(hres == S_OK, "open failed: %08x\n", hres); + CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + + SysFreeString(method); + SysFreeString(url); + + if(FAILED(hres)) { + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; + return; + } + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + text = (BSTR)0xdeadbeef; + hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, &text); + ok(hres == E_FAIL, "got %08x\n", hres); + ok(text == NULL, "text = %p\n", text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(val == 0, "Expect 0, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(text == NULL, "Expect NULL, got %p\n", text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 1, "Expect OPENED, got %d\n", val); + + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + SET_EXPECT(xmlhttprequest_onreadystatechange_headers_received); + SET_EXPECT(xmlhttprequest_onreadystatechange_loading); + SET_EXPECT(xmlhttprequest_onreadystatechange_done); + loading_cnt = 0; + hres = IHTMLXMLHttpRequest_send(xhr, vempty); + + ok(hres == S_OK, "send failed: %08x\n", hres); + if(SUCCEEDED(hres)) + pump_msgs(&called_xmlhttprequest_onreadystatechange_done); + todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + CHECK_CALLED(xmlhttprequest_onreadystatechange_headers_received); + CHECK_CALLED(xmlhttprequest_onreadystatechange_loading); + CHECK_CALLED(xmlhttprequest_onreadystatechange_done); + /* Workaround for loading large files */ + if(expect_text) + ok(loading_cnt == 1, "loading_cnt = %d\n", loading_cnt); + else + todo_wine ok(loading_cnt == 1, "loading_cnt = %d\n", loading_cnt); + + if(FAILED(hres)) { + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; + return; + } + + text = NULL; + hres = IHTMLXMLHttpRequest_getAllResponseHeaders(xhr, &text); + ok(hres == S_OK, "getAllResponseHeader failed, got %08x\n", hres); + ok(text != NULL, "text == NULL\n"); + SysFreeString(text); + + if(expect_text) + test_header(expect_headers, sizeof(expect_headers)/sizeof(expect_headers[0])); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == S_OK, "get_status failed: %08x\n", hres); + ok(val == 200, "Expect 200, got %d\n", val); + + text = NULL; + hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text); + ok(hres == S_OK, "get_statusText failed: %08x\n", hres); + ok(text != NULL, "text == NULL\n"); + ok(!strcmp_wa(text, "OK"), "Expected "OK", got %s\n", wine_dbgstr_w(text)); + SysFreeString(text); + + val = 0xdeadbeef; + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 4, "Expect DONE, got %d\n", val); + + text = NULL; + hres = IHTMLXMLHttpRequest_get_responseText(xhr, &text); + ok(hres == S_OK, "get_responseText failed: %08x\n", hres); + ok(text != NULL, "test == NULL\n"); + if(expect_text) + ok(!strcmp_wa(text, expect_text), "expect %s, got %s\n", + expect_text, wine_dbgstr_w(text)); + SysFreeString(text); + + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; +} + +static void test_async_xhr_abort(IHTMLDocument2 *doc, const char *xml_url) +{ + VARIANT vbool, vempty, var; + BSTR method, url; + LONG val; + HRESULT hres; + + method = a2bstr("GET"); + url = a2bstr(xml_url); + V_VT(&vbool) = VT_BOOL; + V_BOOL(&vbool) = VARIANT_TRUE; + V_VT(&vempty) = VT_EMPTY; + + trace("abort before send() is fired\n"); + create_xmlhttprequest(doc); + if(!xhr) + return; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)&xmlhttprequest_onreadystatechange_obj; + hres = IHTMLXMLHttpRequest_put_onreadystatechange(xhr, var); + + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty); + ok(hres == S_OK, "open failed: %08x\n", hres); + CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + + hres = IHTMLXMLHttpRequest_abort(xhr); + ok(hres == S_OK, "abort failed: %08x\n", hres); + + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(val == 0, "Expect 0, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 0, "Expect UNSENT, got %d\n", val); + + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; + + trace("abort after send() is fired\n"); + create_xmlhttprequest(doc); + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)&xmlhttprequest_onreadystatechange_obj; + hres = IHTMLXMLHttpRequest_put_onreadystatechange(xhr, var); + + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty); + ok(hres == S_OK, "open failed: %08x\n", hres); + CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + + loading_cnt = 0; + readystatechange_cnt = 0; + SET_EXPECT(xmlhttprequest_onreadystatechange_opened); + SET_EXPECT(xmlhttprequest_onreadystatechange_done); + hres = IHTMLXMLHttpRequest_send(xhr, vempty); + ok(hres == S_OK, "send failed: %08x\n", hres); + todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + + hres = IHTMLXMLHttpRequest_abort(xhr); + ok(hres == S_OK, "abort failed: %08x\n", hres); + CHECK_CALLED(xmlhttprequest_onreadystatechange_done); + + hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + ok(val == 0, "Expect UNSENT, got %d\n", val); + + hres = IHTMLXMLHttpRequest_get_status(xhr, &val); + ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres); + ok(val == 0, "Expect 0, got %d\n", val); + + ok(loading_cnt == 0, "loading_cnt = %d, expect 0, loading_cnt\n", loading_cnt); + todo_wine ok(readystatechange_cnt == 2, "readystatechange_cnt = %d, expect 2\n", readystatechange_cnt); + + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; + + SysFreeString(method); + SysFreeString(url); +} + +static IHTMLDocument2 *create_doc_from_url(const char *start_url) +{ + BSTR url; + IBindCtx *bc; + IMoniker *url_mon; + IPersistMoniker *persist_mon; + IHTMLDocument2 *doc; + HRESULT hres; + + hres = CreateBindCtx(0, &bc); + ok(hres == S_OK, "CreateBindCtx failed: 0x%08x\n", hres); + + url = a2bstr(start_url); + hres = CreateURLMoniker(NULL, url, &url_mon); + ok(hres == S_OK, "CreateURLMoniker failed: 0x%08x\n", hres); + + hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, + CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, &IID_IHTMLDocument2, + (void**)&doc); + ok(hres == S_OK, "CoCreateInstance failed: 0x%08x\n", hres); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker, + (void**)&persist_mon); + ok(hres == S_OK, "IHTMLDocument2_QueryInterface failed: 0x%08x\n", hres); + + hres = IPersistMoniker_Load(persist_mon, FALSE, url_mon, bc, + STGM_SHARE_EXCLUSIVE | STGM_READWRITE); + ok(hres == S_OK, "IPersistMoniker_Load failed: 0x%08x\n", hres); + + IPersistMoniker_Release(persist_mon); + IMoniker_Release(url_mon); + IBindCtx_Release(bc); + SysFreeString(url); + + doc_complete = FALSE; + notif_doc = doc; + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); + pump_msgs(&doc_complete); + + return doc; +} + +START_TEST(xmlhttprequest) +{ + IHTMLDocument2 *doc; + static const char start_url[] = "http://test.winehq.org/tests/hello.html"; + static const char xml_url[] = "http://test.winehq.org/tests/xmltest.xml"; + static const char large_page_url[] = "http://test.winehq.org/tests/data.php"; + static const char expect_response_text[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n"; + + CoInitialize(NULL); + + content_type = a2bstr("Content-Type"); + doc = create_doc_from_url(start_url); + if(doc) { + test_sync_xhr(doc, xml_url, expect_response_text); + test_sync_xhr(doc, large_page_url, NULL); + test_async_xhr(doc, xml_url, expect_response_text); + test_async_xhr(doc, large_page_url, NULL); + test_async_xhr_abort(doc, large_page_url); + IHTMLDocument2_Release(doc); + } + SysFreeString(content_type); + + CoUninitialize(); +}
Propchange: trunk/rostests/winetests/mshtml/xmlhttprequest.c ------------------------------------------------------------------------------ svn:eol-style = native