mshtml: Added support for accessing elements id by global properties.
This commit is contained in:
parent
9195e1b756
commit
82c8e7c684
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue