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) VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{ {
HTMLWindow *This = HTMLWINDOW2_THIS(iface); HTMLWindow *This = HTMLWINDOW2_THIS(iface);
IDispatchEx *dispex; global_prop_t *prop;
IDispatch *disp;
DWORD idx; DWORD idx;
HRESULT hres; HRESULT hres;
@ -1014,24 +1013,51 @@ static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla
if(idx >= This->global_prop_cnt) if(idx >= This->global_prop_cnt)
return DISP_E_MEMBERNOTFOUND; return DISP_E_MEMBERNOTFOUND;
disp = get_script_disp(This->global_props[idx].script_host); prop = This->global_props+idx;
if(!disp)
return E_UNEXPECTED;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); switch(prop->type) {
if(SUCCEEDED(hres)) { case GLOBAL_SCRIPTVAR: {
TRACE("%s >>>\n", debugstr_w(This->global_props[idx].name)); IDispatchEx *dispex;
hres = IDispatchEx_InvokeEx(dispex, This->global_props[idx].id, lcid, flags, params, res, ei, caller); IDispatch *disp;
if(hres == S_OK)
TRACE("%s <<<\n", debugstr_w(This->global_props[idx].name)); disp = get_script_disp(prop->script_host);
else if(!disp)
WARN("%s <<< %08x\n", debugstr_w(This->global_props[idx].name), hres); return E_UNEXPECTED;
IDispatchEx_Release(dispex);
}else { hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
FIXME("No IDispatchEx\n"); 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; return hres;
} }
@ -1399,7 +1425,7 @@ static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMembe
pVarResult, pExcepInfo, puArgErr); 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) { if(This->global_prop_cnt == This->global_prop_size) {
global_prop_t *new_props; 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) if(!This->global_props[This->global_prop_cnt].name)
return NULL; return NULL;
This->global_props[This->global_prop_cnt].type = type;
return This->global_props + This->global_prop_cnt++; return This->global_props + This->global_prop_cnt++;
} }
@ -1436,6 +1463,7 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName,
ScriptHost *script_host; ScriptHost *script_host;
DISPID id; DISPID id;
DWORD i; DWORD i;
HRESULT hres;
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid); 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)) { if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) {
global_prop_t *prop; global_prop_t *prop;
prop = alloc_global_prop(This, bstrName); prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName);
if(!prop) if(!prop)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -1461,7 +1489,28 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName,
return S_OK; 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, 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 struct ScriptHost ScriptHost;
typedef enum {
GLOBAL_SCRIPTVAR,
GLOBAL_ELEMENTVAR
} global_prop_type_t;
typedef struct { typedef struct {
global_prop_type_t type;
WCHAR *name; WCHAR *name;
ScriptHost *script_host; ScriptHost *script_host;
DISPID id; DISPID id;

View File

@ -112,6 +112,7 @@ DEFINE_EXPECT(AddNamedItem);
DEFINE_EXPECT(ParseScriptText); DEFINE_EXPECT(ParseScriptText);
DEFINE_EXPECT(GetScriptDispatch); DEFINE_EXPECT(GetScriptDispatch);
DEFINE_EXPECT(funcDisp); DEFINE_EXPECT(funcDisp);
DEFINE_EXPECT(script_divid_d);
DEFINE_EXPECT(script_testprop_d); DEFINE_EXPECT(script_testprop_d);
DEFINE_EXPECT(script_testprop_i); DEFINE_EXPECT(script_testprop_i);
DEFINE_EXPECT(AXQueryInterface_IActiveScript); DEFINE_EXPECT(AXQueryInterface_IActiveScript);
@ -369,7 +370,13 @@ static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
return S_OK; 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; return E_NOTIMPL;
} }
@ -915,6 +922,33 @@ static void test_nextdispid(IDispatchEx *dispex)
ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n"); 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, static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine, LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
@ -1104,6 +1138,8 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
CHECK_CALLED(GetScriptDispatch); CHECK_CALLED(GetScriptDispatch);
CHECK_CALLED(script_testprop_i); CHECK_CALLED(script_testprop_i);
test_global_id();
test_security(); test_security();
return S_OK; return S_OK;
@ -1421,6 +1457,7 @@ static IClassFactory script_cf = { &ClassFactoryVtbl };
static const char simple_script_str[] = static const char simple_script_str[] =
"<html><head></head><body>" "<html><head></head><body>"
"<div id=\"divid\"></div>"
"<script language=\"TestScript\">simple script</script>" "<script language=\"TestScript\">simple script</script>"
"</body></html>"; "</body></html>";