mshtml: Added support for quering global variables from window object.

This commit is contained in:
Jacek Caban 2009-09-09 21:31:32 +02:00 committed by Alexandre Julliard
parent 705fb0f239
commit a50c4edb93
3 changed files with 149 additions and 3 deletions

View File

@ -93,8 +93,13 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
DWORD i;
if(This->event_target)
release_event_target(This->event_target);
for(i=0; i < This->global_prop_cnt; i++)
heap_free(This->global_props[i].name);
heap_free(This->global_props);
release_script_hosts(This);
list_remove(&This->entry);
release_dispex(&This->dispex);
@ -840,6 +845,40 @@ static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **
return IDocHostUIHandler_GetExternal(This->doc->hostui, p);
}
static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
HTMLWindow *This = HTMLWINDOW2_THIS(iface);
IDispatchEx *dispex;
IDispatch *disp;
DWORD idx;
HRESULT hres;
idx = id - MSHTML_DISPID_CUSTOM_MIN;
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");
}
IDispatch_Release(disp);
return hres;
}
#undef HTMLWINDOW2_THIS
static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
@ -1207,9 +1246,49 @@ static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMembe
static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
HTMLWindow *This = DISPEX_THIS(iface);
ScriptHost *script_host;
DISPID id;
DWORD i;
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
for(i=0; i < This->global_prop_cnt; i++) {
/* FIXME: case sensitivity */
if(!strcmpW(This->global_props[i].name, bstrName)) {
*pid = MSHTML_DISPID_CUSTOM_MIN+i;
return S_OK;
}
}
if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) {
if(This->global_prop_cnt == This->global_prop_size) {
global_prop_t *new_props;
DWORD new_size;
if(This->global_props) {
new_size = This->global_prop_size*2;
new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
}else {
new_size = 16;
new_props = heap_alloc(new_size*sizeof(global_prop_t));
}
if(!new_props)
return E_OUTOFMEMORY;
This->global_props = new_props;
This->global_prop_size = new_size;
}
This->global_props[This->global_prop_cnt].name = heap_strdupW(bstrName);
if(!This->global_props[This->global_prop_cnt].name)
return E_OUTOFMEMORY;
This->global_props[This->global_prop_cnt].script_host = script_host;
This->global_props[This->global_prop_cnt].id = id;
*pid = MSHTML_DISPID_CUSTOM_MIN + (This->global_prop_cnt++);
return S_OK;
}
return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
}
@ -1303,8 +1382,15 @@ static const tid_t HTMLWindow_iface_tids[] = {
IHTMLWindow3_tid,
0
};
static dispex_static_data_t HTMLWindow_dispex = {
static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
NULL,
NULL,
HTMLWindow_invoke
};
static dispex_static_data_t HTMLWindow_dispex = {
&HTMLWindow_dispex_vtbl,
DispHTMLWindow2_tid,
NULL,
HTMLWindow_iface_tids

View File

@ -158,6 +158,14 @@ typedef enum {
SCRIPTMODE_ACTIVESCRIPT
} SCRIPTMODE;
typedef struct ScriptHost ScriptHost;
typedef struct {
WCHAR *name;
ScriptHost *script_host;
DISPID id;
} global_prop_t;
typedef struct {
DispatchEx dispex;
const IHTMLWindow2Vtbl *lpHTMLWindow2Vtbl;
@ -175,6 +183,10 @@ typedef struct {
SCRIPTMODE scriptmode;
struct list script_hosts;
global_prop_t *global_props;
DWORD global_prop_cnt;
DWORD global_prop_size;
struct list entry;
} HTMLWindow;
@ -628,6 +640,8 @@ void connect_scripts(HTMLWindow*);
void doc_insert_script(HTMLDocument*,nsIDOMHTMLScriptElement*);
IDispatch *script_parse_event(HTMLDocument*,LPCWSTR);
void set_script_mode(HTMLWindow*,SCRIPTMODE);
BOOL find_global_prop(HTMLWindow*,BSTR,DWORD,ScriptHost**,DISPID*);
IDispatch *get_script_disp(ScriptHost*);
IHTMLElementCollection *create_all_collection(HTMLDOMNode*,BOOL);
IHTMLElementCollection *create_collection_from_nodelist(HTMLDocument*,IUnknown*,nsIDOMNodeList*);

View File

@ -42,7 +42,7 @@ static const WCHAR emptyW[] = {0};
static const CLSID CLSID_JScript =
{0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
typedef struct {
struct ScriptHost {
const IActiveScriptSiteVtbl *lpIActiveScriptSiteVtbl;
const IActiveScriptSiteInterruptPollVtbl *lpIActiveScriptSiteInterruptPollVtbl;
const IActiveScriptSiteWindowVtbl *lpIActiveScriptSiteWindowVtbl;
@ -60,7 +60,7 @@ typedef struct {
GUID guid;
struct list entry;
} ScriptHost;
};
#define ACTSCPSITE(x) ((IActiveScriptSite*) &(x)->lpIActiveScriptSiteVtbl)
#define ACTSCPPOLL(x) (&(x)->lpIActiveScriptSiteInterruptPollVtbl)
@ -811,6 +811,52 @@ IDispatch *script_parse_event(HTMLDocument *doc, LPCWSTR text)
return disp;
}
IDispatch *get_script_disp(ScriptHost *script_host)
{
IDispatch *disp;
HRESULT hres;
if(!script_host->script)
return NULL;
hres = IActiveScript_GetScriptDispatch(script_host->script, windowW, &disp);
if(FAILED(hres))
return NULL;
return disp;
}
BOOL find_global_prop(HTMLWindow *window, BSTR name, DWORD flags, ScriptHost **ret_host, DISPID *ret_id)
{
IDispatchEx *dispex;
IDispatch *disp;
ScriptHost *iter;
HRESULT hres;
LIST_FOR_EACH_ENTRY(iter, &window->script_hosts, ScriptHost, entry) {
disp = get_script_disp(iter);
if(!disp)
continue;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) {
hres = IDispatchEx_GetDispID(dispex, name, flags, ret_id);
IDispatchEx_Release(dispex);
}else {
FIXME("No IDispatchEx\n");
hres = E_NOTIMPL;
}
IDispatch_Release(disp);
if(SUCCEEDED(hres)) {
*ret_host = iter;
return TRUE;
}
}
return FALSE;
}
static BOOL is_jscript_available(void)
{
static BOOL available, checked;