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

mshtml: Added event bubbling implementation.

parent 364b1260
...@@ -58,13 +58,14 @@ typedef struct { ...@@ -58,13 +58,14 @@ typedef struct {
} event_info_t; } event_info_t;
#define EVENT_DEFAULTLISTENER 0x0001 #define EVENT_DEFAULTLISTENER 0x0001
#define EVENT_BUBBLE 0x0002
static const event_info_t event_info[] = { static const event_info_t event_info[] = {
{changeW, onchangeW, EVENT_DEFAULTLISTENER}, {changeW, onchangeW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
{clickW, onclickW, EVENT_DEFAULTLISTENER}, {clickW, onclickW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
{keyupW, onkeyupW, EVENT_DEFAULTLISTENER}, {keyupW, onkeyupW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
{loadW, onloadW, 0}, {loadW, onloadW, 0},
{mouseoverW, onmouseoverW, EVENT_DEFAULTLISTENER} {mouseoverW, onmouseoverW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}
}; };
eventid_t str_to_eid(LPCWSTR str) eventid_t str_to_eid(LPCWSTR str)
...@@ -412,21 +413,62 @@ static IHTMLEventObj *create_event(void) ...@@ -412,21 +413,62 @@ static IHTMLEventObj *create_event(void)
void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target) void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target)
{ {
IHTMLEventObj *prev_event, *event_obj = NULL;
nsIDOMNode *parent, *nsnode;
HTMLDOMNode *node; HTMLDOMNode *node;
PRUint16 node_type;
node = get_node(doc, target, FALSE); nsIDOMNode_GetNodeType(target, &node_type);
if(!node) if(node_type != ELEMENT_NODE) {
FIXME("node type %d node supported\n", node_type);
return; return;
}
prev_event = doc->window->event;
nsnode = target;
nsIDOMNode_AddRef(nsnode);
while(1) {
node = get_node(doc, nsnode, FALSE);
if(node && node->event_target && node->event_target->event_table[eid]) {
if(!event_obj)
event_obj = doc->window->event = create_event();
TRACE("%s >>>\n", debugstr_w(event_info[eid].name));
call_disp_func(doc, node->event_target->event_table[eid]);
TRACE("%s <<<\n", debugstr_w(event_info[eid].name));
}
if(node->event_target && node->event_target->event_table[eid]) { if(!(event_info[eid].flags & EVENT_BUBBLE))
doc->window->event = create_event(); break;
TRACE("%s >>>\n", debugstr_w(event_info[eid].name)); nsIDOMNode_GetParentNode(nsnode, &parent);
call_disp_func(doc, node->event_target->event_table[eid]); nsIDOMNode_Release(nsnode);
TRACE("%s <<<\n", debugstr_w(event_info[eid].name)); nsnode = parent;
if(!nsnode)
break;
nsIDOMNode_GetNodeType(nsnode, &node_type);
if(node_type != ELEMENT_NODE)
break;
}
if(nsnode)
nsIDOMNode_Release(nsnode);
if((event_info[eid].flags & EVENT_BUBBLE) && doc->event_target && doc->event_target->event_table[eid]) {
if(!event_obj)
event_obj = doc->window->event = create_event();
TRACE("doc %s >>>\n", debugstr_w(event_info[eid].name));
call_disp_func(doc, doc->event_target->event_table[eid]);
TRACE("doc %s <<<\n", debugstr_w(event_info[eid].name));
}
IHTMLEventObj_Release(doc->window->event); if(event_obj) {
doc->window->event = NULL; IHTMLEventObj_Release(event_obj);
doc->window->event = prev_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