} handler_vector_t;
struct event_target_t {
- DWORD node_handlers_mask;
handler_vector_t *event_table[EVENTID_LAST];
};
#define EVENT_DEFAULTLISTENER 0x0001
#define EVENT_BUBBLE 0x0002
#define EVENT_FORWARDBODY 0x0004
-#define EVENT_NODEHANDLER 0x0008
+#define EVENT_BIND_TO_BODY 0x0008
#define EVENT_CANCELABLE 0x0010
#define EVENT_HASDEFAULTHANDLERS 0x0020
static const event_info_t event_info[] = {
{abortW, onabortW, EVENTT_NONE, DISPID_EVMETH_ONABORT,
- EVENT_NODEHANDLER},
+ EVENT_BIND_TO_BODY},
{beforeunloadW, onbeforeunloadW, EVENTT_NONE, DISPID_EVMETH_ONBEFOREUNLOAD,
EVENT_DEFAULTLISTENER|EVENT_FORWARDBODY},
{blurW, onblurW, EVENTT_HTML, DISPID_EVMETH_ONBLUR,
{dragstartW, ondragstartW, EVENTT_MOUSE, DISPID_EVMETH_ONDRAGSTART,
EVENT_CANCELABLE},
{errorW, onerrorW, EVENTT_NONE, DISPID_EVMETH_ONERROR,
- EVENT_NODEHANDLER},
+ EVENT_BIND_TO_BODY},
{focusW, onfocusW, EVENTT_HTML, DISPID_EVMETH_ONFOCUS,
EVENT_DEFAULTLISTENER},
{helpW, onhelpW, EVENTT_KEY, DISPID_EVMETH_ONHELP,
{keyupW, onkeyupW, EVENTT_KEY, DISPID_EVMETH_ONKEYUP,
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
{loadW, onloadW, EVENTT_HTML, DISPID_EVMETH_ONLOAD,
- EVENT_NODEHANDLER},
+ EVENT_BIND_TO_BODY},
{mousedownW, onmousedownW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEDOWN,
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
{mousemoveW, onmousemoveW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEMOVE,
EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_CANCELABLE}
};
-static const eventid_t node_handled_list[] = { EVENTID_ABORT, EVENTID_ERROR, EVENTID_LOAD };
-
eventid_t str_to_eid(LPCWSTR str)
{
int i;
return EVENTID_LAST;
}
-static DWORD get_node_handler_mask(eventid_t eid)
-{
- DWORD i;
-
- for(i=0; i<sizeof(node_handled_list)/sizeof(*node_handled_list); i++) {
- if(node_handled_list[i] == eid)
- return 1 << i;
- }
-
- ERR("Invalid eid %d\n", eid);
- return ~0;
-}
-
typedef struct {
DispatchEx dispex;
IHTMLEventObj IHTMLEventObj_iface;
static HRESULT WINAPI HTMLEventObj_get_x(IHTMLEventObj *iface, LONG *p)
{
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
+ LONG x = 0;
- FIXME("(%p)->(%p)\n", This, p);
+ TRACE("(%p)->(%p)\n", This, p);
- *p = -1;
+ if(This->nsevent) {
+ nsIDOMUIEvent *ui_event;
+ nsresult nsres;
+
+ nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
+ if(NS_SUCCEEDED(nsres)) {
+ /* NOTE: pageX is not exactly right here. */
+ nsres = nsIDOMUIEvent_GetPageX(ui_event, &x);
+ assert(nsres == NS_OK);
+ nsIDOMUIEvent_Release(ui_event);
+ }
+ }
+
+ *p = x;
return S_OK;
}
static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p)
{
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
+ LONG y = 0;
- FIXME("(%p)->(%p)\n", This, p);
+ TRACE("(%p)->(%p)\n", This, p);
+
+ if(This->nsevent) {
+ nsIDOMUIEvent *ui_event;
+ nsresult nsres;
+
+ nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
+ if(NS_SUCCEEDED(nsres)) {
+ /* NOTE: pageY is not exactly right here. */
+ nsres = nsIDOMUIEvent_GetPageY(ui_event, &y);
+ assert(nsres == NS_OK);
+ nsIDOMUIEvent_Release(ui_event);
+ }
+ }
- *p = -1;
+ *p = y;
return S_OK;
}
return TRUE;
}
-static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *event_target, nsIDOMNode *nsnode, eventid_t eid)
+static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *event_target, eventid_t eid)
{
- if(!doc->nsdoc)
- return S_OK;
+ nsIDOMNode *nsnode = NULL;
- if(event_info[eid].flags & EVENT_NODEHANDLER) {
- DWORD mask;
+ TRACE("%s\n", debugstr_w(event_info[eid].name));
- mask = get_node_handler_mask(eid);
- if(event_target->node_handlers_mask & mask)
- return S_OK;
-
- add_nsevent_listener(doc, nsnode, event_info[eid].name);
- event_target->node_handlers_mask |= mask;
+ if(!doc->nsdoc || doc->event_vector[eid] || !(event_info[eid].flags & (EVENT_DEFAULTLISTENER|EVENT_BIND_TO_BODY)))
return S_OK;
- }
- if(!(event_info[eid].flags & EVENT_DEFAULTLISTENER))
- return S_OK;
+ if(event_info[eid].flags & EVENT_BIND_TO_BODY) {
+ nsIDOMHTMLElement *nsbody;
+ nsresult nsres;
- if(!doc->event_vector[eid]) {
- doc->event_vector[eid] = TRUE;
- add_nsevent_listener(doc, NULL, event_info[eid].name);
+ nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody);
+ if(NS_SUCCEEDED(nsres) && nsbody) {
+ nsnode = (nsIDOMNode*)nsbody;
+ }else {
+ ERR("GetBody failed: %08x\n", nsres);
+ return E_UNEXPECTED;
+ }
}
+ doc->event_vector[eid] = TRUE;
+ add_nsevent_listener(doc, nsnode, event_info[eid].name);
+
+ if(nsnode)
+ nsIDOMNode_Release(nsnode);
return S_OK;
}
return S_OK;
}
-static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTMLDocumentNode *doc,
+static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc,
eventid_t eid, IDispatch *disp)
{
event_target_t *event_target;
event_target->event_table[eid]->handler_prop = disp;
IDispatch_AddRef(disp);
- return ensure_nsevent_handler(doc, event_target, nsnode, eid);
+ return ensure_nsevent_handler(doc, event_target, eid);
}
-HRESULT set_event_handler(event_target_t **event_target, nsIDOMNode *nsnode, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var)
+HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var)
{
switch(V_VT(var)) {
case VT_NULL:
return remove_event_handler(event_target, eid);
case VT_DISPATCH:
- return set_event_handler_disp(event_target, nsnode, doc, eid, V_DISPATCH(var));
+ return set_event_handler_disp(event_target, doc, eid, V_DISPATCH(var));
default:
FIXME("not handler %s\n", debugstr_variant(var));
return S_OK;
}
-HRESULT attach_event(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTMLDocument *doc, BSTR name,
+HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR name,
IDispatch *disp, VARIANT_BOOL *res)
{
event_target_t *event_target;
event_target->event_table[eid]->handlers[i] = disp;
*res = VARIANT_TRUE;
- return ensure_nsevent_handler(doc->doc_node, event_target, nsnode, eid);
+ return ensure_nsevent_handler(doc->doc_node, event_target, eid);
}
HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name, IDispatch *disp)
return S_OK;
}
-void bind_elem_event(HTMLDocumentNode *doc, HTMLElement *elem, const WCHAR *event, IDispatch *disp)
+void bind_node_event(HTMLDocumentNode *doc, event_target_t **event_target, HTMLDOMNode *node, const WCHAR *event, IDispatch *disp)
{
eventid_t eid;
- TRACE("(%p %p %s %p)\n", doc, elem, debugstr_w(event), disp);
+ TRACE("(%p %p %p %s %p)\n", doc, event_target, node, debugstr_w(event), disp);
eid = attr_to_eid(event);
if(eid == EVENTID_LAST) {
return;
}
- set_event_handler_disp(&elem->node.event_target, elem->node.nsnode, 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, nsIDOMNode *nsnode)
+void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp)
{
event_target_t *event_target;
int i;
for(i=0; i < EVENTID_LAST; i++) {
if((event_info[i].flags & EVENT_DEFAULTLISTENER) && is_cp_event(cp, event_info[i].dispid))
- ensure_nsevent_handler(window->doc, event_target, nsnode, i);
+ ensure_nsevent_handler(window->doc, event_target, i);
}
}
if(disp) {
hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node);
if(SUCCEEDED(hres)) {
- set_event_handler_disp(get_node_event_target(node), node->nsnode, node->doc, i, disp);
+ set_event_handler_disp(get_node_event_target(node), node->doc, i, disp);
node_release(node);
}
IDispatch_Release(disp);
for(i=0; i < EVENTID_LAST; i++) {
if(event_info[i].flags & EVENT_HASDEFAULTHANDLERS) {
- hres = ensure_nsevent_handler(doc, NULL, NULL, i);
+ hres = ensure_nsevent_handler(doc, NULL, i);
if(FAILED(hres))
return hres;
}