mshtml: Added support for load event on all nodes.
This commit is contained in:
parent
da01d8acaf
commit
df0a35e3d3
|
@ -1477,7 +1477,7 @@ static void HTMLDocument_on_advise(IUnknown *iface, cp_static_data_t *cp)
|
|||
HTMLDocument *This = HTMLDOC_THIS(iface);
|
||||
|
||||
if(This->window)
|
||||
update_cp_events(This->window, cp);
|
||||
update_cp_events(This->window, &This->doc_node->node.event_target, cp, This->doc_node->node.nsnode);
|
||||
}
|
||||
|
||||
#undef HTMLDOC_THIS
|
||||
|
|
|
@ -182,7 +182,7 @@ static HRESULT WINAPI HTMLDocument3_attachEvent(IHTMLDocument3 *iface, BSTR even
|
|||
|
||||
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
|
||||
|
||||
return attach_event(&This->doc_node->node.event_target, This, event, pDisp, pfResult);
|
||||
return attach_event(&This->doc_node->node.event_target, This->doc_node->node.nsnode, This, event, pDisp, pfResult);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLDocument3_detachEvent(IHTMLDocument3 *iface, BSTR event,
|
||||
|
|
|
@ -649,7 +649,7 @@ static HRESULT WINAPI HTMLElement2_attachEvent(IHTMLElement2 *iface, BSTR event,
|
|||
|
||||
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
|
||||
|
||||
return attach_event(get_node_event_target(&This->node), &This->node.doc->basedoc, event, pDisp, pfResult);
|
||||
return attach_event(get_node_event_target(&This->node), This->node.nsnode, &This->node.doc->basedoc, event, pDisp, pfResult);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLElement2_detachEvent(IHTMLElement2 *iface, BSTR event, IDispatch *pDisp)
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct {
|
|||
} handler_vector_t;
|
||||
|
||||
struct event_target_t {
|
||||
DWORD node_handlers_mask;
|
||||
handler_vector_t *event_table[EVENTID_LAST];
|
||||
};
|
||||
|
||||
|
@ -129,6 +130,7 @@ typedef struct {
|
|||
#define EVENT_DEFAULTLISTENER 0x0001
|
||||
#define EVENT_BUBBLE 0x0002
|
||||
#define EVENT_FORWARDBODY 0x0004
|
||||
#define EVENT_NODEHANDLER 0x0008
|
||||
|
||||
static const event_info_t event_info[] = {
|
||||
{beforeunloadW, onbeforeunloadW, EVENTT_NONE, DISPID_EVMETH_ONBEFOREUNLOAD,
|
||||
|
@ -152,7 +154,7 @@ static const event_info_t event_info[] = {
|
|||
{keyupW, onkeyupW, EVENTT_KEY, DISPID_EVMETH_ONKEYUP,
|
||||
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
||||
{loadW, onloadW, EVENTT_HTML, DISPID_EVMETH_ONLOAD,
|
||||
0},
|
||||
EVENT_NODEHANDLER},
|
||||
{mousedownW, onmousedownW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEDOWN,
|
||||
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
||||
{mouseoutW, onmouseoutW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEOUT,
|
||||
|
@ -171,6 +173,8 @@ static const event_info_t event_info[] = {
|
|||
0}
|
||||
};
|
||||
|
||||
static const eventid_t node_handled_list[] = { EVENTID_LOAD };
|
||||
|
||||
eventid_t str_to_eid(LPCWSTR str)
|
||||
{
|
||||
int i;
|
||||
|
@ -196,6 +200,19 @@ static eventid_t attr_to_eid(LPCWSTR str)
|
|||
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;
|
||||
const IHTMLEventObjVtbl *lpIHTMLEventObjVtbl;
|
||||
|
@ -1024,9 +1041,24 @@ static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid, in
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, eventid_t eid)
|
||||
static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *event_target, nsIDOMNode *nsnode, eventid_t eid)
|
||||
{
|
||||
if(!doc->nsdoc || !(event_info[eid].flags & EVENT_DEFAULTLISTENER))
|
||||
if(!doc->nsdoc)
|
||||
return S_OK;
|
||||
|
||||
if(event_info[eid].flags & EVENT_NODEHANDLER) {
|
||||
DWORD mask;
|
||||
|
||||
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;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(!(event_info[eid].flags & EVENT_DEFAULTLISTENER))
|
||||
return S_OK;
|
||||
|
||||
if(!doc->event_vector) {
|
||||
|
@ -1037,7 +1069,7 @@ static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, eventid_t eid)
|
|||
|
||||
if(!doc->event_vector[eid]) {
|
||||
doc->event_vector[eid] = TRUE;
|
||||
add_nsevent_listener(doc, event_info[eid].name);
|
||||
add_nsevent_listener(doc, NULL, event_info[eid].name);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -1053,7 +1085,7 @@ static HRESULT remove_event_handler(event_target_t **event_target, eventid_t eid
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc,
|
||||
static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTMLDocumentNode *doc,
|
||||
eventid_t eid, IDispatch *disp)
|
||||
{
|
||||
event_target_t *event_target;
|
||||
|
@ -1074,17 +1106,17 @@ static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDoc
|
|||
event_target->event_table[eid]->handler_prop = disp;
|
||||
IDispatch_AddRef(disp);
|
||||
|
||||
return ensure_nsevent_handler(doc, eid);
|
||||
return ensure_nsevent_handler(doc, event_target, nsnode, eid);
|
||||
}
|
||||
|
||||
HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var)
|
||||
HRESULT set_event_handler(event_target_t **event_target, nsIDOMNode *nsnode, 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, doc, eid, V_DISPATCH(var));
|
||||
return set_event_handler_disp(event_target, nsnode, doc, eid, V_DISPATCH(var));
|
||||
|
||||
default:
|
||||
FIXME("not supported vt=%d\n", V_VT(var));
|
||||
|
@ -1108,7 +1140,8 @@ 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)
|
||||
HRESULT attach_event(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTMLDocument *doc, BSTR name,
|
||||
IDispatch *disp, VARIANT_BOOL *res)
|
||||
{
|
||||
event_target_t *event_target;
|
||||
eventid_t eid;
|
||||
|
@ -1138,7 +1171,7 @@ HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR
|
|||
event_target->event_table[eid]->handlers[i] = disp;
|
||||
|
||||
*res = VARIANT_TRUE;
|
||||
return ensure_nsevent_handler(doc->doc_node, eid);
|
||||
return ensure_nsevent_handler(doc->doc_node, event_target, nsnode, eid);
|
||||
}
|
||||
|
||||
HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name, IDispatch *disp)
|
||||
|
@ -1169,13 +1202,18 @@ HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void update_cp_events(HTMLWindow *window, cp_static_data_t *cp)
|
||||
void update_cp_events(HTMLWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp, nsIDOMNode *nsnode)
|
||||
{
|
||||
event_target_t *event_target;
|
||||
int i;
|
||||
|
||||
event_target = get_event_target(event_target_ptr);
|
||||
if(!event_target)
|
||||
return; /* FIXME */
|
||||
|
||||
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, i);
|
||||
ensure_nsevent_handler(window->doc, event_target, nsnode, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1204,7 +1242,7 @@ void check_event_attr(HTMLDocumentNode *doc, nsIDOMElement *nselem)
|
|||
disp = script_parse_event(doc->basedoc.window, attr_value);
|
||||
if(disp) {
|
||||
node = get_node(doc, (nsIDOMNode*)nselem, TRUE);
|
||||
set_event_handler_disp(get_node_event_target(node), node->doc, i, disp);
|
||||
set_event_handler_disp(get_node_event_target(node), node->nsnode, node->doc, i, disp);
|
||||
IDispatch_Release(disp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,13 @@ eventid_t str_to_eid(LPCWSTR);
|
|||
void check_event_attr(HTMLDocumentNode*,nsIDOMElement*);
|
||||
void release_event_target(event_target_t*);
|
||||
void fire_event(HTMLDocumentNode*,eventid_t,BOOL,nsIDOMNode*,nsIDOMEvent*);
|
||||
HRESULT set_event_handler(event_target_t**,HTMLDocumentNode*,eventid_t,VARIANT*);
|
||||
HRESULT set_event_handler(event_target_t**,nsIDOMNode*,HTMLDocumentNode*,eventid_t,VARIANT*);
|
||||
HRESULT get_event_handler(event_target_t**,eventid_t,VARIANT*);
|
||||
HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*);
|
||||
HRESULT attach_event(event_target_t**,nsIDOMNode*,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*);
|
||||
HRESULT detach_event(event_target_t*,HTMLDocument*,BSTR,IDispatch*);
|
||||
HRESULT dispatch_event(HTMLDOMNode*,const WCHAR*,VARIANT*,VARIANT_BOOL*);
|
||||
HRESULT call_event(HTMLDOMNode*,eventid_t);
|
||||
void update_cp_events(HTMLWindow*,cp_static_data_t*);
|
||||
void update_cp_events(HTMLWindow*,event_target_t**,cp_static_data_t*,nsIDOMNode*);
|
||||
|
||||
static inline event_target_t **get_node_event_target(HTMLDOMNode *node)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ static inline event_target_t **get_node_event_target(HTMLDOMNode *node)
|
|||
|
||||
static inline HRESULT set_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var)
|
||||
{
|
||||
return set_event_handler(get_node_event_target(node), node->doc, eid, var);
|
||||
return set_event_handler(get_node_event_target(node), node->nsnode, node->doc, eid, var);
|
||||
}
|
||||
|
||||
static inline HRESULT get_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var)
|
||||
|
|
|
@ -126,7 +126,7 @@ static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIAN
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return set_event_handler(&window->doc->body_event_target, window->doc, eid, var);
|
||||
return set_event_handler(&window->doc->body_event_target, NULL, window->doc, eid, var);
|
||||
}
|
||||
|
||||
static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
|
||||
|
@ -1419,7 +1419,7 @@ static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, I
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return attach_event(&This->doc->body_event_target, &This->doc->basedoc, event, pDisp, pfResult);
|
||||
return attach_event(&This->doc->body_event_target, NULL, &This->doc->basedoc, event, pDisp, pfResult);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
|
||||
|
|
|
@ -736,7 +736,7 @@ nsresult get_nsinterface(nsISupports*,REFIID,void**);
|
|||
|
||||
void init_nsevents(HTMLDocumentNode*);
|
||||
void release_nsevents(HTMLDocumentNode*);
|
||||
void add_nsevent_listener(HTMLDocumentNode*,LPCWSTR);
|
||||
void add_nsevent_listener(HTMLDocumentNode*,nsIDOMNode*,LPCWSTR);
|
||||
|
||||
void set_window_bscallback(HTMLWindow*,nsChannelBSC*);
|
||||
void set_current_mon(HTMLWindow*,IMoniker*);
|
||||
|
|
|
@ -271,6 +271,8 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *
|
|||
eventid_t eid;
|
||||
nsresult nsres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
nsAString_Init(&type_str, NULL);
|
||||
nsIDOMEvent_GetType(event, &type_str);
|
||||
nsAString_GetData(&type_str, &type);
|
||||
|
@ -334,11 +336,14 @@ static void init_listener(nsEventListener *This, nsDocumentEventListener *listen
|
|||
This->This = listener;
|
||||
}
|
||||
|
||||
void add_nsevent_listener(HTMLDocumentNode *doc, LPCWSTR type)
|
||||
void add_nsevent_listener(HTMLDocumentNode *doc, nsIDOMNode *nsnode, LPCWSTR type)
|
||||
{
|
||||
nsIDOMEventTarget *target;
|
||||
nsresult nsres;
|
||||
|
||||
if(nsnode)
|
||||
nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMEventTarget, (void**)&target);
|
||||
else
|
||||
nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
|
||||
if(NS_FAILED(nsres)) {
|
||||
ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
|
||||
|
|
Loading…
Reference in New Issue