Module: wine Branch: master Commit: a0c162cc4aa1cff4a7a38260735c0e26ddfae16e URL: http://source.winehq.org/git/wine.git/?a=commit;h=a0c162cc4aa1cff4a7a3826073...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Oct 10 15:46:47 2008 -0500
mshtml: Added event bubbling implementation.
---
dlls/mshtml/htmlevent.c | 68 ++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 55 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 4c8e2a2..5942990 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -58,13 +58,14 @@ typedef struct { } event_info_t;
#define EVENT_DEFAULTLISTENER 0x0001 +#define EVENT_BUBBLE 0x0002
static const event_info_t event_info[] = { - {changeW, onchangeW, EVENT_DEFAULTLISTENER}, - {clickW, onclickW, EVENT_DEFAULTLISTENER}, - {keyupW, onkeyupW, EVENT_DEFAULTLISTENER}, + {changeW, onchangeW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {clickW, onclickW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {keyupW, onkeyupW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {loadW, onloadW, 0}, - {mouseoverW, onmouseoverW, EVENT_DEFAULTLISTENER} + {mouseoverW, onmouseoverW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE} };
eventid_t str_to_eid(LPCWSTR str) @@ -412,21 +413,62 @@ static IHTMLEventObj *create_event(void)
void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target) { + IHTMLEventObj *prev_event, *event_obj = NULL; + nsIDOMNode *parent, *nsnode; HTMLDOMNode *node; + PRUint16 node_type;
- node = get_node(doc, target, FALSE); - if(!node) + nsIDOMNode_GetNodeType(target, &node_type); + if(node_type != ELEMENT_NODE) { + FIXME("node type %d node supported\n", node_type); 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]) { - doc->window->event = create_event(); + if(!(event_info[eid].flags & EVENT_BUBBLE)) + break;
- 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)); + nsIDOMNode_GetParentNode(nsnode, &parent); + nsIDOMNode_Release(nsnode); + 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); - doc->window->event = NULL; + if(event_obj) { + IHTMLEventObj_Release(event_obj); + doc->window->event = prev_event; } }