From: Jacek Caban Subject: [PATCH 2/3] Added support for shadowing of element pseudo-variables Message-Id: <4F8D41A8.8080302@codeweavers.com> Date: Tue, 17 Apr 2012 12:10:48 +0200 --- dlls/mshtml/dispex.c | 13 ++++++++++++ dlls/mshtml/htmlwindow.c | 43 +++++++++++++++++++++++++++++----------- dlls/mshtml/mshtml_private.h | 4 ++- dlls/mshtml/tests/jstest.html | 8 +++++++ 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index c42e2ef..66dad69 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -480,6 +480,19 @@ HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VA return S_OK; } +HRESULT dispex_get_dynid(DispatchEx *This, const WCHAR *name, DISPID *id) +{ + dynamic_prop_t *prop; + HRESULT hres; + + hres = get_dynamic_prop(This, name, fdexNameEnsure, &prop); + if(FAILED(hres)) + return hres; + + *id = DISPID_DYNPROP_0 + (prop - This->dynamic_data->props); + return S_OK; +} + static HRESULT dispex_value(DispatchEx *This, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 9069e6d..3ee2273 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2461,21 +2461,40 @@ static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD IDispatch_Release(disp); break; } - case GLOBAL_ELEMENTVAR: { - IHTMLElement *elem; + case GLOBAL_ELEMENTVAR: + switch(flags) { + case DISPATCH_PROPERTYGET: { + IHTMLElement *elem; - hres = IHTMLDocument3_getElementById(&This->doc->basedoc.IHTMLDocument3_iface, - prop->name, &elem); - if(FAILED(hres)) - return hres; + hres = IHTMLDocument3_getElementById(&This->doc->basedoc.IHTMLDocument3_iface, + prop->name, &elem); + if(FAILED(hres)) + return hres; - if(!elem) - return DISP_E_MEMBERNOTFOUND; + if(!elem) + return DISP_E_MEMBERNOTFOUND; - V_VT(res) = VT_DISPATCH; - V_DISPATCH(res) = (IDispatch*)elem; - break; - } + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)elem; + return S_OK; + } + case DISPATCH_PROPERTYPUT: { + DISPID dispex_id; + + hres = dispex_get_dynid(&This->dispex, prop->name, &dispex_id); + if(FAILED(hres)) + return hres; + + prop->type = GLOBAL_DISPEXVAR; + prop->id = dispex_id; + return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, dispex_id, 0, flags, params, res, ei, caller); + } + default: + FIXME("Not suppoted flags: %x\n", flags); + return E_NOTIMPL; + } + case GLOBAL_DISPEXVAR: + return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, prop->id, 0, flags, params, res, ei, caller); default: ERR("invalid type %d\n", prop->type); hres = DISP_E_MEMBERNOTFOUND; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c8551fb..3376084 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -229,6 +229,7 @@ BOOL dispex_query_interface(DispatchEx*,REFIID,void**) DECLSPEC_HIDDEN; HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**) DECLSPEC_HIDDEN; HRESULT get_dispids(tid_t,DWORD*,DISPID**) DECLSPEC_HIDDEN; HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*) DECLSPEC_HIDDEN; +HRESULT dispex_get_dynid(DispatchEx*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN; void release_typelib(void) DECLSPEC_HIDDEN; HRESULT get_htmldoc_classinfo(ITypeInfo **typeinfo) DECLSPEC_HIDDEN; @@ -248,7 +249,8 @@ typedef struct ScriptHost ScriptHost; typedef enum { GLOBAL_SCRIPTVAR, - GLOBAL_ELEMENTVAR + GLOBAL_ELEMENTVAR, + GLOBAL_DISPEXVAR } global_prop_type_t; typedef struct { diff --git a/dlls/mshtml/tests/jstest.html b/dlls/mshtml/tests/jstest.html index abda45e..10863f4 100644 --- a/dlls/mshtml/tests/jstest.html +++ b/dlls/mshtml/tests/jstest.html @@ -60,6 +60,14 @@ function test_document_name_as_index() { var e = document.getElementById("formid"); ok(!!e, "e is null"); ok(!("formid" in document), "formid is in document"); + + document.body.innerHTML = '
'; + ok("formname" in window, "formname' is not in window"); + ok(typeof(window.formname) === "object", "typeof(window.formname) = " + typeof(window.formname)); + window.formname = 1; + ok(window.formname === 1, "window.formname = " + window.formname); + formname = 2; + ok(window.formname === 2, "window.formname = " + window.formname); } function test_remove_style_attribute() {