mshtml: Added IHTMLElement2::attachEvent implementation.

This commit is contained in:
Jacek Caban 2009-09-06 19:06:10 +02:00 committed by Alexandre Julliard
parent 86410d4a0c
commit 724fde7e91
3 changed files with 73 additions and 5 deletions

View File

@ -605,8 +605,10 @@ static HRESULT WINAPI HTMLElement2_attachEvent(IHTMLElement2 *iface, BSTR event,
IDispatch *pDisp, VARIANT_BOOL *pfResult)
{
HTMLElement *This = HTMLELEM2_THIS(iface);
FIXME("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
return E_NOTIMPL;
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
return attach_event(&This->node.event_target, This->node.doc, event, pDisp, pfResult);
}
static HRESULT WINAPI HTMLElement2_detachEvent(IHTMLElement2 *iface, BSTR event, IDispatch *pDisp)

View File

@ -127,6 +127,18 @@ eventid_t str_to_eid(LPCWSTR str)
return EVENTID_LAST;
}
static eventid_t attr_to_eid(LPCWSTR str)
{
int i;
for(i=0; i < sizeof(event_info)/sizeof(event_info[0]); i++) {
if(!strcmpW(event_info[i].attr_name, str))
return i;
}
return EVENTID_LAST;
}
typedef struct {
DispatchEx dispex;
const IHTMLEventObjVtbl *lpIHTMLEventObjVtbl;
@ -670,10 +682,11 @@ static IHTMLEventObj *create_event(HTMLDOMNode *target, eventid_t eid, nsIDOMEve
return HTMLEVENTOBJ(ret);
}
static void call_event_handlers(HTMLDocument *doc, event_target_t *event_target,
static void call_event_handlers(HTMLDocument *doc, IHTMLEventObj *event_obj, event_target_t *event_target,
eventid_t eid, IDispatch *this_obj)
{
handler_vector_t *handler_vector;
DWORD i;
HRESULT hres;
if(!event_target || !(handler_vector = event_target->event_table[eid]))
@ -694,6 +707,25 @@ static void call_event_handlers(HTMLDocument *doc, event_target_t *event_target,
else
WARN("%s <<< %08x\n", debugstr_w(event_info[eid].name), hres);
}
if(handler_vector->handler_cnt) {
VARIANTARG arg;
DISPPARAMS dp = {&arg, NULL, 1, 0};
V_VT(&arg) = VT_DISPATCH;
V_DISPATCH(&arg) = (IDispatch*)event_obj;
for(i=0; i < handler_vector->handler_cnt; i++) {
if(handler_vector->handlers[i]) {
TRACE("%s [%d] >>>\n", debugstr_w(event_info[eid].name), i);
hres = call_disp_func(handler_vector->handlers[i], &dp);
if(hres == S_OK)
TRACE("%s [%d] <<<\n", debugstr_w(event_info[eid].name), i);
else
WARN("%s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres);
}
}
}
}
void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target, nsIDOMEvent *nsevent)
@ -718,7 +750,7 @@ void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target, nsIDOMEven
node = get_node(doc, nsnode, FALSE);
if(node)
call_event_handlers(doc, node->event_target, eid, (IDispatch*)HTMLDOMNODE(node));
call_event_handlers(doc, event_obj, node->event_target, eid, (IDispatch*)HTMLDOMNODE(node));
if(!(event_info[eid].flags & EVENT_BUBBLE))
break;
@ -738,7 +770,7 @@ void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target, nsIDOMEven
nsIDOMNode_Release(nsnode);
if(event_info[eid].flags & EVENT_BUBBLE)
call_event_handlers(doc, doc->event_target, eid, (IDispatch*)HTMLDOC(doc));
call_event_handlers(doc, event_obj, doc->event_target, eid, (IDispatch*)HTMLDOC(doc));
IHTMLEventObj_Release(event_obj);
doc->window->event = prev_event;
@ -841,6 +873,39 @@ HRESULT get_event_handler(event_target_t **event_target, eventid_t eid, VARIANT
return S_OK;
}
HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR name, IDispatch *disp, VARIANT_BOOL *res)
{
event_target_t *event_target;
eventid_t eid;
DWORD i = 0;
eid = attr_to_eid(name);
if(eid == EVENTID_LAST) {
WARN("Unknown event\n");
*res = VARIANT_TRUE;
return S_OK;
}
event_target = get_event_target(event_target_ptr);
if(!event_target)
return E_OUTOFMEMORY;
if(event_target->event_table[eid]) {
while(i < event_target->event_table[eid]->handler_cnt && event_target->event_table[eid]->handlers[i])
i++;
if(i == event_target->event_table[eid]->handler_cnt && !alloc_handler_vector(event_target, eid, i+1))
return E_OUTOFMEMORY;
}else if(!alloc_handler_vector(event_target, eid, i+1)) {
return E_OUTOFMEMORY;
}
IDispatch_AddRef(disp);
event_target->event_table[eid]->handlers[i] = disp;
*res = VARIANT_TRUE;
return S_OK;
}
void check_event_attr(HTMLDocument *doc, nsIDOMElement *nselem)
{
const PRUnichar *attr_value;

View File

@ -41,6 +41,7 @@ void release_event_target(event_target_t*);
void fire_event(HTMLDocument*,eventid_t,nsIDOMNode*,nsIDOMEvent*);
HRESULT set_event_handler(event_target_t**,HTMLDocument*,eventid_t,VARIANT*);
HRESULT get_event_handler(event_target_t**,eventid_t,VARIANT*);
HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*);
static inline HRESULT set_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var)
{