mshtml: Added support for quering global variables from window object.
This commit is contained in:
parent
705fb0f239
commit
a50c4edb93
|
@ -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
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue