Commit f2659775 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

mshtml: Pass EventTarget to set_event_handler.

parent 2f4e85ab
......@@ -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,24 +1494,18 @@ 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,
(void**)&plugin_container);
else
hres = E_NOINTERFACE;
hres = IDispatchEx_QueryInterface(&event_target->dispex.IDispatchEx_iface, &IID_HTMLPluginContainer,
(void**)&plugin_container);
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);
if(plugin_container)
node_release(&plugin_container->element.node);
}
IDispatchEx_Release(&event_target->dispex.IDispatchEx_iface);
if(plugin_container)
node_release(&plugin_container->element.node);
}
heap_free(event);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment