Jacek Caban : mshtml: Added event bubbling implementation.
Alexandre Julliard
julliard at winehq.org
Mon Oct 13 06:37:19 CDT 2008
Module: wine
Branch: master
Commit: a0c162cc4aa1cff4a7a38260735c0e26ddfae16e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a0c162cc4aa1cff4a7a38260735c0e26ddfae16e
Author: Jacek Caban <jacek at 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;
}
}
More information about the wine-cvs
mailing list