From: Gabriel Ivăncescu gabrielopcode@gmail.com
When GLOBAL_DISPEXVAR is used, we store the id of the dynamic prop and invoke it using the same id. But this is not the case if we have a jsdisp, which is redirected from InvokeEx and results in an invalid id.
The actual way this works on native (in IE9+) is that element/frame props are special and not part of the window object at all. They're actually looked up after the prototype is, in a special way, but that requires a revamp. Storing over it just creates an actual prop on the window (which is what we are doing here).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
This is necessary in next patch (and tested). --- dlls/jscript/dispex.c | 14 ++++++++++++++ dlls/jscript/jsdisp.idl | 1 + dlls/mshtml/htmlwindow.c | 3 +++ 3 files changed, 18 insertions(+)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 91fa2c00cf4..ab7d004bf04 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2386,6 +2386,19 @@ static HRESULT WINAPI WineJSDispatch_GetScriptGlobal(IWineJSDispatch *iface, IWi return S_OK; }
+static HRESULT WINAPI WineJSDispatch_OverrideExternalProp(IWineJSDispatch *iface, const WCHAR *name, VARIANT *value) +{ + jsdisp_t *This = impl_from_IWineJSDispatch(iface); + dispex_prop_t *prop; + + prop = lookup_dispex_prop(This, string_hash(name), name, FALSE); + assert(prop != NULL && prop->type == PROP_EXTERN); + + prop->type = PROP_JSVAL; + prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE; + return variant_to_jsval(This->ctx, value, &prop->u.val); +} + static IWineJSDispatchVtbl DispatchExVtbl = { DispatchEx_QueryInterface, DispatchEx_AddRef, @@ -2404,6 +2417,7 @@ static IWineJSDispatchVtbl DispatchExVtbl = { DispatchEx_GetNameSpaceParent, WineJSDispatch_Free, WineJSDispatch_GetScriptGlobal, + WineJSDispatch_OverrideExternalProp, };
jsdisp_t *as_jsdisp(IDispatch *disp) diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index 051f819e817..b49d0c9b30d 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -52,6 +52,7 @@ interface IWineJSDispatch : IDispatchEx { void Free(); HRESULT GetScriptGlobal(IWineJSDispatchHost **ret); + HRESULT OverrideExternalProp(const WCHAR *name, VARIANT *value); }
[ diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 731acd61cd7..2409b3a1288 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3926,6 +3926,9 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, case DISPATCH_PROPERTYPUT: { DISPID dispex_id;
+ if(This->event_target.dispex.jsdisp) + return IWineJSDispatch_OverrideExternalProp(This->event_target.dispex.jsdisp, prop->name, params->rgvarg); + hres = dispex_get_dynid(&This->event_target.dispex, prop->name, TRUE, &dispex_id); if(FAILED(hres)) return hres;