mshtml: Pass EventTarget to set_event_handler.
This commit is contained in:
parent
2f4e85abb8
commit
f26597753a
|
@ -1308,6 +1308,19 @@ static inline event_target_t *get_event_target(event_target_t **event_target_ptr
|
|||
return *event_target_ptr;
|
||||
}
|
||||
|
||||
static inline event_target_t *get_event_target_data(EventTarget *event_target, BOOL alloc)
|
||||
{
|
||||
event_target_t **ptr;
|
||||
|
||||
ptr = event_target->dispex.data->vtbl && event_target->dispex.data->vtbl->get_event_target_ptr
|
||||
? event_target->dispex.data->vtbl->get_event_target_ptr(&event_target->dispex)
|
||||
: &event_target->ptr;
|
||||
if(*ptr || !alloc)
|
||||
return *ptr;
|
||||
|
||||
return *ptr = heap_alloc_zero(sizeof(event_target_t));
|
||||
}
|
||||
|
||||
static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid, int cnt)
|
||||
{
|
||||
handler_vector_t *new_vector, *handler_vector = event_target->event_table[eid];
|
||||
|
@ -1368,52 +1381,53 @@ void detach_events(HTMLDocumentNode *doc)
|
|||
}
|
||||
|
||||
|
||||
static void remove_event_handler(DispatchEx *dispex, event_target_t **event_target, eventid_t eid)
|
||||
static void remove_event_handler(EventTarget *event_target, eventid_t eid)
|
||||
{
|
||||
event_target_t *data;
|
||||
VARIANT *store;
|
||||
HRESULT hres;
|
||||
|
||||
hres = dispex_get_dprop_ref(dispex, event_info[eid].attr_name, FALSE, &store);
|
||||
hres = dispex_get_dprop_ref(&event_target->dispex, event_info[eid].attr_name, FALSE, &store);
|
||||
if(SUCCEEDED(hres))
|
||||
VariantClear(store);
|
||||
|
||||
if(*event_target && (*event_target)->event_table[eid] && (*event_target)->event_table[eid]->handler_prop) {
|
||||
IDispatch_Release((*event_target)->event_table[eid]->handler_prop);
|
||||
(*event_target)->event_table[eid]->handler_prop = NULL;
|
||||
data = get_event_target_data(event_target, FALSE);
|
||||
if(data && data->event_table[eid] && data->event_table[eid]->handler_prop) {
|
||||
IDispatch_Release(data->event_table[eid]->handler_prop);
|
||||
data->event_table[eid]->handler_prop = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT set_event_handler_disp(DispatchEx *dispex, event_target_t **event_target_ptr, HTMLDocumentNode *doc,
|
||||
eventid_t eid, IDispatch *disp)
|
||||
static HRESULT set_event_handler_disp(EventTarget *event_target, HTMLDocumentNode *doc, eventid_t eid, IDispatch *disp)
|
||||
{
|
||||
event_target_t *event_target;
|
||||
event_target_t *data;
|
||||
|
||||
remove_event_handler(dispex, event_target_ptr, eid);
|
||||
remove_event_handler(event_target, eid);
|
||||
if(!disp)
|
||||
return S_OK;
|
||||
|
||||
event_target = get_event_target(event_target_ptr);
|
||||
data = get_event_target_data(event_target, TRUE);
|
||||
if(!event_target)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if(!alloc_handler_vector(event_target, eid, 0))
|
||||
if(!alloc_handler_vector(data, eid, 0))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
event_target->event_table[eid]->handler_prop = disp;
|
||||
data->event_table[eid]->handler_prop = disp;
|
||||
IDispatch_AddRef(disp);
|
||||
|
||||
return ensure_nsevent_handler(doc, event_target, eid);
|
||||
return ensure_nsevent_handler(doc, data, eid);
|
||||
}
|
||||
|
||||
HRESULT set_event_handler(DispatchEx *dispex, event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var)
|
||||
HRESULT set_event_handler(EventTarget *event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var)
|
||||
{
|
||||
switch(V_VT(var)) {
|
||||
case VT_NULL:
|
||||
remove_event_handler(dispex, event_target, eid);
|
||||
remove_event_handler(event_target, eid);
|
||||
return S_OK;
|
||||
|
||||
case VT_DISPATCH:
|
||||
return set_event_handler_disp(dispex, event_target, doc, eid, V_DISPATCH(var));
|
||||
return set_event_handler_disp(event_target, doc, eid, V_DISPATCH(var));
|
||||
|
||||
case VT_BSTR: {
|
||||
VARIANT *v;
|
||||
|
@ -1425,9 +1439,9 @@ HRESULT set_event_handler(DispatchEx *dispex, event_target_t **event_target, HTM
|
|||
* we store the value in DispatchEx, which can already handle custom
|
||||
* properties.
|
||||
*/
|
||||
remove_event_handler(dispex, event_target, eid);
|
||||
remove_event_handler(event_target, eid);
|
||||
|
||||
hres = dispex_get_dprop_ref(dispex, event_info[eid].attr_name, TRUE, &v);
|
||||
hres = dispex_get_dprop_ref(&event_target->dispex, event_info[eid].attr_name, TRUE, &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -1530,12 +1544,11 @@ HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void bind_target_event(HTMLDocumentNode *doc, event_target_t **event_target, DispatchEx *dispex,
|
||||
const WCHAR *event, IDispatch *disp)
|
||||
void bind_target_event(HTMLDocumentNode *doc, EventTarget *event_target, const WCHAR *event, IDispatch *disp)
|
||||
{
|
||||
eventid_t eid;
|
||||
|
||||
TRACE("(%p %p %p %s %p)\n", doc, event_target, dispex, debugstr_w(event), disp);
|
||||
TRACE("(%p %p %s %p)\n", doc, event_target, debugstr_w(event), disp);
|
||||
|
||||
eid = attr_to_eid(event);
|
||||
if(eid == EVENTID_LAST) {
|
||||
|
@ -1543,7 +1556,7 @@ void bind_target_event(HTMLDocumentNode *doc, event_target_t **event_target, Dis
|
|||
return;
|
||||
}
|
||||
|
||||
set_event_handler_disp(dispex, event_target, doc, eid, disp);
|
||||
set_event_handler_disp(event_target, doc, eid, disp);
|
||||
}
|
||||
|
||||
void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp)
|
||||
|
@ -1583,7 +1596,7 @@ void check_event_attr(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem)
|
|||
if(disp) {
|
||||
hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node);
|
||||
if(SUCCEEDED(hres)) {
|
||||
set_event_handler_disp(&node->event_target.dispex, get_node_event_target(node), node->doc, i, disp);
|
||||
set_event_handler_disp(&node->event_target, node->doc, i, disp);
|
||||
node_release(node);
|
||||
}
|
||||
IDispatch_Release(disp);
|
||||
|
|
|
@ -54,7 +54,7 @@ eventid_t str_to_eid(LPCWSTR) DECLSPEC_HIDDEN;
|
|||
void check_event_attr(HTMLDocumentNode*,nsIDOMHTMLElement*) DECLSPEC_HIDDEN;
|
||||
void release_event_target(event_target_t*) DECLSPEC_HIDDEN;
|
||||
void fire_event(HTMLDocumentNode*,eventid_t,BOOL,nsIDOMNode*,nsIDOMEvent*,IDispatch*) DECLSPEC_HIDDEN;
|
||||
HRESULT set_event_handler(DispatchEx*,event_target_t**,HTMLDocumentNode*,eventid_t,VARIANT*) DECLSPEC_HIDDEN;
|
||||
HRESULT set_event_handler(EventTarget*,HTMLDocumentNode*,eventid_t,VARIANT*) DECLSPEC_HIDDEN;
|
||||
HRESULT get_event_handler(DispatchEx*,event_target_t**,eventid_t,VARIANT*) DECLSPEC_HIDDEN;
|
||||
HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*) DECLSPEC_HIDDEN;
|
||||
HRESULT detach_event(event_target_t*,HTMLDocument*,BSTR,IDispatch*) DECLSPEC_HIDDEN;
|
||||
|
@ -64,7 +64,7 @@ void update_cp_events(HTMLInnerWindow*,event_target_t**,cp_static_data_t*) DECLS
|
|||
HRESULT doc_init_events(HTMLDocumentNode*) DECLSPEC_HIDDEN;
|
||||
void detach_events(HTMLDocumentNode *doc) DECLSPEC_HIDDEN;
|
||||
HRESULT create_event_obj(IHTMLEventObj**) DECLSPEC_HIDDEN;
|
||||
void bind_target_event(HTMLDocumentNode*,event_target_t**,DispatchEx*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN;
|
||||
void bind_target_event(HTMLDocumentNode*,EventTarget*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN;
|
||||
|
||||
void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
|
||||
void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
|
||||
|
@ -80,7 +80,7 @@ static inline event_target_t **get_node_event_target(HTMLDOMNode *node)
|
|||
|
||||
static inline HRESULT set_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var)
|
||||
{
|
||||
return set_event_handler(&node->event_target.dispex, get_node_event_target(node), node->doc, eid, var);
|
||||
return set_event_handler(&node->event_target, node->doc, eid, var);
|
||||
}
|
||||
|
||||
static inline HRESULT get_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var)
|
||||
|
|
|
@ -95,8 +95,7 @@ static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIAN
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return set_event_handler(&window->inner_window->event_target.dispex, &window->inner_window->doc->body_event_target,
|
||||
window->inner_window->doc, eid, var);
|
||||
return set_event_handler(&window->inner_window->event_target, window->inner_window->doc, eid, var);
|
||||
}
|
||||
|
||||
static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
|
||||
|
|
|
@ -1314,10 +1314,9 @@ IDispatch *get_script_disp(ScriptHost *script_host)
|
|||
return disp;
|
||||
}
|
||||
|
||||
static event_target_t **find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem, DispatchEx **ret_target_dispex)
|
||||
static EventTarget *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem)
|
||||
{
|
||||
DispatchEx *target_dispex = NULL;
|
||||
event_target_t **target = NULL;
|
||||
EventTarget *event_target = NULL;
|
||||
const PRUnichar *target_id;
|
||||
nsAString target_id_str;
|
||||
nsresult nsres;
|
||||
|
@ -1335,28 +1334,24 @@ static event_target_t **find_event_target(HTMLDocumentNode *doc, HTMLScriptEleme
|
|||
if(!*target_id) {
|
||||
FIXME("Empty for attribute\n");
|
||||
}else if(!strcmpW(target_id, documentW)) {
|
||||
target = &doc->node.event_target.ptr;
|
||||
target_dispex = &doc->node.event_target.dispex;
|
||||
event_target = &doc->node.event_target;
|
||||
htmldoc_addref(&doc->basedoc);
|
||||
}else if(!strcmpW(target_id, windowW)) {
|
||||
if(doc->window) {
|
||||
target_dispex = &doc->window->event_target.dispex;
|
||||
IDispatchEx_AddRef(&target_dispex->IDispatchEx_iface);
|
||||
target = &doc->body_event_target;
|
||||
event_target = &doc->window->event_target;
|
||||
IDispatchEx_AddRef(&event_target->dispex.IDispatchEx_iface);
|
||||
}
|
||||
}else {
|
||||
HTMLElement *target_elem;
|
||||
|
||||
hres = get_doc_elem_by_id(doc, target_id, &target_elem);
|
||||
if(SUCCEEDED(hres) && target_elem) {
|
||||
target_dispex = &target_elem->node.event_target.dispex;
|
||||
target = &target_elem->node.event_target.ptr;
|
||||
event_target = &target_elem->node.event_target;
|
||||
}
|
||||
}
|
||||
nsAString_Finish(&target_id_str);
|
||||
|
||||
*ret_target_dispex = target_dispex;
|
||||
return target;
|
||||
nsAString_Finish(&target_id_str);
|
||||
return event_target;
|
||||
}
|
||||
|
||||
static BOOL parse_event_str(WCHAR *event, const WCHAR **args)
|
||||
|
@ -1451,9 +1446,8 @@ void bind_event_scripts(HTMLDocumentNode *doc)
|
|||
HTMLPluginContainer *plugin_container;
|
||||
nsIDOMHTMLScriptElement *nsscript;
|
||||
HTMLScriptElement *script_elem;
|
||||
event_target_t **event_target;
|
||||
EventTarget *event_target;
|
||||
nsIDOMNodeList *node_list;
|
||||
DispatchEx *target_dispex;
|
||||
nsIDOMNode *script_node;
|
||||
nsAString selector_str;
|
||||
IDispatch *event_disp;
|
||||
|
@ -1500,25 +1494,19 @@ void bind_event_scripts(HTMLDocumentNode *doc)
|
|||
|
||||
event_disp = parse_event_elem(doc, script_elem, &event);
|
||||
if(event_disp) {
|
||||
event_target = find_event_target(doc, script_elem, &target_dispex);
|
||||
event_target = find_event_target(doc, script_elem);
|
||||
if(event_target) {
|
||||
if(target_dispex)
|
||||
hres = IDispatchEx_QueryInterface(&target_dispex->IDispatchEx_iface, &IID_HTMLPluginContainer,
|
||||
hres = IDispatchEx_QueryInterface(&event_target->dispex.IDispatchEx_iface, &IID_HTMLPluginContainer,
|
||||
(void**)&plugin_container);
|
||||
else
|
||||
hres = E_NOINTERFACE;
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
bind_activex_event(doc, plugin_container, event, event_disp);
|
||||
else
|
||||
bind_target_event(doc, event_target, target_dispex, event, event_disp);
|
||||
bind_target_event(doc, event_target, event, event_disp);
|
||||
|
||||
if(target_dispex) {
|
||||
IDispatchEx_Release(&target_dispex->IDispatchEx_iface);
|
||||
IDispatchEx_Release(&event_target->dispex.IDispatchEx_iface);
|
||||
if(plugin_container)
|
||||
node_release(&plugin_container->element.node);
|
||||
}
|
||||
}
|
||||
|
||||
heap_free(event);
|
||||
IDispatch_Release(event_disp);
|
||||
|
|
Loading…
Reference in New Issue