mshtml: Added support for accessing elements id by global properties.

This commit is contained in:
Jacek Caban 2009-11-01 19:21:57 +01:00 committed by Alexandre Julliard
parent 9195e1b756
commit 82c8e7c684
3 changed files with 113 additions and 21 deletions

View File

@ -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;
prop = This->global_props+idx;
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");
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,

View File

@ -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;

View File

@ -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>";