Module: wine Branch: master Commit: 82c8e7c68489581e6a42038b1fc46d58d978f59a URL: http://source.winehq.org/git/wine.git/?a=commit;h=82c8e7c68489581e6a42038b1f...
Author: Jacek Caban jacek@codeweavers.com Date: Sun Nov 1 19:21:57 2009 +0100
mshtml: Added support for accessing elements id by global properties.
---
dlls/mshtml/htmlwindow.c | 91 ++++++++++++++++++++++++++++++++---------- dlls/mshtml/mshtml_private.h | 6 +++ dlls/mshtml/tests/script.c | 39 +++++++++++++++++- 3 files changed, 114 insertions(+), 22 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index a14fe5c..6158b32 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -1005,8 +1005,7 @@ static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - IDispatchEx *dispex; - IDispatch *disp; + global_prop_t *prop; DWORD idx; HRESULT hres;
@@ -1014,24 +1013,51 @@ static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla if(idx >= This->global_prop_cnt) return DISP_E_MEMBERNOTFOUND;
- disp = get_script_disp(This->global_props[idx].script_host); - if(!disp) - return E_UNEXPECTED; - - hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); - if(SUCCEEDED(hres)) { - TRACE("%s >>>\n", debugstr_w(This->global_props[idx].name)); - hres = IDispatchEx_InvokeEx(dispex, This->global_props[idx].id, lcid, flags, params, res, ei, caller); - if(hres == S_OK) - TRACE("%s <<<\n", debugstr_w(This->global_props[idx].name)); - else - WARN("%s <<< %08x\n", debugstr_w(This->global_props[idx].name), hres); - IDispatchEx_Release(dispex); - }else { - FIXME("No IDispatchEx\n"); + prop = This->global_props+idx; + + switch(prop->type) { + case GLOBAL_SCRIPTVAR: { + IDispatchEx *dispex; + IDispatch *disp; + + disp = get_script_disp(prop->script_host); + if(!disp) + return E_UNEXPECTED; + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(SUCCEEDED(hres)) { + TRACE("%s >>>\n", debugstr_w(prop->name)); + hres = IDispatchEx_InvokeEx(dispex, prop->id, lcid, flags, params, res, ei, caller); + if(hres == S_OK) + TRACE("%s <<<\n", debugstr_w(prop->name)); + else + WARN("%s <<< %08x\n", debugstr_w(prop->name), hres); + IDispatchEx_Release(dispex); + }else { + FIXME("No IDispatchEx\n"); + } + IDispatch_Release(disp); + break; + } + case GLOBAL_ELEMENTVAR: { + IHTMLElement *elem; + + hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), prop->name, &elem); + if(FAILED(hres)) + return hres; + + if(!elem) + return DISP_E_MEMBERNOTFOUND; + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)elem; + break; + } + default: + ERR("invalid type %d\n", prop->type); + hres = DISP_E_MEMBERNOTFOUND; }
- IDispatch_Release(disp); return hres; }
@@ -1399,7 +1425,7 @@ static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMembe pVarResult, pExcepInfo, puArgErr); }
-static global_prop_t *alloc_global_prop(HTMLWindow *This, BSTR name) +static global_prop_t *alloc_global_prop(HTMLWindow *This, global_prop_type_t type, BSTR name) { if(This->global_prop_cnt == This->global_prop_size) { global_prop_t *new_props; @@ -1422,6 +1448,7 @@ static global_prop_t *alloc_global_prop(HTMLWindow *This, BSTR name) if(!This->global_props[This->global_prop_cnt].name) return NULL;
+ This->global_props[This->global_prop_cnt].type = type; return This->global_props + This->global_prop_cnt++; }
@@ -1436,6 +1463,7 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, ScriptHost *script_host; DISPID id; DWORD i; + HRESULT hres;
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
@@ -1450,7 +1478,7 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) { global_prop_t *prop;
- prop = alloc_global_prop(This, bstrName); + prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName); if(!prop) return E_OUTOFMEMORY;
@@ -1461,7 +1489,28 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, return S_OK; }
- return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid); + hres = IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid); + if(hres != DISP_E_UNKNOWNNAME) + return hres; + + if(This->doc) { + global_prop_t *prop; + IHTMLElement *elem; + + hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), bstrName, &elem); + if(SUCCEEDED(hres) && elem) { + IHTMLElement_Release(elem); + + prop = alloc_global_prop(This, GLOBAL_ELEMENTVAR, bstrName); + if(!prop) + return E_OUTOFMEMORY; + + *pid = prop_to_dispid(This, prop); + return S_OK; + } + } + + return DISP_E_UNKNOWNNAME; }
static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index a6a8396..89acf46 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -168,7 +168,13 @@ typedef enum {
typedef struct ScriptHost ScriptHost;
+typedef enum { + GLOBAL_SCRIPTVAR, + GLOBAL_ELEMENTVAR +} global_prop_type_t; + typedef struct { + global_prop_type_t type; WCHAR *name; ScriptHost *script_host; DISPID id; diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 16c7811..05f2e4e 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -112,6 +112,7 @@ DEFINE_EXPECT(AddNamedItem); DEFINE_EXPECT(ParseScriptText); DEFINE_EXPECT(GetScriptDispatch); DEFINE_EXPECT(funcDisp); +DEFINE_EXPECT(script_divid_d); DEFINE_EXPECT(script_testprop_d); DEFINE_EXPECT(script_testprop_i); DEFINE_EXPECT(AXQueryInterface_IActiveScript); @@ -369,7 +370,13 @@ static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW return S_OK; }
- ok(0, "unexpected call\n"); + if(!strcmp_wa(bstrName, "divid")) { + CHECK_EXPECT(script_divid_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + return E_FAIL; + } + + ok(0, "unexpected call\b"); return E_NOTIMPL; }
@@ -915,6 +922,33 @@ static void test_nextdispid(IDispatchEx *dispex) ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n"); }
+static void test_global_id(void) +{ + VARIANT var; + DISPPARAMS dp; + EXCEPINFO ei; + BSTR tmp; + DISPID id; + HRESULT hres; + + SET_EXPECT(GetScriptDispatch); + SET_EXPECT(script_divid_d); + tmp = a2bstr("divid"); + hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + SysFreeString(tmp); + CHECK_CALLED(GetScriptDispatch); + CHECK_CALLED(script_divid_d); + + VariantInit(&var); + memset(&ei, 0, sizeof(ei)); + memset(&dp, 0, sizeof(dp)); + hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(var) = %d\n", V_VT(&var)); + VariantClear(&var); +} + static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface, LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine, @@ -1104,6 +1138,8 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac CHECK_CALLED(GetScriptDispatch); CHECK_CALLED(script_testprop_i);
+ test_global_id(); + test_security();
return S_OK; @@ -1421,6 +1457,7 @@ static IClassFactory script_cf = { &ClassFactoryVtbl };
static const char simple_script_str[] = "<html><head></head><body>" + "<div id="divid"></div>" "<script language="TestScript">simple script</script>" "</body></html>";