-- v2: jscript: Return JS_E_OBJECT_NOT_COLLECTION when object has no DISPID_NEWENUM. mshtml: Return MSHTML_E_INVALID_PROPERTY when trying to construct a legacy mshtml/tests: Add more host object related tests for IE9+ modes. jscript: Use deferred fill-in if available to fill the exception info. jscript: Use proper dispatch flags to retrieve the enumerator. mshtml: Implement retrieving the builtin method props for the legacy mshtml: Move formatting of the builtin func disp string to a helper. mshtml: Use designated initializers for function_dispex.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 49ed4790d94..2f722c9eccc 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1134,13 +1134,9 @@ static const dispex_static_data_vtbl_t function_dispex_vtbl = { .invoke = function_invoke };
-static const tid_t function_iface_tids[] = {0}; - static dispex_static_data_t function_dispex = { - "Function", - &function_dispex_vtbl, - NULL_tid, - function_iface_tids + .name = "Function", + .vtbl = &function_dispex_vtbl, };
static func_disp_t *create_func_disp(DispatchEx *obj, func_info_t *info)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 67 ++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 31 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 2f722c9eccc..5cb51ccda2d 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -894,6 +894,39 @@ static HRESULT get_disp_prop(IDispatchEx *dispex, const WCHAR *name, LCID lcid, return hres; }
+static HRESULT format_func_disp_string(const WCHAR *name, IServiceProvider *caller, VARIANT *res) +{ + unsigned name_len; + WCHAR *ptr; + BSTR str; + + static const WCHAR func_prefixW[] = + {'\n','f','u','n','c','t','i','o','n',' '}; + static const WCHAR func_suffixW[] = + {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'}; + + /* FIXME: This probably should be more generic. Also we should try to get IID_IActiveScriptSite and SID_GetCaller. */ + if(!caller) + return E_ACCESSDENIED; + + name_len = wcslen(name); + ptr = str = SysAllocStringLen(NULL, name_len + ARRAY_SIZE(func_prefixW) + ARRAY_SIZE(func_suffixW)); + if(!str) + return E_OUTOFMEMORY; + + memcpy(ptr, func_prefixW, sizeof(func_prefixW)); + ptr += ARRAY_SIZE(func_prefixW); + + memcpy(ptr, name, name_len * sizeof(WCHAR)); + ptr += name_len; + + memcpy(ptr, func_suffixW, sizeof(func_suffixW)); + + V_VT(res) = VT_BSTR; + V_BSTR(res) = str; + return S_OK; +} + static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { IWineJSDispatchHost *this_iface; @@ -1037,37 +1070,9 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR return E_UNEXPECTED; hres = dispex_call_builtin(This->obj, This->info->id, params, res, ei, caller); break; - case DISPATCH_PROPERTYGET: { - unsigned name_len; - WCHAR *ptr; - BSTR str; - - static const WCHAR func_prefixW[] = - {'\n','f','u','n','c','t','i','o','n',' '}; - static const WCHAR func_suffixW[] = - {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'}; - - /* FIXME: This probably should be more generic. Also we should try to get IID_IActiveScriptSite and SID_GetCaller. */ - if(!caller) - return E_ACCESSDENIED; - - name_len = SysStringLen(This->info->name); - ptr = str = SysAllocStringLen(NULL, name_len + ARRAY_SIZE(func_prefixW) + ARRAY_SIZE(func_suffixW)); - if(!str) - return E_OUTOFMEMORY; - - memcpy(ptr, func_prefixW, sizeof(func_prefixW)); - ptr += ARRAY_SIZE(func_prefixW); - - memcpy(ptr, This->info->name, name_len*sizeof(WCHAR)); - ptr += name_len; - - memcpy(ptr, func_suffixW, sizeof(func_suffixW)); - - V_VT(res) = VT_BSTR; - V_BSTR(res) = str; - return S_OK; - } + case DISPATCH_PROPERTYGET: + hres = format_func_disp_string(This->info->name, caller, res); + break; default: FIXME("Unimplemented flags %x\n", flags); hres = E_NOTIMPL;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
They are actual stubs even on native (but avoid throwing when retrieving them, even if unused).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 62 +++++++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 34 +++++++++++++++++ 2 files changed, 96 insertions(+)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 5cb51ccda2d..f1cbc0a186e 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -98,6 +98,11 @@ typedef struct { func_info_t *info; } func_disp_t;
+typedef struct { + DispatchEx dispex; + const WCHAR *name; +} stub_func_disp_t; + typedef struct { func_disp_t *func_obj; VARIANT val; @@ -927,6 +932,51 @@ static HRESULT format_func_disp_string(const WCHAR *name, IServiceProvider *call return S_OK; }
+static inline stub_func_disp_t *stub_func_disp_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, stub_func_disp_t, dispex); +} + +static void stub_function_destructor(DispatchEx *dispex) +{ + stub_func_disp_t *This = stub_func_disp_from_DispatchEx(dispex); + free(This); +} + +static HRESULT stub_function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + stub_func_disp_t *This = stub_func_disp_from_DispatchEx(dispex); + HRESULT hres; + + switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; + /* fall through */ + case DISPATCH_METHOD: + return MSHTML_E_INVALID_PROPERTY; + case DISPATCH_PROPERTYGET: + hres = format_func_disp_string(This->name, caller, res); + break; + default: + FIXME("Unimplemented flags %x\n", flags); + hres = E_NOTIMPL; + } + + return hres; +} + +static const dispex_static_data_vtbl_t stub_function_dispex_vtbl = { + .destructor = stub_function_destructor, + .value = stub_function_value +}; + +static dispex_static_data_t stub_function_dispex = { + .name = "Function", + .vtbl = &stub_function_dispex_vtbl, +}; + static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { IWineJSDispatchHost *this_iface; @@ -1124,6 +1174,18 @@ static HRESULT function_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD fl /* fall through */ case DISPATCH_METHOD: return function_props[idx].invoke(This, params, lcid, res, ei, caller); + case DISPATCH_PROPERTYGET: { + stub_func_disp_t *disp = calloc(1, sizeof(stub_func_disp_t)); + + if(!disp) + return E_OUTOFMEMORY; + disp->name = function_props[idx].name; + init_dispatch_with_owner(&disp->dispex, &stub_function_dispex, This->obj); + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)&disp->dispex.IWineJSDispatchHost_iface; + break; + } default: return MSHTML_E_INVALID_PROPERTY; } diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f967b36e562..20188f459dd 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -364,6 +364,8 @@ sync_test("builtin_obj", function() { if(v < 9) { ok(!(window instanceof Object), "window instance of Object"); ok(!(document instanceof Object), "document instance of Object"); + ok(!(f.apply instanceof Function), "f.apply instance of Function"); + ok(!(f.call instanceof Function), "f.call instance of Function"); ok(!("arguments" in f), "arguments in f"); ok(!("length" in f), "length in f"); e = 0; @@ -419,6 +421,38 @@ sync_test("builtin_obj", function() { elem1.click.apply(elem2, { length: -1 }); ok(false, "exception expected"); }catch(ex) {} + + if(v < 9) { + ok(!("call" in f.call), "call in f.call"); + ok(!("apply" in f.call), "apply in f.call"); + ok(!("call" in f.apply), "call in f.apply"); + ok(!("apply" in f.apply), "apply in f.apply"); + ok(f.call+"" === "\nfunction call() {\n [native code]\n}\n", "f.call = " + f.call); + ok(f.apply+"" === "\nfunction apply() {\n [native code]\n}\n", "f.apply = " + f.apply); + ok(external.getVT(f.call) === "VT_DISPATCH", "f.call not VT_DISPATCH"); + ok(external.getVT(f.apply) === "VT_DISPATCH", "f.apply not VT_DISPATCH"); + + ok(f.apply !== f.apply, "f.apply == f.apply"); + f = f.apply; + ok(!("arguments" in f), "arguments in f.apply"); + ok(!("length" in f), "length in f.apply"); + ok(!("call" in f), "call in f.apply"); + ok(!("apply" in f), "apply in f.apply"); + e = 0; + try { + f.toString(); + }catch(ex) { + e = ex.number; + } + ok(e === 0xa01b6 - 0x80000000, "[f.apply.toString] e = " + e); + e = 0; + try { + f(document, ["style"]); + }catch(ex) { + e = ex.number; + } + ok(e === 0xa01b6 - 0x80000000, "[f.apply() indirect] e = " + e); + } });
sync_test("elem_props", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/enumerator.c | 2 +- dlls/jscript/tests/run.c | 1 + dlls/mshtml/tests/documentmode.js | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c index 203bfa8b8e0..dd008cc2bbf 100644 --- a/dlls/jscript/enumerator.c +++ b/dlls/jscript/enumerator.c @@ -240,7 +240,7 @@ static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **re /* Try to get a IEnumVARIANT by _NewEnum */ VariantInit(&varresult); hres = IDispatch_Invoke(obj, DISPID_NEWENUM, &IID_NULL, LOCALE_NEUTRAL, - DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL); + DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL); if (FAILED(hres)) { WARN("Enumerator: no DISPID_NEWENUM.\n"); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index db1e95dc844..627a7a11213 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -482,6 +482,7 @@ static HRESULT WINAPI testObj_Invoke(IDispatchEx *iface, DISPID id, { switch(id) { case DISPID_NEWENUM: + ok(wFlags == (DISPATCH_METHOD | DISPATCH_PROPERTYGET), "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 20188f459dd..13dd172fec1 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -452,6 +452,13 @@ sync_test("builtin_obj", function() { e = ex.number; } ok(e === 0xa01b6 - 0x80000000, "[f.apply() indirect] e = " + e); + + var enumerator = new Enumerator(document.getElementsByTagName("br")); + enumerator.moveNext(); + var enum_elem = enumerator.item(); + ok(enum_elem === elem2, "enum_elem = " + enum_elem); + enumerator.moveNext(); + ok(enumerator.atEnd(), "enumerator not at end"); } });
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/error.c | 2 ++ dlls/jscript/tests/run.c | 56 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index a3388ee9a27..482932e2c1b 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -407,6 +407,8 @@ void handle_dispatch_exception(script_ctx_t *ctx, EXCEPINFO *ei) TRACE("%08lx %s %s\n", ei->scode, debugstr_w(ei->bstrSource), debugstr_w(ei->bstrDescription));
reset_ei(ctx->ei); + if(ei->pfnDeferredFillIn) + ei->pfnDeferredFillIn(ei); ctx->ei->error = (SUCCEEDED(ei->scode) || ei->scode == DISP_E_EXCEPTION) ? E_FAIL : ei->scode; if(ei->bstrSource) ctx->ei->source = jsstr_alloc_len(ei->bstrSource, SysStringLen(ei->bstrSource)); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 627a7a11213..264d632aabe 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -964,6 +964,26 @@ static IDispatchExVtbl bindEventHandlerDispVtbl = {
static IDispatchEx bindEventHandlerDisp = { &bindEventHandlerDispVtbl };
+static HRESULT CALLBACK test_deferred_fill_in(struct tagEXCEPINFO *ei) +{ + ok(ei->pfnDeferredFillIn == test_deferred_fill_in, "pfnDeferredFillIn != test_deferred_fill_in\n"); + ok(!wcscmp(ei->bstrSource, L"source before defer"), "bstrSource = %s\n", wine_dbgstr_w(ei->bstrSource)); + ok(!wcscmp(ei->bstrDescription, L"desc before defer"), "bstrDescription = %s\n", wine_dbgstr_w(ei->bstrDescription)); + ok(!wcscmp(ei->bstrHelpFile, L"help before defer"), "bstrHelpFile = %s\n", wine_dbgstr_w(ei->bstrHelpFile)); + ok(ei->dwHelpContext == 1337, "dwHelpContext = %lu\n", ei->dwHelpContext); + + SysFreeString(ei->bstrSource); + SysFreeString(ei->bstrDescription); + SysFreeString(ei->bstrHelpFile); + ei->pfnDeferredFillIn = NULL; + ei->bstrSource = SysAllocString(L"source after defer"); + ei->bstrDescription = SysAllocString(L"desc after defer"); + ei->bstrHelpFile = SysAllocString(L"help after defer"); + ei->dwHelpContext = 1234567890; + + return E_FAIL; /* return code ignored */ +} + static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { if(!lstrcmpW(bstrName, L"ok")) { @@ -1940,6 +1960,12 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, if(pdp->cArgs == 1) { pei->bstrSource = SysAllocString(L"test source"); pei->bstrDescription = SysAllocString(L"test description"); + }else if(V_VT(pdp->rgvarg) == VT_BOOL && V_BOOL(pdp->rgvarg)) { + pei->pfnDeferredFillIn = test_deferred_fill_in; + pei->bstrSource = SysAllocString(L"source before defer"); + pei->bstrDescription = SysAllocString(L"desc before defer"); + pei->bstrHelpFile = SysAllocString(L"help before defer"); + pei->dwHelpContext = 1337; } return DISP_E_EXCEPTION; } @@ -2283,6 +2309,7 @@ static HRESULT parse_htmlscript(const WCHAR *script_str) #define ERROR_TODO_PARSE 0x0001 #define ERROR_TODO_SCODE 0x0002 #define ERROR_TODO_DESCRIPTION 0x0004 +#define ERROR_TODO_HELPFILE 0x0008
static void test_error_reports(void) { @@ -2298,6 +2325,8 @@ static void test_error_reports(void) unsigned character; const WCHAR *error_source; const WCHAR *description; + const WCHAR *help_file; + DWORD help_context; const WCHAR *line_text; BOOL todo_flags; BOOL reserved_lcid; @@ -2307,6 +2336,7 @@ static void test_error_reports(void) JS_E_SYNTAX, 0, 0, L"Microsoft JScript compilation error", L"Syntax error", + NULL, 0, L"?" }, { @@ -2314,6 +2344,7 @@ static void test_error_reports(void) JS_E_MISSING_RBRACKET, 2, 0, L"Microsoft JScript compilation error", L"Expected ')'", + NULL, 0, L"-->0) a=5;", ERROR_TODO_PARSE }, @@ -2406,6 +2437,7 @@ static void test_error_reports(void) E_FAIL, 0, 1, NULL, NULL, + NULL, 0, NULL, FALSE, 0x409 @@ -2416,6 +2448,15 @@ static void test_error_reports(void) L"test source", L"test description" }, + { + L" throwEI(-2147467259 /* E_FAIL */, true);", + E_FAIL, 0, 1, + L"source after defer", + L"desc after defer", + L"help after defer", 1234567890, + NULL, + ERROR_TODO_HELPFILE + }, { L"switch(2) {\n" L" case 1: break;\n" @@ -2461,6 +2502,7 @@ static void test_error_reports(void) JS_E_SUBSCRIPT_OUT_OF_RANGE, 3, 0, L"Microsoft JScript runtime error", L"test", + NULL, 0, NULL, FALSE, TRUE @@ -2473,6 +2515,7 @@ static void test_error_reports(void) JS_E_SUBSCRIPT_OUT_OF_RANGE, 3, 0, L"Microsoft JScript runtime error", L"", + NULL, 0, NULL, FALSE, TRUE @@ -2483,6 +2526,7 @@ static void test_error_reports(void) E_FAIL, 1, 0, NULL, L"", + NULL, 0, NULL, FALSE, TRUE @@ -2495,6 +2539,7 @@ static void test_error_reports(void) JS_E_EXCEPTION_THROWN, 3, 0, L"Microsoft JScript runtime error", L"Exception thrown and not caught", + NULL, 0, NULL, ERROR_TODO_SCODE | ERROR_TODO_DESCRIPTION }, @@ -2503,6 +2548,7 @@ static void test_error_reports(void) JS_E_SYNTAX, 3, 1, L"Microsoft JScript compilation error", L"Syntax error", + NULL, 0, L" ,,3" }, }; @@ -2623,9 +2669,15 @@ static void test_error_reports(void) "[%u] bstrDescription = %s expected %s\n", i, wine_dbgstr_w(ei.bstrDescription), wine_dbgstr_w(tests[i].description)); else ok(!ei.bstrDescription, "[%u] bstrDescription = %s expected NULL\n", i, wine_dbgstr_w(ei.bstrDescription)); + if(tests[i].help_file) + todo_wine_if(tests[i].todo_flags & ERROR_TODO_HELPFILE) + ok(ei.bstrHelpFile && !lstrcmpW(ei.bstrHelpFile, tests[i].help_file), + "[%u] bstrHelpFile = %s expected %s\n", i, wine_dbgstr_w(ei.bstrHelpFile), wine_dbgstr_w(tests[i].help_file)); + else + ok(!ei.bstrHelpFile, "[%u] bstrHelpFile = %s expected NULL\n", i, wine_dbgstr_w(ei.bstrHelpFile)); } - ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile)); - ok(!ei.dwHelpContext, "dwHelpContext = %ld\n", ei.dwHelpContext); + todo_wine_if(tests[i].todo_flags & ERROR_TODO_HELPFILE) + ok(ei.dwHelpContext == tests[i].help_context, "dwHelpContext = %lu, expected %lu\n", ei.dwHelpContext, tests[i].help_context); ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved); ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/documentmode.js | 36 +++++++++++++++++++++++++++++-- dlls/mshtml/tests/dom.js | 2 ++ dlls/mshtml/tests/events.c | 23 +++++++++++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 13dd172fec1..ce887068a95 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -379,6 +379,12 @@ sync_test("builtin_obj", function() { window.toString.call(null); ok(false, "expected exception calling window.toString with null context"); }catch(ex) {} + }else { + ok(Object.getPrototypeOf(f) === Function.prototype, "unexpected document.createElement prototype"); + e = window.toString.call(null); + ok(e === "[object Window]", "window.toString with null context = " + e); + e = window.toString.call(external.nullDisp); + ok(e === "[object Window]", "window.toString with nullDisp context = " + e); }
e = 0; @@ -422,6 +428,15 @@ sync_test("builtin_obj", function() { ok(false, "exception expected"); }catch(ex) {}
+ e = 0; + try { + new f(); + }catch(ex) { + e = ex.number; + } + todo_wine_if(v < 9). + ok(e === (v < 9 ? 0xa01b6 : 0x0ffff) - 0x80000000, "[new f()] e = " + e); + if(v < 9) { ok(!("call" in f.call), "call in f.call"); ok(!("apply" in f.call), "apply in f.call"); @@ -459,6 +474,24 @@ sync_test("builtin_obj", function() { ok(enum_elem === elem2, "enum_elem = " + enum_elem); enumerator.moveNext(); ok(enumerator.atEnd(), "enumerator not at end"); + }else { + elem = f.call.call(f, document, "div"); + f = f.bind(document); + elem = f.apply(null, ["style"]); + document.body.appendChild(elem); + + try { + var enumerator = new Enumerator(document.getElementsByTagName("style")); + }catch(ex) { + e = ex.number; + } + todo_wine. + ok(e === 0xa01c3 - 0x80000000, "[style Enumerator] e = " + e); + + f.apply = 0; + f.call = function() { }; + ok(f.apply === 0, "changed f.apply = ", f.apply); + ok(f.call instanceof Function, "changed f.call not instance of Function"); } });
@@ -2175,11 +2208,10 @@ sync_test("elem_attr", function() { var func = elem.setAttribute; try { func("testattr", arr); - todo_wine_if(v >= 9). ok(v < 9, "expected exception setting testattr via func"); }catch(ex) { ok(v >= 9, "did not expect exception setting testattr via func"); - elem.setAttribute("testattr", arr); + func.call(elem, "testattr", arr); } r = elem.getAttribute("testattr"); ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute (as func) = " + r); diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index b26280e00d6..628ed3d9703 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -572,6 +572,7 @@ sync_test("storage", function() {
sessionStorage.setItem("foobar", 42); ok("foobar" in sessionStorage, "foobar not in sessionStorage"); + ok(Object.prototype.hasOwnProperty.call(sessionStorage, "foobar"), "foobar not prop of sessionStorage"); item = sessionStorage.getItem("foobar"); ok(item === "42", "'foobar' item = " + item); item = sessionStorage["foobar"]; @@ -582,6 +583,7 @@ sync_test("storage", function() {
sessionStorage["barfoo"] = true; ok("barfoo" in sessionStorage, "barfoo not in sessionStorage"); + ok(Object.prototype.hasOwnProperty.call(sessionStorage, "barfoo"), "barfoo not prop of sessionStorage"); item = sessionStorage["barfoo"]; ok(item === "true", "[barfoo] item = " + item); item = sessionStorage.getItem("barfoo"); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 69488001fb2..6950c1e2a08 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -1602,8 +1602,10 @@ EVENT_HANDLER_FUNC_OBJ(onmessage); static HRESULT WINAPI onvisibilitychange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { + DISPPARAMS dp = {0}; IDispatchEx *dispex; HRESULT hres; + VARIANT res; BSTR bstr;
CHECK_EXPECT(visibilitychange); @@ -1614,10 +1616,15 @@ static HRESULT WINAPI onvisibilitychange(IDispatchEx *iface, DISPID id, LCID lci
bstr = SysAllocString(L"toString"); hres = IDispatchEx_GetDispID(dispex, bstr, 0, &id); - todo_wine ok(hres == S_OK, "GetDispID("toString") failed: %08lx\n", hres); SysFreeString(bstr);
+ hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &res, NULL, NULL); + ok(hres == S_OK, "InvokeEx("toString") failed: %08lx\n", hres); + ok(V_VT(&res) == VT_BSTR, "V_VT("toString") = %d\n", V_VT(&res)); + ok(!wcscmp(V_BSTR(&res), L"[object Event]"), "toString = %s\n", wine_dbgstr_w(V_BSTR(&res))); + VariantClear(&res); + return S_OK; }
@@ -4652,8 +4659,10 @@ static void test_storage_event(DISPPARAMS *params, BOOL doc_onstorage) IHTMLEventObj *event_obj; IDOMStorageEvent *event; IDispatchEx *dispex; + DISPPARAMS dp = {0}; IDispatch *disp; HRESULT hres; + VARIANT res; unsigned i; DISPID id; BSTR bstr; @@ -4669,6 +4678,18 @@ static void test_storage_event(DISPPARAMS *params, BOOL doc_onstorage) hres = IDispatch_QueryInterface(V_DISPATCH(¶ms->rgvarg[1]), &IID_IDispatchEx, (void**)&dispex); ok_(__FILE__,line)(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres);
+ bstr = SysAllocString(L"toString"); + hres = IDispatchEx_GetDispID(dispex, bstr, 0, &id); + ok_(__FILE__,line)(hres == S_OK, "GetDispID("toString") failed: %08lx\n", hres); + SysFreeString(bstr); + + hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &res, NULL, NULL); + ok_(__FILE__,line)(hres == S_OK, "InvokeEx("toString") failed: %08lx\n", hres); + ok_(__FILE__,line)(V_VT(&res) == VT_BSTR, "V_VT("toString") = %d\n", V_VT(&res)); + ok_(__FILE__,line)(!wcscmp(V_BSTR(&res), doc_onstorage ? L"[object MSEventObj]" : L"[object StorageEvent]"), + "toString = %s\n", wine_dbgstr_w(V_BSTR(&res))); + VariantClear(&res); + hres = IDispatchEx_QueryInterface(dispex, &IID_IDOMStorageEvent, (void**)&event); if(doc_onstorage) { static const WCHAR *props[] = { L"key", L"oldValue", L"newValue", L"storageArea" };
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 4 ++++ dlls/mshtml/tests/documentmode.js | 1 - 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index f1cbc0a186e..20f924230fe 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -950,6 +950,8 @@ static HRESULT stub_function_value(DispatchEx *dispex, LCID lcid, WORD flags, DI HRESULT hres;
switch(flags) { + case DISPATCH_CONSTRUCT: + return MSHTML_E_INVALID_PROPERTY; case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!res) return E_INVALIDARG; @@ -1111,6 +1113,8 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR HRESULT hres;
switch(flags) { + case DISPATCH_CONSTRUCT: + return MSHTML_E_INVALID_PROPERTY; case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!res) return E_INVALIDARG; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index ce887068a95..84b310c8373 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -434,7 +434,6 @@ sync_test("builtin_obj", function() { }catch(ex) { e = ex.number; } - todo_wine_if(v < 9). ok(e === (v < 9 ? 0xa01b6 : 0x0ffff) - 0x80000000, "[new f()] e = " + e);
if(v < 9) {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/enumerator.c | 4 ++-- dlls/jscript/error.c | 1 + dlls/jscript/jscript.h | 1 + dlls/jscript/jscript.rc | 1 + dlls/jscript/resource.h | 1 + dlls/mshtml/tests/documentmode.js | 1 - 6 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c index dd008cc2bbf..1f57f6b5173 100644 --- a/dlls/jscript/enumerator.c +++ b/dlls/jscript/enumerator.c @@ -244,7 +244,7 @@ static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **re if (FAILED(hres)) { WARN("Enumerator: no DISPID_NEWENUM.\n"); - return E_INVALIDARG; + return JS_E_OBJECT_NOT_COLLECTION; }
if ((V_VT(&varresult) == VT_DISPATCH) || (V_VT(&varresult) == VT_UNKNOWN)) @@ -255,7 +255,7 @@ static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **re else { FIXME("Enumerator: NewEnum unexpected type of varresult (%d).\n", V_VT(&varresult)); - hres = E_INVALIDARG; + hres = JS_E_OBJECT_NOT_COLLECTION; } VariantClear(&varresult); if (FAILED(hres)) diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index 482932e2c1b..3ff40a1e1e7 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -477,6 +477,7 @@ jsdisp_t *create_builtin_error(script_ctx_t *ctx) case JS_E_INVALID_PROPERTY: case JS_E_INVALID_ACTION: case JS_E_MISSING_ARG: + case JS_E_OBJECT_NOT_COLLECTION: case JS_E_FUNCTION_EXPECTED: case JS_E_DATE_EXPECTED: case JS_E_NUMBER_EXPECTED: diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index b413b4d1ae9..3d3d0f8a6c9 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -530,6 +530,7 @@ static inline HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_ #define JS_E_INVALID_PROPERTY MAKE_JSERROR(IDS_NO_PROPERTY) #define JS_E_INVALID_ACTION MAKE_JSERROR(IDS_UNSUPPORTED_ACTION) #define JS_E_MISSING_ARG MAKE_JSERROR(IDS_ARG_NOT_OPT) +#define JS_E_OBJECT_NOT_COLLECTION MAKE_JSERROR(IDS_OBJECT_NOT_COLLECTION) #define JS_E_SYNTAX MAKE_JSERROR(IDS_SYNTAX_ERROR) #define JS_E_MISSING_SEMICOLON MAKE_JSERROR(IDS_SEMICOLON) #define JS_E_MISSING_LBRACKET MAKE_JSERROR(IDS_LBRACKET) diff --git a/dlls/jscript/jscript.rc b/dlls/jscript/jscript.rc index cbdfde507b7..438aaad4c35 100644 --- a/dlls/jscript/jscript.rc +++ b/dlls/jscript/jscript.rc @@ -33,6 +33,7 @@ STRINGTABLE IDS_NO_PROPERTY "Object doesn't support this property or method" IDS_UNSUPPORTED_ACTION "Object doesn't support this action" IDS_ARG_NOT_OPT "Argument not optional" + IDS_OBJECT_NOT_COLLECTION "Object not a collection" IDS_SYNTAX_ERROR "Syntax error" IDS_SEMICOLON "Expected ';'" IDS_LBRACKET "Expected '('" diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h index 801e940b95e..640cc01cff9 100644 --- a/dlls/jscript/resource.h +++ b/dlls/jscript/resource.h @@ -31,6 +31,7 @@ #define IDS_NO_PROPERTY 0x01B6 #define IDS_UNSUPPORTED_ACTION 0x01BD #define IDS_ARG_NOT_OPT 0x01c1 +#define IDS_OBJECT_NOT_COLLECTION 0x01c3 #define IDS_SYNTAX_ERROR 0x03EA #define IDS_SEMICOLON 0x03EC #define IDS_LBRACKET 0x03ED diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 84b310c8373..071f76c11f0 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -484,7 +484,6 @@ sync_test("builtin_obj", function() { }catch(ex) { e = ex.number; } - todo_wine. ok(e === 0xa01c3 - 0x80000000, "[style Enumerator] e = " + e);
f.apply = 0;