mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:35:52 +00:00
jscript: Pass correct 'this' to host objects in ES5 mode.
For some reason, only pure js objects are passed in mshtml's jscript engine. Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
144479afa1
commit
2e4721ac8f
|
@ -2212,14 +2212,11 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD
|
|||
if(jsdisp)
|
||||
jsdisp_release(jsdisp);
|
||||
|
||||
if(is_undefined(vthis))
|
||||
jsthis = NULL;
|
||||
else if(is_object_instance(vthis))
|
||||
if(is_object_instance(vthis) && (ctx->version < SCRIPTLANGUAGEVERSION_ES5 ||
|
||||
((jsdisp = to_jsdisp(get_object(vthis))) && is_class(jsdisp, JSCLASS_OBJECT))))
|
||||
jsthis = get_object(vthis);
|
||||
else {
|
||||
FIXME("Unimplemented 'this' passed to host object: %s\n", debugstr_jsval(vthis));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
else
|
||||
jsthis = NULL;
|
||||
|
||||
flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
|
||||
if(r && argc && flags == DISPATCH_METHOD)
|
||||
|
|
|
@ -1668,6 +1668,20 @@ sync_test("builtin_context", function() {
|
|||
ok(obj.valueOf() === 42, "obj = " + obj);
|
||||
});
|
||||
|
||||
sync_test("host this", function() {
|
||||
var tests = [ undefined, null, external.nullDisp, function() {}, [0], "foobar", true, 42, new Number(42), external.testHostContext(true), window, document ];
|
||||
var i, obj = Object.create(Function.prototype);
|
||||
|
||||
// only pure js objects are passed as 'this' (regardless of prototype)
|
||||
[137].forEach(external.testHostContext(true), obj);
|
||||
Function.prototype.apply.call(external.testHostContext(true), obj, [137, 0, {}]);
|
||||
|
||||
for(i = 0; i < tests.length; i++) {
|
||||
[137].forEach(external.testHostContext(false), tests[i]);
|
||||
Function.prototype.apply.call(external.testHostContext(false), tests[i], [137, 0, {}]);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("head_setter", function() {
|
||||
document.head = "";
|
||||
ok(typeof(document.head) === "object", "typeof(document.head) = " + typeof(document.head));
|
||||
|
|
|
@ -158,7 +158,8 @@ DEFINE_EXPECT(GetTypeInfo);
|
|||
#define DISPID_EXTERNAL_IS_ENGLISH 0x300009
|
||||
#define DISPID_EXTERNAL_LIST_SEP 0x30000A
|
||||
#define DISPID_EXTERNAL_TEST_VARS 0x30000B
|
||||
#define DISPID_EXTERNAL_GETMIMETYPE 0x30000C
|
||||
#define DISPID_EXTERNAL_TESTHOSTCTX 0x30000C
|
||||
#define DISPID_EXTERNAL_GETMIMETYPE 0x30000D
|
||||
|
||||
static const GUID CLSID_TestScript =
|
||||
{0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
|
||||
|
@ -745,6 +746,87 @@ static IDispatchExVtbl scriptDispVtbl = {
|
|||
|
||||
static IDispatchEx scriptDisp = { &scriptDispVtbl };
|
||||
|
||||
static HRESULT WINAPI testHostContextDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
ok(id == DISPID_VALUE, "id = %ld\n", id);
|
||||
ok(wFlags == (DISPATCH_PROPERTYGET | DISPATCH_METHOD), "wFlags = %x\n", wFlags);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->cArgs == 4, "pdp->cArgs = %d\n", pdp->cArgs);
|
||||
ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %ld\n", pdp->rgdispidNamedArgs[0]);
|
||||
ok(V_VT(&pdp->rgvarg[0]) == VT_DISPATCH, "V_VT(rgvarg[0]) = %d\n", V_VT(&pdp->rgvarg[0]));
|
||||
ok(V_DISPATCH(&pdp->rgvarg[0]) != NULL, "V_DISPATCH(rgvarg[0]) = NULL\n");
|
||||
ok(V_VT(&pdp->rgvarg[1]) == VT_DISPATCH, "V_VT(rgvarg[1]) = %d\n", V_VT(&pdp->rgvarg[1]));
|
||||
ok(V_DISPATCH(&pdp->rgvarg[1]) != NULL, "V_DISPATCH(rgvarg[1]) = NULL\n");
|
||||
ok(V_VT(&pdp->rgvarg[2]) == VT_I4, "V_VT(rgvarg[2]) = %d\n", V_VT(&pdp->rgvarg[2]));
|
||||
ok(V_I4(&pdp->rgvarg[2]) == 0, "V_I4(rgvarg[2]) = %ld\n", V_I4(&pdp->rgvarg[2]));
|
||||
ok(V_VT(&pdp->rgvarg[3]) == VT_I4, "V_VT(rgvarg[3]) = %d\n", V_VT(&pdp->rgvarg[3]));
|
||||
ok(V_I4(&pdp->rgvarg[3]) == 137, "V_I4(rgvarg[3]) = %ld\n", V_I4(&pdp->rgvarg[3]));
|
||||
V_VT(pvarRes) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IDispatchExVtbl testHostContextDispVtbl = {
|
||||
DispatchEx_QueryInterface,
|
||||
DispatchEx_AddRef,
|
||||
DispatchEx_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke,
|
||||
DispatchEx_GetDispID,
|
||||
testHostContextDisp_InvokeEx,
|
||||
DispatchEx_DeleteMemberByName,
|
||||
DispatchEx_DeleteMemberByDispID,
|
||||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
};
|
||||
|
||||
static IDispatchEx testHostContextDisp = { &testHostContextDispVtbl };
|
||||
|
||||
static HRESULT WINAPI testHostContextDisp_no_this_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
ok(id == DISPID_VALUE, "id = %ld\n", id);
|
||||
ok(wFlags == (DISPATCH_PROPERTYGET | DISPATCH_METHOD), "wFlags = %x\n", wFlags);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->cArgs == 3, "pdp->cArgs = %d\n", pdp->cArgs);
|
||||
ok(V_VT(&pdp->rgvarg[0]) == VT_DISPATCH, "V_VT(rgvarg[1]) = %d\n", V_VT(&pdp->rgvarg[1]));
|
||||
ok(V_DISPATCH(&pdp->rgvarg[0]) != NULL, "V_DISPATCH(rgvarg[1]) = NULL\n");
|
||||
ok(V_VT(&pdp->rgvarg[1]) == VT_I4, "V_VT(rgvarg[2]) = %d\n", V_VT(&pdp->rgvarg[2]));
|
||||
ok(V_I4(&pdp->rgvarg[1]) == 0, "V_I4(rgvarg[2]) = %ld\n", V_I4(&pdp->rgvarg[2]));
|
||||
ok(V_VT(&pdp->rgvarg[2]) == VT_I4, "V_VT(rgvarg[3]) = %d\n", V_VT(&pdp->rgvarg[3]));
|
||||
ok(V_I4(&pdp->rgvarg[2]) == 137, "V_I4(rgvarg[3]) = %ld\n", V_I4(&pdp->rgvarg[3]));
|
||||
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
ok(pspCaller != NULL, "pspCaller == NULL\n");
|
||||
V_VT(pvarRes) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IDispatchExVtbl testHostContextDisp_no_this_vtbl = {
|
||||
DispatchEx_QueryInterface,
|
||||
DispatchEx_AddRef,
|
||||
DispatchEx_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke,
|
||||
DispatchEx_GetDispID,
|
||||
testHostContextDisp_no_this_InvokeEx,
|
||||
DispatchEx_DeleteMemberByName,
|
||||
DispatchEx_DeleteMemberByDispID,
|
||||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
};
|
||||
|
||||
static IDispatchEx testHostContextDisp_no_this = { &testHostContextDisp_no_this_vtbl };
|
||||
|
||||
static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
if(!lstrcmpW(bstrName, L"ok")) {
|
||||
|
@ -795,6 +877,10 @@ static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName,
|
|||
*pid = DISPID_EXTERNAL_TEST_VARS;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"testHostContext")) {
|
||||
*pid = DISPID_EXTERNAL_TESTHOSTCTX;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"getExpectedMimeType")) {
|
||||
*pid = DISPID_EXTERNAL_GETMIMETYPE;
|
||||
return S_OK;
|
||||
|
@ -1032,6 +1118,20 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID
|
|||
test_script_vars(pdp->cArgs, pdp->rgvarg);
|
||||
return S_OK;
|
||||
|
||||
case DISPID_EXTERNAL_TESTHOSTCTX:
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
|
||||
V_VT(pvarRes) = VT_DISPATCH;
|
||||
V_DISPATCH(pvarRes) = (IDispatch*)(V_BOOL(pdp->rgvarg) ? &testHostContextDisp : &testHostContextDisp_no_this);
|
||||
return S_OK;
|
||||
|
||||
case DISPID_EXTERNAL_GETMIMETYPE:
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||
|
|
Loading…
Reference in a new issue